commit b912995e94db9b6dad3d569897771ac3336e66ea
parent dd7a05cc0e99dde0c7c9db643ffbe2bacf84d186
Author: Vineet Kumar <git@vineetk.net>
Date: Sun, 31 May 2026 17:26:14 -0400
parse instructions into names to generate control signals
Diffstat:
| M | rtl/stage_decode.sv | | | 92 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- |
1 file changed, 80 insertions(+), 12 deletions(-)
diff --git a/rtl/stage_decode.sv b/rtl/stage_decode.sv
@@ -16,7 +16,7 @@ module stage_decode
JTYPE}
inst_type_t;
- typedef enum {INVALID,
+ typedef enum {NAME_INVALID,
// rv32i
LUI,
AUIPC,
@@ -30,6 +30,7 @@ module stage_decode
BGEU,
LB,
LH,
+ LW,
LBU,
LHU,
SB,
@@ -64,17 +65,17 @@ module stage_decode
// based off of Unprivileged ISA Chapter 36 Table 72 (no reserved)
typedef enum logic [6:0] {OPCODE_INVALID = 'b0000000,
// rv32i/m
+ OPCODE_LUI = 'b0110111,
+ OPCODE_AUIPC = 'b0010111,
+ OPCODE_JAL = 'b1101111,
+ OPCODE_JALR = 'b1100111,
+ OPCODE_BRANCH = 'b1100011,
OPCODE_LOAD = 'b0000011,
OPCODE_STORE = 'b0100011,
- OPCODE_BRANCH = 'b1100011,
- OPCODE_JALR = 'b1100111,
- OPCODE_JAL = 'b1101111,
- OPCODE_MISC_MEM = 'b0001111,
OPCODE_OP_IMM = 'b0010011,
OPCODE_OP = 'b0110011,
+ OPCODE_MISC_MEM = 'b0001111,
OPCODE_SYSTEM = 'b1110011,
- OPCODE_AUIPC = 'b0010111,
- OPCODE_LUI = 'b0110111,
// rv32f/d
OPCODE_LOAD_FP = 'b0000111,
OPCODE_STORE_FP = 'b0100111,
@@ -93,7 +94,7 @@ module stage_decode
OPCODE_CUSTOM_1 = 'b0101011,
OPCODE_CUSTOM_2 = 'b1011011,
OPCODE_CUSTOM_3 = 'b1111011}
- opcode_t;
+ opcode_t;
logic [6:0] funct7 = inst[31:25];
logic [4:0] rs2_num = inst[24:20];
@@ -109,15 +110,15 @@ module stage_decode
always_comb begin
unique case (opcode)
// rv32i
- OPCODE_OP: inst_type = RTYPE;
- OPCODE_OP_IMM: inst_type = ITYPE;
- OPCODE_AUIPC: inst_type = ITYPE;
OPCODE_LUI: inst_type = ITYPE;
- OPCODE_BRANCH: inst_type = BTYPE;
+ OPCODE_AUIPC: inst_type = ITYPE;
OPCODE_JAL: inst_type = JTYPE;
OPCODE_JALR: inst_type = ITYPE;
+ OPCODE_BRANCH: inst_type = BTYPE;
OPCODE_LOAD: inst_type = ITYPE;
OPCODE_STORE: inst_type = STYPE;
+ OPCODE_OP_IMM: inst_type = ITYPE;
+ OPCODE_OP: inst_type = RTYPE;
OPCODE_MISC_MEM: inst_type = ITYPE;
OPCODE_SYSTEM: inst_type = ITYPE;
default: inst_type = INVALIDTYPE;
@@ -137,6 +138,73 @@ module stage_decode
endcase
end
+ // parse what the actual instruction
+ always_comb begin
+ casez ({funct7, funct3, opcode})
+ // rv32i
+ {7'b???????, 3'b???, OPCODE_LUI}: name = LUI;
+ {7'b???????, 3'b???, OPCODE_AUIPC}: name = AUIPC;
+ {7'b???????, 3'b???, OPCODE_JAL}: name = JAL;
+ {7'b???????, 3'b???, OPCODE_JALR}: name = JALR;
+ {7'b???????, 3'b000, OPCODE_BRANCH}: name = BEQ;
+ {7'b???????, 3'b001, OPCODE_BRANCH}: name = BNE;
+ {7'b???????, 3'b100, OPCODE_BRANCH}: name = BLT;
+ {7'b???????, 3'b101, OPCODE_BRANCH}: name = BGE;
+ {7'b???????, 3'b110, OPCODE_BRANCH}: name = BLTU;
+ {7'b???????, 3'b111, OPCODE_BRANCH}: name = BGEU;
+ {7'b???????, 3'b000, OPCODE_LOAD}: name = LB;
+ {7'b???????, 3'b001, OPCODE_LOAD}: name = LH;
+ {7'b???????, 3'b010, OPCODE_LOAD}: name = LW;
+ {7'b???????, 3'b100, OPCODE_LOAD}: name = LBU;
+ {7'b???????, 3'b101, OPCODE_LOAD}: name = LHU;
+ {7'b???????, 3'b000, OPCODE_STORE}: name = SB;
+ {7'b???????, 3'b001, OPCODE_STORE}: name = SH;
+ {7'b???????, 3'b010, OPCODE_STORE}: name = SW;
+ {7'b???????, 3'b000, OPCODE_OP_IMM}: name = ADDI;
+ {7'b???????, 3'b010, OPCODE_OP_IMM}: name = SLTI;
+ {7'b???????, 3'b011, OPCODE_OP_IMM}: name = SLTIU;
+ {7'b???????, 3'b100, OPCODE_OP_IMM}: name = XORI;
+ {7'b???????, 3'b110, OPCODE_OP_IMM}: name = ORI;
+ {7'b???????, 3'b111, OPCODE_OP_IMM}: name = ANDI;
+ {7'b0000000, 3'b001, OPCODE_OP_IMM}: name = SLLI;
+ {7'b0000000, 3'b101, OPCODE_OP_IMM}: name = SRLI;
+ {7'b0100000, 3'b101, OPCODE_OP_IMM}: name = SRAI;
+ {7'b0000000, 3'b000, OPCODE_OP}: name = ADD;
+ {7'b0100000, 3'b000, OPCODE_OP}: name = SUB;
+ {7'b0000000, 3'b001, OPCODE_OP}: name = SLL;
+ {7'b0000000, 3'b010, OPCODE_OP}: name = SLT;
+ {7'b0000000, 3'b011, OPCODE_OP}: name = SLTU;
+ {7'b0000000, 3'b100, OPCODE_OP}: name = XOR;
+ {7'b0000000, 3'b101, OPCODE_OP}: name = SRL;
+ {7'b0100000, 3'b101, OPCODE_OP}: name = SRA;
+ {7'b0000000, 3'b110, OPCODE_OP}: name = OR;
+ {7'b0000000, 3'b111, OPCODE_OP}: name = AND;
+ {7'b???????, 3'b000, OPCODE_MISC_MEM}: begin
+ // FENCE{,.TSO}/PAUSE encoding is a bit different
+ if (rs1_num == '0) begin
+ if (inst[31:20] == 'b1000_0011_0011) name = FENCE_TSO;
+ else if (inst[31:20] == 'b0000_0001_0000) name = PAUSE;
+ else name = NAME_INVALID;
+ end else name = FENCE;
+ end
+ {7'b0000000, 3'b000, OPCODE_SYSTEM}: begin
+ // ECALL and EBREAK encoding is also a bit different
+ if (rs1_num == '0 && rd_num == '0 && rs2_num[4:1] == '0) begin
+ name = (rs2_num[0] == '0) ? ECALL : EBREAK;
+ end else name = NAME_INVALID;
+ end
+ default: name = NAME_INVALID;
+ endcase
+ end
+
+ // set control signals based on instruction name
+ always_comb begin
+ case (name)
+ // rv32i
+ default: ctrl = '0;
+ endcase
+ end
+
assign rs1_val = regfile[rs1_num];
assign rs2_val = regfile[rs2_num];