diff options
author | Joshua Yun <joshua@joshuayun.com> | 2025-03-25 00:29:30 -0500 |
---|---|---|
committer | Joshua Yun <joshua@joshuayun.com> | 2025-03-25 00:29:30 -0500 |
commit | 86021b3616c24efe38d8869b45d201bf24fe9a07 (patch) | |
tree | 445ec3b30de9451604f12c96c18fdbb975fbaf66 /core/rtl | |
parent | 6bd9f4f7ab48576d3fda98bef915162a7436866d (diff) | |
download | riscv-processor-86021b3616c24efe38d8869b45d201bf24fe9a07.tar.gz |
feat: initial completion of decode stage, fix: removed hardcoded path for riscv assembly files in TB
Diffstat (limited to 'core/rtl')
-rw-r--r-- | core/rtl/decode.sv | 135 |
1 files changed, 118 insertions, 17 deletions
diff --git a/core/rtl/decode.sv b/core/rtl/decode.sv index e337e11..8642013 100644 --- a/core/rtl/decode.sv +++ b/core/rtl/decode.sv @@ -7,28 +7,129 @@ import riscv_types::*; input logic rst_l, // I-MEM Interface - input logic [31:0] imem_id_instr_ID + input logic [31:0] imem_id_instr_ID, + + // Fetch Interface + input logic [31:0] imem_id_pc_ID + + // Dispatch Interface ); +// OpCode opcode_t instrOpCode_ID; -assign instrOpCode_ID = opcode_t'(imem_id_instr_ID[6:0]); +// Instruction Type +logic instrTypeR_ID; +logic instrTypeI_ID; +logic instrTypeS_ID; +logic instrTypeB_ID; +logic instrTypeU_ID; +logic instrTypeJ_ID; + + // Immediate +logic [31:0] instrImm_ID; +logic instrImmSign_ID; + +// Register Indices +logic [4:0] instrRs1Idx_ID; +logic instrRs1Vld_ID; +logic [4:0] instrRs2Idx_ID; +logic instrRs2Vld_ID; +logic [4:0] instrRdIdx_ID; +logic instrRdVld_ID; + +// Funct3 and Funct7 +logic [2:0] instrFunct3_ID; +logic instrFunct7_ID; + +// Control Bits -always_ff @(posedge clk) begin - $display("Instruction: %x", imem_id_instr_ID); - case (instrOpCode_ID) - INSTR_TYPE_LUI: begin $display("Instr type: LUI"); end - INSTR_TYPE_AUIPC: begin $display("Instr type: AUIPC"); end - INSTR_TYPE_JAL: begin $display("Instr type: JAL"); end - INSTR_TYPE_JALR: begin $display("Instr type: JALR"); end - INSTR_TYPE_BR: begin $display("Instr type: BR"); end - INSTR_TYPE_LD: begin $display("Instr type: LD"); end - INSTR_TYPE_ST: begin $display("Instr type: ST"); end - INSTR_TYPE_IMM: begin $display("Instr type: IMM"); end - INSTR_TYPE_REG: begin $display("Instr type: REG"); end - INSTR_TYPE_CSR: begin $display("Instr type: CSR"); end - default: begin $display("Instr type: Unknown"); end - endcase +// Memory Op +mem_op_t instrMemOp_ID; + +// Branch OP +brjmp_op_t instrBrJmpOp_ID; + +// ALU Operand Selection +aluSelOp1_t instrAluOp1_ID; +aluSelOp2_t instrAluOp2_ID; + +// DEBUG: Display decode instr +always_ff @(clk) begin : f_print_decode + $display("OpCode: %s", instrOpCode_ID.name()); + $display("Immediate: %0d", instrImm_ID); + $display("Memory: %s", instrMemOp_ID.name()); + $display("Branch: %s", instrBrJmpOp_ID.name()); + $display("ALU Sel 1: %s", instrAluOp1_ID.name()); + $display("ALU Sel 2: %s", instrAluOp2_ID.name()); + $display("Funct3: %0x", instrFunct3_ID); + $display("Funct7: %0x", instrFunct7_ID); end +// 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]); + +// Immediate Decode +assign instrImm_ID[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 + '0; // All other instructions set to 0 + +assign instrImm_ID[4:1] = instrTypeI_ID ? imem_id_instr_ID[24:21] : // I-Type bits + (instrTypeS_ID | instrTypeB_ID) ? imem_id_instr_ID[11:8] : // S-Type + B-Type bits + '0; // All other instructions set to 0 + +assign instrImm_ID[10:5] = instrTypeU_ID ? '0 : imem_id_instr_ID[30:25]; // Only J type is an immediate instruction that doesn't have it in 30:25 + + +assign instrImm_ID[11] = (instrTypeI_ID | instrTypeS_ID) ? imem_id_instr_ID[31] : + (instrTypeB_ID) ? imem_id_instr_ID[7] : + (instrTypeJ_ID) ? imem_id_instr_ID[20] : + '0; + +assign instrImm_ID[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 instrImm_ID[31:20] = (instrTypeU_ID) ? imem_id_instr_ID[31:20] : {12{instrImmSign_ID}}; // Only U type use 31:20 as not sign bit + +// Control Bits +assign instrMemOp_ID = (instrOpCode_ID == INSTR_TYPE_ST) ? MEM_OP_STORE : + (instrOpCode_ID == INSTR_TYPE_LD) ? MEM_OP_LOAD : + MEM_OP_NONE; + +assign instrBrJmpOp_ID = (instrOpCode_ID == INSTR_TYPE_JALR) ? REG_IMM_OFFSET : + (instrOpCode_ID == INSTR_TYPE_BR | instrOpCode_ID == INSTR_TYPE_JAL) ? PC_IMM_OFFSET : + OFFSET_NONE; + +assign instrAluOp1_ID = (instrOpCode_ID == INSTR_TYPE_AUIPC) | (instrOpCode_ID == INSTR_TYPE_JAL) ? PC : // Loading PC for AUIPC, PC Offset for JAL + (instrOpCode_ID == INSTR_TYPE_LUI) ? OP_NONE : // Only loading immediate for LUI + RS1; // All else use RS1 value + +assign instrAluOp2_ID = (instrOpCode_ID == INSTR_TYPE_REG) ? RS2 : IMM; // Only R2R needs non-immediate op in ALU + + endmodule |