aboutsummaryrefslogtreecommitdiff
path: root/core/rtl/idu.sv
diff options
context:
space:
mode:
authorJoshua Yun <joshua@joshuayun.com>2025-05-22 22:46:34 -0500
committerJoshua Yun <joshua@joshuayun.com>2025-05-22 22:46:34 -0500
commit88db611b50f16146bc6ca39f543348d0d9f5eadb (patch)
tree6374c9aec65ffd7a36581b9d9a319e197ed2cde4 /core/rtl/idu.sv
parente580017e209a0888c3f5a2063d265de50c66c56b (diff)
downloadriscv-processor-88db611b50f16146bc6ca39f543348d0d9f5eadb.tar.gz
finished exe stage
Diffstat (limited to 'core/rtl/idu.sv')
-rw-r--r--core/rtl/idu.sv199
1 files changed, 118 insertions, 81 deletions
diff --git a/core/rtl/idu.sv b/core/rtl/idu.sv
index 0bfd073..8736613 100644
--- a/core/rtl/idu.sv
+++ b/core/rtl/idu.sv
@@ -7,58 +7,76 @@ import riscv_types::*;
input logic rst_l,
// I-MEM Interface
- input logic [INSTR_SIZE-1:0] imem_id_instr_ID,
+ input logic imem_idu_vld_ID,
+ input logic [INSTR_SIZE-1:0] imem_idu_data_ID,
+ //----------------
// Fetch Interface
- input logic [PC_SIZE-1:0] imem_id_pc_ID,
+ //----------------
+ input logic [PC_SIZE-1:0] ifu_idu_pc_ID,
+ input logic ifu_idu_instrVld_ID
//------------------
// Execute Interface
//------------------
- input logic exe_idu_exeRdy_EXE,
-
- // Alu information
- output alu_op_t idu_exe_aluOp_ID,
+ output logic idu_exe_instrVld_EXE,
// Register Idx
- output logic idu_exe_rs1Vld_EXE,
- output logic [REG_IDX-1:0] idu_exe_rs1Idx_EXE,
+ output logic idu_exe_rs1Vld_EXE,
+ output logic [REG_IDX-1:0] idu_exe_rs1Idx_EXE,
+ output logic idu_exe_rs2Vld_EXE,
+ output logic [REG_IDX-1:0] idu_exe_rs2Idx_EXE,
+
+ // Branch Type
+ output logic idu_exe_instrJmp_ID,
+ output logic idu_exe_instrBr_ID,
+
+ // Alu information
+ output alu_op_t idu_exe_aluOp_ID,
- output logic idu_exe_rs2Vld_EXE,
- output logic [REG_IDX-1:0] idu_exe_rs2Idx_EXE
+ // Passthrough information
+ output mem_op_t idu_exe_instrMemOp_ID,
+ output mem_size_t idu_exe_instrMemSize_ID,
+ output rd_data_sel_t idu_exe_instrRdDataSel_ID
);
// OpCode
opcode_t instrOpCode_ID;
+// Instruction Op
+logic instrAuipc_ID;
+logic instrJal_ID;
+logic instrJal_ID;
+logic instrLui_ID;
+logic instrReg_ID;
+logic instrImm_ID;
+logic instrLd_ID;
+logic instrSt_ID;
+logic instrBr_ID;
+
// Instruction Type
-logic instrTypeR_ID;
-logic instrTypeI_ID;
-logic instrTypeS_ID;
-logic instrTypeB_ID;
-logic instrTypeU_ID;
-logic instrTypeJ_ID;
-
- // Immediate
+logic instrTypeR_ID;
+logic instrTypeI_ID;
+logic instrTypeS_ID;
+logic instrTypeB_ID;
+logic instrTypeU_ID;
+logic instrTypeJ_ID;
+
+// Immediate
logic [WORD_WID-1:0] instrImm_ID;
-logic instrImmSign_ID;
+logic instrImmSign_ID;
// Register Indices
-logic [REG_IDX-1:0] instrRs1Idx_ID;
-logic instrRs1Vld_ID;
-logic [REG_IDX-1:0] instrRs2Idx_ID;
-logic instrRs2Vld_ID;
-logic [REG_IDX-1:0] instrRdIdx_ID;
-logic instrRdVld_ID;
+logic [REG_IDX-1:0] instrRs1Idx_ID;
+logic instrRs1Vld_ID;
+logic [REG_IDX-1:0] instrRs2Idx_ID;
+logic instrRs2Vld_ID;
+logic [REG_IDX-1:0] instrRdIdx_ID;
+logic instrRdVld_ID;
// Funct3 and Funct7
-logic [2:0] instrFunct3_ID;
-logic instrFunct7_ID;
-
-// Control Bits
-
-// Memory Op
-mem_op_t instrMemOp_ID;
+logic [2:0] instrFunct3_ID;
+logic instrFunct7_ID;
// Branch OP
brjmp_op_t instrBrJmpOp_ID;
@@ -67,94 +85,113 @@ brjmp_op_t instrBrJmpOp_ID;
aluSelOp1_t instrAluIn1_ID;
aluSelOp2_t instrAluIn2_ID;
-// Reg File
-logic [NUM_REG-1:0] [WORD_WID-1:0] regData_XXX;
+//-------------------
+// Instruction Decode
+//-------------------
-//------------------------
-// Instruction Type Decode
-//------------------------
+assign instr_ID = imem_idu_data_ID;
+
+// Instruction Type (OpCode) Decode
+assign instrOpCode_ID = opcode_t'(instr_ID[6:0]);
+
+assign instrAuipc_ID = (instrOpCode_ID == INSTR_TYPE_AUIPC);
+assign instrJal_ID = (instrOpCode_ID == INSTR_TYPE_JAL);
+assign instrJal_ID = (instrOpCode_ID == INSTR_TYPE_JALR);
+assign instrLui_ID = (instrOpCode_ID == INSTR_TYPE_LUI);
+assign instrReg_ID = (instrOpCode_ID == INSTR_TYPE_REG);
+assign instrImm_ID = (instrOpCode_ID == INSTR_TYPE_IMM);
+assign instrLd_ID = (instrOpCode_ID == INSTR_TYPE_LD);
+assign instrSt_ID = (instrOpCode_ID == INSTR_TYPE_ST);
+assign instrBr_ID = (instrOpCode_ID == INSTR_TYPE_BR);
// FIXME: Add support for FENCE + ECALL + EBREAK + CSRs
-assign instrTypeI_ID = (instrOpCode_ID == INSTR_TYPE_IMM)
- | (instrOpCode_ID == INSTR_TYPE_JALR)
- | (instrOpCode_ID == INSTR_TYPE_LD);
-assign instrTypeU_ID = (instrOpCode_ID == INSTR_TYPE_LUI)
- | (instrOpCode_ID == INSTR_TYPE_AUIPC);
-assign instrTypeR_ID = (instrOpCode_ID == INSTR_TYPE_REG);
-assign instrTypeS_ID = (instrOpCode_ID == INSTR_TYPE_ST);
-assign instrTypeB_ID = (instrOpCode_ID == INSTR_TYPE_BR);
-assign instrTypeJ_ID = (instrOpCode_ID == INSTR_TYPE_JAL);
+assign instrTypeI_ID = instrImm_ID
+ | instrJal_IDR
+ | instrLd_ID;
+assign instrTypeU_ID = instrLui_ID
+ | instrLui_PC;
+assign instrTypeR_ID = instrReg_ID;
+assign instrTypeS_ID = instrSt_ID;
+assign instrTypeB_ID = instrBr_ID;
+assign instrTypeJ_ID = instrJal_ID;
// Register Index Decode
-assign instrRs1Idx_ID = imem_id_instr_ID[19:15];
+assign instrRs1Idx_ID = instr_ID[19:15];
assign instrRs1Vld_ID = instrTypeR_ID | instrTypeI_ID | instrTypeS_ID | instrTypeB_ID;
-assign instrRs2Idx_ID = imem_id_instr_ID[24:20];
+assign instrRs2Idx_ID = instr_ID[24:20];
assign instrRs2Vld_ID = instrTypeR_ID | instrTypeS_ID | instrTypeB_ID;
-assign instrRdIdx_ID = imem_id_instr_ID[11:7];
+assign instrRdIdx_ID = instr_ID[11:7];
assign instrRdVld_ID = instrTypeR_ID | instrTypeI_ID | instrTypeU_ID | instrTypeJ_ID;
// Func Bit decode
-assign instrFunct7_ID = imem_id_instr_ID[30];
-assign instrFunct3_ID = imem_id_instr_ID[14:12];
+assign instrFunct7_ID = instr_ID[30];
+assign instrFunct3_ID = instr_ID[14:12];
-// Instruction Type (OpCode) Decode
-assign instrImmSign_ID = imem_id_instr_ID[31];
-assign instrOpCode_ID = opcode_t'(imem_id_instr_ID[6:0]);
//----------------
// ALU Information
//----------------
// Immediate Decode
-assign idu_exe_aluOp_ID.imm[0] = instrTypeJ_ID ? imem_id_instr_ID[25] : // Bit 25 for I-Type
- instrTypeS_ID ? imem_id_instr_ID[7] : // Bit 7 for S-Type
- 1'b0; // All other instructions set to 0
+assign instrImmSign_ID = instr_ID[31];
+
+assign idu_exe_aluOp_ID.imm[0] = instrTypeI_ID ? instr_ID[20] : // Bit 20 for I-Type
+ instrTypeS_ID ? instr_ID[7] : // Bit 7 for S-Type
+ 1'b0; // All other instructions set to 0
+
+assign idu_exe_aluOp_ID.imm[4:1] = ({3{instrTypeI_ID | instrTypeJ_ID}} & instr_ID[24:21]) // I-Type + J-Type bits
+ | ({3{instrTypeS_ID | instrTypeB_ID}} & instr_ID[11:8]); // S-Type + B-Type bits
-assign idu_exe_aluOp_ID.imm[4:1] = ({3{instrTypeI_ID | instrTypeJ_ID}} & imem_id_instr_ID[24:21]) // I-Type + J-Type bits
- | ({3{instrTypeS_ID | instrTypeB_ID}} & imem_id_instr_ID[11:8]); // S-Type + B-Type bits
+assign idu_exe_aluOp_ID.imm[10:5] = {6{~instrTypeU_ID}} & instr_ID[30:25]; // U type doesn't use 10:5
-assign idu_exe_aluOp_ID.imm[10:5] = {6{~instrTypeU_ID}} & imem_id_instr_ID[30:25]; // U type is the only instr that doesn't have 10:5
+assign idu_exe_aluOp_ID.imm[11] = ((instrTypeI_ID | instrTypeS_ID) & instr_ID[31]) // I-Type + S-Type bit
+ | ( instrTypeB_ID & instr_ID[7]) // B-Type bit
+ | ( instrTypeJ_ID & instr_ID[20]); // J-Type bit
-assign idu_exe_aluOp_ID.imm[11] = ((instrTypeI_ID | instrTypeS_ID) & imem_id_instr_ID[31]) // I-Type + S-Type bit
- | ( instrTypeB_ID & imem_id_instr_ID[7]) // B-Type bit
- | ( instrTypeJ_ID & imem_id_instr_ID[20]); // J-Type bit
+assign idu_exe_aluOp_ID.imm[19:12] = (instrTypeU_ID | instrTypeJ_ID) ? instr_ID[19:12] : // J and U types use 19:12
+ {8{instrImmSign_ID}}; // Else use SEXT Bit
-assign idu_exe_aluOp_ID.imm[19:12] = (instrTypeU_ID | instrTypeJ_ID) ? imem_id_instr_ID[19:12] : { 8{instrImmSign_ID}}; // Only J and U types use 19:12 as not sign bit
-assign idu_exe_aluOp_ID.imm[31:20] = (instrTypeU_ID) ? imem_id_instr_ID[31:20] : {12{instrImmSign_ID}}; // Only U type use 31:20 as not sign bit
+assign idu_exe_aluOp_ID.imm[31:20] = (instrTypeU_ID) ? instr_ID[31:20] : // U type uses 31:20
+ {12{instrImmSign_ID}}; // Else use SEXT bit
-assign idu_exe_aluOp_ID.rs1Sel = (instrOpCode_ID == INSTR_TYPE_AUIPC) | (instrOpCode_ID == INSTR_TYPE_JAL) ? PC : // Loading PC for AUIPC, PC Offset for JAL
- (instrOpCode_ID == INSTR_TYPE_LUI) ? ZERO : // Only loading immediate for LUI
- RS1; // All else use RS1 value
+// ALU Operand Selection
+// FIXME: Make Non Priority Mux
+assign idu_exe_aluOp_ID.rs1Sel = (instrAuipc) | (instrJal) ? PC : // Loading PC for AUIPC, PC Offset for JAL
+ (instrLui) ? ZERO : // Only loading immediate for LUI
+ RS1; // All else use RS1 value
+
+assign idu_exe_aluOp_ID.rs2Sel = (instrReg) ? RS2 : // RS2 Used in R2R Instr
+ IMM; // Immediate used for all other instructions
-assign idu_exe_aluOp_ID.rs2Sel = (instrOpCode_ID == INSTR_TYPE_REG) ? RS2 : IMM; // Only R Type needs non-immediate op in ALU
+// Alu Control Signals
+assign idu_exe_aluOp_ID.func3 = instr_ID[14:12];
+assign idu_exe_aluOp_ID.func7 = instr_ID[30];
-assign idu_exe_aluOp_ID.func3 = imem_id_instr_ID[14:12];
-assign idu_exe_aluOp_ID.func7 = imem_id_instr_ID[30];
+// Supply PC for Jmp and AUIPC
+assign idu_exe_pc_ID = ifu_idu_pc_ID;
//---------------
// Branch Control
//---------------
-assign idu_exe_instrJmp_ID = (instrOpCode_ID == INSTR_TYPE_JALR) | (instrOpCode_ID == INSTR_TYPE_JAL);
-assign idu_exe_brAluOp_ID = (idu_exe_aluOp_ID.func3 == 3'b0) ? BR_ALU_XOR : BR_ALU_CMP; // Only equality needs XOR all other OPs use compare
-assign idu_exe_brCmpSign_ID = (idu_exe_aluOp_ID.func3[2:1] == 2'b11); // Unsigned comparisons have func3 top two bits set
-assign idu_exe_brCmpGreater_ID = (idu_exe_aluOp_ID.func3[2:1] == 2'b11); // Unsigned comparisons have func3 top two bits set
+assign idu_exe_instrJmp_ID = instrJal_ID | instrJalr_ID;
+assign idu_exe_instrBr_ID = instrBr_ID;
//---------------
// Memory Control
//---------------
-assign instrMemOp_ID = (instrOpCode_ID == INSTR_TYPE_ST) ? MEM_OP_STORE :
- (instrOpCode_ID == INSTR_TYPE_LD) ? MEM_OP_LOAD :
- MEM_OP_NONE;
+assign idu_exe_instrMemOp_ID = (instrSt_ID) ? MEM_OP_STORE :
+ (instrID_ID) ? MEM_OP_LOAD :
+ MEM_OP_NONE;
//------------------
// Writeback Control
//------------------
-
-
-assign instrAluOp_ID = ;
+assign idu_exe_instrRdDataSel_ID = (instrJal_ID | instrJalr_ID) ? PC : // Jump loads PC into RD
+ (instrLd_ID | instrSt_ID) ? MEM : // Mem loads memory into RD
+ ALU // All Other OPs load AlU result
endmodule