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