aboutsummaryrefslogtreecommitdiff
path: root/core/rtl/exe.sv
diff options
context:
space:
mode:
Diffstat (limited to 'core/rtl/exe.sv')
-rw-r--r--core/rtl/exe.sv191
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