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