diff options
Diffstat (limited to 'core/rtl/idu.sv')
-rw-r--r-- | core/rtl/idu.sv | 160 |
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 |