stage_decode.sv (5652B)
1 module stage_decode 2 import rv32g_pkg::*; 3 (input logic clk, 4 input logic rstN, 5 input logic [31:0] inst, 6 input logic wb_we, 7 input logic [4:0] wb_rd_num, 8 input logic [31:0] wb_data, 9 output ctrl_t ctrl, 10 output logic [31:0] imm, 11 output logic [31:0] rs1_val, 12 output logic [31:0] rs2_val, 13 output logic [4:0] rs1_num, 14 output logic [4:0] rs2_num, 15 output logic [4:0] rd_num); 16 17 logic [6:0] funct7; 18 logic [2:0] funct3; 19 opcode_t opcode; 20 inst_type_t inst_type; 21 reg_t regfile [0:31]; 22 reg_t regfile_b [0:31]; 23 24 always_comb begin 25 funct7 = inst[31:25]; 26 rs2_num = inst[24:20]; 27 rs1_num = inst[19:15]; 28 funct3 = inst[14:12]; 29 rd_num = inst[11:7]; 30 opcode = opcode_t'(inst[6:0]); 31 end 32 33 // parse the type for each instruction 34 always_comb begin 35 unique case (opcode) 36 // rv32i 37 OPCODE_LUI: inst_type = UTYPE; 38 OPCODE_AUIPC: inst_type = UTYPE; 39 OPCODE_JAL: inst_type = JTYPE; 40 OPCODE_JALR: inst_type = ITYPE; 41 OPCODE_BRANCH: inst_type = BTYPE; 42 OPCODE_LOAD: inst_type = ITYPE; 43 OPCODE_STORE: inst_type = STYPE; 44 OPCODE_OP_IMM: inst_type = ITYPE; 45 OPCODE_OP: inst_type = RTYPE; 46 OPCODE_MISC_MEM: inst_type = ITYPE; 47 OPCODE_SYSTEM: inst_type = ITYPE; 48 default: inst_type = INVALIDTYPE; 49 endcase 50 end 51 52 // parse the (sign-extended) immediate value 53 // based off of Unprivileged ISA Section 2.3 Figure 1 54 always_comb begin 55 unique case (inst_type) 56 ITYPE: imm = {{20{inst[31]}}, inst[31:20]}; 57 STYPE: imm = {{20{inst[31]}}, inst[31:25], inst[11:7]}; 58 BTYPE: imm = {{20{inst[31]}}, inst[7], inst[30:25], inst[11:8], 1'b0}; 59 UTYPE: imm = inst[31:12] << 12; 60 JTYPE: imm = {{12{inst[31]}}, inst[19:12], inst[20], inst[30:25], inst[24:21], 1'b0}; 61 default: imm = '0; 62 endcase 63 end 64 65 // set control signals 66 always_comb begin 67 ctrl = '{aluop: ALU_NONE, 68 aluop1src: ALUOP1_NONE, 69 aluop2src: ALUOP2_NONE, 70 loadop: LD_NONE, 71 storeop: ST_NONE, 72 pcsrc: PC_SEQ, 73 branchop: BRANCH_NONE, 74 wbsrc: WB_NONE, 75 exception: EXC_NONE, 76 fence_flush: 1'b0}; 77 78 // the major opcodes share the same signals, just operation varies based on funct 79 unique case (opcode) 80 OPCODE_LUI: ctrl.wbsrc = WB_IMM; 81 OPCODE_AUIPC: begin 82 ctrl.aluop = ALU_ADD; 83 ctrl.aluop1src = ALUOP1_PC; 84 ctrl.aluop2src = ALUOP2_IMM; 85 ctrl.wbsrc = WB_ALU; 86 end 87 OPCODE_JAL: begin 88 ctrl.pcsrc = PC_IMM; 89 ctrl.wbsrc = WB_PC; 90 end 91 OPCODE_JALR: begin 92 ctrl.aluop = ALU_ADD; 93 ctrl.aluop1src = ALUOP1_REG; 94 ctrl.aluop2src = ALUOP2_IMM; 95 ctrl.pcsrc = PC_ALU; 96 ctrl.wbsrc = WB_PC; 97 end 98 OPCODE_BRANCH: begin 99 ctrl.aluop1src = ALUOP1_REG; 100 ctrl.aluop2src = ALUOP2_REG; 101 ctrl.pcsrc = PC_IMM; 102 ctrl.branchop = branchop_t'(funct3); 103 end 104 OPCODE_LOAD: begin 105 ctrl.aluop = ALU_ADD; 106 ctrl.aluop1src = ALUOP1_REG; 107 ctrl.aluop2src = ALUOP2_IMM; 108 ctrl.wbsrc = WB_MEM; 109 ctrl.loadop = loadop_t'(funct3); 110 end 111 OPCODE_STORE: begin 112 ctrl.aluop = ALU_ADD; 113 ctrl.aluop1src = ALUOP1_REG; 114 ctrl.aluop2src = ALUOP2_IMM; 115 ctrl.storeop = storeop_t'(funct3); 116 end 117 OPCODE_OP_IMM: begin 118 ctrl.aluop1src = ALUOP1_REG; 119 ctrl.aluop2src = ALUOP2_IMM; 120 ctrl.wbsrc = WB_ALU; 121 unique case (funct3) 122 // rv32i; done in same order as it appears in chapter 36 of unprivileged manual 123 3'b000: ctrl.aluop = ALU_ADD; 124 3'b010: ctrl.aluop = ALU_SLT; 125 3'b011: ctrl.aluop = ALU_SLTU; 126 3'b100: ctrl.aluop = ALU_XOR; 127 3'b110: ctrl.aluop = ALU_OR; 128 3'b111: ctrl.aluop = ALU_AND; 129 3'b001: ctrl.aluop = (funct7 == '0) ? ALU_SLL : ALU_NONE; 130 3'b101: begin 131 if ({funct7[6], funct7[4:0]} == '0) ctrl.aluop = (funct7[5] == '0) ? ALU_SRL : ALU_SRA; 132 else ctrl.aluop = ALU_NONE; 133 end 134 endcase 135 end 136 OPCODE_OP: begin 137 ctrl.aluop1src = ALUOP1_REG; 138 ctrl.aluop2src = ALUOP2_REG; 139 ctrl.wbsrc = WB_ALU; 140 unique case ({funct7, funct3}) 141 // rv32i 142 {7'b0000000, 3'b000}: ctrl.aluop = ALU_ADD; 143 {7'b0100000, 3'b000}: ctrl.aluop = ALU_SUB; 144 {7'b0000000, 3'b001}: ctrl.aluop = ALU_SLL; 145 {7'b0000000, 3'b010}: ctrl.aluop = ALU_SLT; 146 {7'b0000000, 3'b011}: ctrl.aluop = ALU_SLTU; 147 {7'b0000000, 3'b100}: ctrl.aluop = ALU_XOR; 148 {7'b0000000, 3'b101}: ctrl.aluop = ALU_SRL; 149 {7'b0100000, 3'b101}: ctrl.aluop = ALU_SRA; 150 {7'b0000000, 3'b110}: ctrl.aluop = ALU_OR; 151 {7'b0000000, 3'b111}: ctrl.aluop = ALU_AND; 152 default: ctrl.aluop = ALU_NONE; 153 endcase 154 end 155 OPCODE_MISC_MEM: ctrl.fence_flush = rs1_num == '0 && rd_num == '0 && inst[31:20] == '0; 156 OPCODE_SYSTEM: begin 157 // ECALL and EBREAK encoding is also a bit different 158 if (rs1_num == '0 && rd_num == '0 && rs2_num[4:1] == '0) begin 159 ctrl.exception = (rs2_num[0] == '0) ? EXC_CALL : EXC_BKPT; 160 end else ctrl.exception = EXC_NONE; 161 end 162 default: ; 163 endcase 164 end 165 166 always_ff @(posedge clk or negedge rstN) begin 167 if (!rstN) begin 168 rs1_val <= '0; 169 rs2_val <= '0; 170 end else begin 171 if (wb_we) begin 172 regfile[wb_rd_num] <= wb_data; 173 regfile_b[wb_rd_num] <= wb_data; 174 end 175 176 rs1_val <= (rs1_num == 0) ? '0 : 177 ((wb_we && wb_rd_num == rs1_num) ? wb_data : regfile[rs1_num]); 178 rs2_val <= (rs2_num == 0) ? '0 : 179 ((wb_we && wb_rd_num == rs2_num) ? wb_data : regfile_b[rs2_num]); 180 end 181 end 182 183 endmodule: stage_decode