aboutsummaryrefslogtreecommitdiff
path: root/core/rtl/idu.sv
diff options
context:
space:
mode:
Diffstat (limited to 'core/rtl/idu.sv')
-rw-r--r--core/rtl/idu.sv160
1 files changed, 160 insertions, 0 deletions
diff --git a/core/rtl/idu.sv b/core/rtl/idu.sv
new file mode 100644
index 0000000..0bfd073
--- /dev/null
+++ b/core/rtl/idu.sv
@@ -0,0 +1,160 @@
+module idu
+import riscv_types::*;
+#(
+ )
+ (
+ input logic clk,
+ input logic rst_l,
+
+ // I-MEM Interface
+ input logic [INSTR_SIZE-1:0] imem_id_instr_ID,
+
+ // Fetch Interface
+ input logic [PC_SIZE-1:0] imem_id_pc_ID,
+
+ //------------------
+ // Execute Interface
+ //------------------
+ input logic exe_idu_exeRdy_EXE,
+
+ // Alu information
+ output alu_op_t idu_exe_aluOp_ID,
+
+ // Register Idx
+ 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
+ );
+
+// OpCode
+opcode_t instrOpCode_ID;
+
+// Instruction Type
+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;
+
+// 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;
+
+// Funct3 and Funct7
+logic [2:0] instrFunct3_ID;
+logic instrFunct7_ID;
+
+// Control Bits
+
+// Memory Op
+mem_op_t instrMemOp_ID;
+
+// Branch OP
+brjmp_op_t instrBrJmpOp_ID;
+
+// ALU Operand Selection
+aluSelOp1_t instrAluIn1_ID;
+aluSelOp2_t instrAluIn2_ID;
+
+// Reg File
+logic [NUM_REG-1:0] [WORD_WID-1:0] regData_XXX;
+
+//------------------------
+// Instruction Type Decode
+//------------------------
+
+// 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);
+
+// Register Index Decode
+assign instrRs1Idx_ID = imem_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 instrRs2Vld_ID = instrTypeR_ID | instrTypeS_ID | instrTypeB_ID;
+
+assign instrRdIdx_ID = imem_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];
+
+// 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 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}} & 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) & 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) ? 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.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
+
+assign idu_exe_aluOp_ID.rs2Sel = (instrOpCode_ID == INSTR_TYPE_REG) ? RS2 : IMM; // Only R Type needs non-immediate op in ALU
+
+assign idu_exe_aluOp_ID.func3 = imem_id_instr_ID[14:12];
+assign idu_exe_aluOp_ID.func7 = imem_id_instr_ID[30];
+
+//---------------
+// 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
+
+//---------------
+// Memory Control
+//---------------
+assign instrMemOp_ID = (instrOpCode_ID == INSTR_TYPE_ST) ? MEM_OP_STORE :
+ (instrOpCode_ID == INSTR_TYPE_LD) ? MEM_OP_LOAD :
+ MEM_OP_NONE;
+
+//------------------
+// Writeback Control
+//------------------
+
+
+assign instrAluOp_ID = ;
+
+
+endmodule