diff options
author | Joshua Yun <joshua@joshuayun.com> | 2025-05-22 22:46:34 -0500 |
---|---|---|
committer | Joshua Yun <joshua@joshuayun.com> | 2025-05-22 22:46:34 -0500 |
commit | 88db611b50f16146bc6ca39f543348d0d9f5eadb (patch) | |
tree | 6374c9aec65ffd7a36581b9d9a319e197ed2cde4 /core/rtl/exe.sv | |
parent | e580017e209a0888c3f5a2063d265de50c66c56b (diff) | |
download | riscv-processor-88db611b50f16146bc6ca39f543348d0d9f5eadb.tar.gz |
finished exe stage
Diffstat (limited to 'core/rtl/exe.sv')
-rw-r--r-- | core/rtl/exe.sv | 191 |
1 files changed, 124 insertions, 67 deletions
diff --git a/core/rtl/exe.sv b/core/rtl/exe.sv index 4615638..c39807a 100644 --- a/core/rtl/exe.sv +++ b/core/rtl/exe.sv @@ -1,39 +1,61 @@ module exe ( - input logic clk, - input logic rst, - - //----------------- - // Decode Interface - //----------------- - input logic idu_exe_rs1Vld_EXE, - input logic [REG_IDX-1:0] idu_exe_rs1Idx_EXE, - - input logic idu_exe_rs2Vld_EXE, - input logic [REG_IDX-1:0] idu_exe_rs2Idx_EXE, - - input alu_op_t idu_exe_aluOp_EXE, - - //----------------- - // Memory Interface - //----------------- - output logic [WORD_WID-1:0] exe_mem_aluOpOut_EXE, - - //----------------------- - // Fetch Branch Interface - //----------------------- - output logic exe_ifu_brRes_EXE, - output logic exe_ifu_brTaken_EXE, - output logic [WORD_WID-1:0] exe_ifu_brPC_EXE, - - //-------------------- - // Writeback Interface - //-------------------- - input logic wb_exe_rdVld_WB, - input logic [ REG_IDX-1:0] wb_exe_rdIdx_WB, - input logic [WORD_WID-1:0] wb_exe_rdData_WB + input logic clk, + input logic rst, + + //----------------- + // Decode Interface + //----------------- + input logic idu_exe_instrVld_ID, + + // Register Access + input logic idu_exe_rs1Vld_ID, + input logic [REG_IDX-1:0] idu_exe_rs1Idx_ID, + input logic idu_exe_rs2Vld_ID, + input logic [REG_IDX-1:0] idu_exe_rs2Idx_ID, + + // Branch Type + input logic idu_exe_instrJmp_ID, + input logic idu_exe_instrBr_ID, + + // ALU information + input alu_op_t idu_exe_aluOp_ID, + + // Passthrough Information + input mem_op_t idu_exe_instrMemOp_ID, + input mem_size_t idu_exe_instrMemSize_ID, + input rd_data_sel_t idu_exe_instrRdDataSel_ID, + + //----------------- + // Memory Interface + //----------------- + // ALU Result information + output logic [WORD_WID-1:0] exe_mem_aluOpOut_EXE, + // Stall + input logic mem_exe_stallVld_EXE, + // Memory Information + output mem_op_t exe_mem_instrMemOp_EXE, + output mem_size_t exe_mem_instrMemSize_EXE, + // Passthrough information + output rd_data_sel_t exe_mem_instrRdDataSel_EXE, + + //----------------------- + // Fetch Branch Interface + //----------------------- + output logic exe_ifu_brRes_EXE, + output logic exe_ifu_brTaken_EXE, + output logic [WORD_WID-1:0] exe_ifu_brPC_EXE, + + //-------------------- + // Writeback Interface + //-------------------- + input logic wb_exe_rdVld_WB, + input logic [REG_IDX-1:0] wb_exe_rdIdx_WB, + input logic [WORD_WID-1:0] wb_exe_rdData_WB ); + logic instrVld_EXE; + // Alu logic [WORD_WID-1:0] aluSumDiff_EXE; logic [WORD_WID-1:0] aluSumDiffIn1_EXE; @@ -51,40 +73,56 @@ module exe ( logic aluCmpLowUsign_EXE; // Branch Resolution - logic [ 5:0] brResChoice_EXE; + logic [5:0] brResChoice_EXE; + + // Reg File + logic [NUM_REG-1:1] [WORD_WID-1:0] regData_XXX; + + // Stall Signal + assign stallVld_ID = exe_mem_instrVld_EXE & ~mem_exe_stallVld_EXE; //-------------------- // Decode Output Flops //-------------------- - assign stallVld_ID = ~exe_idu_exeRdy_EXE; // Flop Decode information - AFF #( .DTYPE(alu_op_t) ) AFF_EXE_aluOp ( .q(idu_exe_aluOp_EXE), .d(idu_exe_aluOp_ID), .en(stallVld_ID), .clk(clk) ); - AFF #( .WIDTH(WORD_WID) ) AFF_EXE_pc ( .q(idu_exe_pc_EXE), .d(idu_exe_pc_ID), .en(stallVld_ID), .clk(clk) ); - AFF #( .WIDTH(1) ) AFF_EXE_instrJmp ( .q(idu_exe_instrJmp_EXE), .d(idu_exe_instrJmp_ID), .en(stallVld_ID), .clk(clk) ); - AFF #( .WIDTH(1) ) AFF_EXE_brRes ( .q(idu_exe_brRes_EXE), .d(brResNxt_EXEM1), .en(stallVld_ID), .clk(clk) ); + AFFR #(.WIDTH(1)) AFFR_EXE_instrVld (.q(exe_mem_instrVld_EXE), .d(idu_exe_instrVld_ID), .en(stallVld_ID), .clk(clk), rst(rst)); + AFF #(.DTYPE(alu_op_t)) AFF_EXE_aluOp (.q(idu_exe_aluOp_EXE), .d(idu_exe_aluOp_ID), .en(stallVld_ID), .clk(clk)); + AFF #(.WIDTH(WORD_WID)) AFF_EXE_pc (.q(idu_exe_pc_EXE), .d(idu_exe_pc_ID), .en(stallVld_ID), .clk(clk)); + AFF #(.WIDTH(1)) AFF_EXE_instrJmp (.q(idu_exe_instrJmp_EXE), .d(idu_exe_instrJmp_ID), .en(stallVld_ID), .clk(clk)); + AFF #(.WIDTH(1)) AFF_EXE_brRes (.q(idu_exe_brRes_EXE), .d(brResNxt_EXEM1), .en(stallVld_ID), .clk(clk)); //-------------- // Register File //-------------- - // FIXME: Add support for the zero register - always_ff @(posedge clk) begin + assign rs1WrFwd_ID = wb_exe_rdWrVld_WB & (idu_exe_rs1Idx_ID == wb_exe_rdIdx_WB); + assign rs2WrFwd_ID = wb_exe_rdWrVld_WB & (idu_exe_rs2Idx_ID == wb_exe_rdIdx_WB); + always_ff @(posedge clk) begin // RS1 Read Port with Forwarding if (instrRs1Vld_ID) begin - idu_exe_rs1Data_EXE <= (wb_exe_rdVld_WB & (idu_exe_rs1Idx_ID == wb_exe_rdIdx_WB)) ? wb_exe_rdData_WB : regData_XXX[idu_exe_rs1Idx_ID]; + if (idx_exe_rs1Idx == REG_IDX'0) // X0 Register + idu_exe_rs1Data_EXE <= WORD_SIZE'0; + else if (rs1WrFwd_ID) begin // Write Foward + idu_exe_rs1Data_EXE <= wb_exe_rdData_WB; + else // Normal Read + idu_exe_rs1Data_EXE <= regData_XXX[idu_exe_rs1Idx_ID]; end // RS2 Read Port with Forwarding - if (instrRdVld_ID) begin - idu_exe_rs2Data_EXE <= (wb_exe_rdVld_WB & (idu_exe_rs1Idx_ID == wb_exe_rdIdx_WB)) ? wb_exe_rdData_WB : regData_XXX[idu_exe_rs2Idx_ID]; + if (instrRs2Vld_ID) begin + if (idx_exe_rs2Idx == REG_IDX'0) // X0 Register + idu_exe_rs2Data_EXE <= WORD_WID'0; + else if (rs2WrFwd_ID) begin // Write Foward + idu_exe_rs2Data_EXE <= wb_exe_rdData_WB; + else // Normal Read + idu_exe_rs2Data_EXE <= regData_XXX[idu_exe_rs1Idx_ID]; end // RD Write Port - if (wb_exe_rdData_WB) begin + if (wb_exe_rdWrVld_WB & (~|wb_exe_rdIdx_WB)) begin regData_XXX[wb_exe_rdIdx_WB] <= wb_exe_rdData_WB; end - end //---- @@ -92,29 +130,24 @@ module exe ( //---- // Operand Selection - assign aluIn1_EXE = (aluOp_EXE.rs1Sel == PC) ? pc_EXE : // PC for AUIPC, JAL - (aluOp_EXE.rs1Sel == ZERO) ? WORD_WID'(0) : // 0 for LUI - rs1Data_EXE; // RS1 for other operations + assign aluIn1_EXE = (aluOp_EXE.rs1Sel == PC) ? pc_EXE : // PC for AUIPC, JAL + (aluOp_EXE.rs1Sel == ZERO) ? WORD_WID'(0) : // 0 for LUI + rs1Data_EXE; // RS1 for other operations - assign aluIn2_EXE = (aluOp_EXE.rs2Sel == RS2) ? rs2Data_EXE : // RS2 for R type operations - aluOp_EXE.immediate; // Immediate for all other operations + assign aluIn2_EXE = (aluOp_EXE.rs2Sel == RS2) ? rs2Data_EXE : // RS2 for R type operations + aluOp_EXE.immediate; // Immediate for all other operations // Two's complement negation of aluIn2 if func7 is set (subtract) assign aluSumDiffIn1_EXE = aluIn1_EXE; assign aluSumDiffIn2_EXE = ({WORD_WID{aluOp_EXE.func7}} ^ aluIn2_EXE) + aluOp_EXE.func7; - assign aluSumDiff_EXE = aluSumDiffIn1_EXE + aluSumDiffIn2_EXE; + assign aluSumDiff_EXE = aluSumDiffIn1_EXE + aluSumDiffIn2_EXE; - // Shifter, TODO: Explicit signed barrel shifter + // Shifter, TODO: Explicit signed barrel shifter with sign bit assign aluRightShftUsign_EXE = aluIn1_EXE >> aluIn2_EXE[4:0]; - assign aluRightShftSext_EXE = ~({WORD_WID{1'b1}} >> aluIn2_EXE[4:0]); + assign aluRightShftSext_EXE = ~({WORD_WID{1'b1}} >> aluIn2_EXE[4:0]); assign aluRightShft_EXE = aluRightShftUsgn_EXE | (aluRightShftSext_EXE & {WORD_WID{aluOp_EXE.func7}}); - FLIP #( - .WIDTH(WORD_WID) - ) EXE_aluLeftShft ( - .in (aluRightShftUsign_EXE), - .out(aluLeftShft_EXE) - ); + FLIP #( .WIDTH(WORD_WID) ) EXE_aluLeftShft ( .in (aluRightShftUsign_EXE), .out(aluLeftShft_EXE) ); // Set Less Than assign aluCmpMsbDiff_EXE = aluIn2_EXE ^ aluIn1_EXE; @@ -152,22 +185,24 @@ module exe ( //------------------ // Branch Resolution //------------------ - assign exe_ifu_brPC_EXE = aluOpOut_EXE; - assign exe_ifu_brRes_EXE = brRes_EXE; // FIXME: Only send this once after a branch is processed until stall is lifted + assign exe_ifu_brPC_EXE = aluOpOut_EXE; + assign exe_ifu_brRes_EXE = brRes_EXE; + assign exe_ifu_brTaken_EXE = (brTaken_EXE & idu_exe_instrBr_ID) | idu_exe_instrJmp_ID; + assign brResChoice_EXE[0] = ~|aluXor_EXE; - assign brResChoice_EXE[1] = |aluXor_EXE; - assign brResChoice_EXE[2] = aluCmpSign_EXE; - assign brResChoice_EXE[3] = ~aluCmpSign_EXE; - assign brResChoice_EXE[4] = aluCmpUSign_EXE; - assign brResChoice_EXE[5] = ~aluCmpUSign_EXE; + assign brResChoice_EXE[1] = |aluXor_EXE; + assign brResChoice_EXE[2] = aluCmpSign_EXE; + assign brResChoice_EXE[3] = ~aluCmpSign_EXE; + assign brResChoice_EXE[4] = aluCmpUSign_EXE; + assign brResChoice_EXE[5] = ~aluCmpUSign_EXE; EMUX #( .WIDTH (1), .INPUTS(6) ) EMUX_exe_aluOpSel ( .in (brResChoice_EXE), - .out(exe_ifu_brTaken_EXE), + .out(brTaken_EXE), .sel(idu_exe_brOp_ID) ); @@ -175,5 +210,27 @@ module exe ( // Pipeline passthrough //--------------------- + // Memory + AFF #(.DTYPE(mem_op_t)) AFF_EXE_instRdDataSel ( + .q(exe_mem_instrMemOp_EXE), + .d(idu_exe_instrMemOp_ID), + .en(stallVld_ID), + .clk(clk) + ); + + AFF #(.DTYPE(mem_op_size_t)) AFF_EXE_instMemSize ( + .q(exe_mem_instrMemSize_EXE), + .d(idu_exe_instrMemSize_ID), + .en(stallVld_ID), + .clk(clk) + ); + + // Write Back + AFF #(.DTYPE(rd_data_sel_t)) AFF_EXE_instRdDataSel ( + .q(exe_mem_instrRdDataSel_EXE), + .d(idu_exe_instrRdDataSel_ID), + .en(stallVld_ID), + .clk(clk) + ); endmodule |