rv32g-core

Pipelined, synthesizable, and fabricable RISC-V core in SystemVerilog+Yosys+OpenROAD
Log | Files | Refs | LICENSE

commit 0697dae7c278f7d3b076fb1617d6c155b63e31fc
parent 01e6e1ad0d0252ae4279a94cbf21deee8300965e
Author: Vineet Kumar <git@vineetk.net>
Date:   Mon,  1 Jun 2026 15:40:14 -0400

make a package for user-defined types

Diffstat:
Mrtl/rv32g_hart.sv | 16++++++++++------
Artl/rv32g_pkg.sv | 85+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mrtl/stage_decode.sv | 98+++++++------------------------------------------------------------------------
3 files changed, 103 insertions(+), 96 deletions(-)

diff --git a/rtl/rv32g_hart.sv b/rtl/rv32g_hart.sv @@ -1,4 +1,5 @@ module rv32g_hart + import rv32g_pkg::*; (input logic clk, input logic rstN, @@ -11,14 +12,17 @@ module rv32g_hart output logic [31:0] dmem_wdata, output logic dmem_we); - typedef logic [31:0] reg_t; - // x0 to x31 - reg_t regfile [0:31]; + reg_t regfile [0:31]; reg_t pc; - reg_t next_pc; - logic [31:0] inst; - logic ctrl; // TODO change to struct + reg_t next_pc; + + logic [31:0] inst; + ctrl_t ctrl; + logic [31:0] imm; + reg_t rs1_val; + reg_t rs2_val; + logic [4:0] rd_num; assign regfile[0] = 'd0; always_ff @(posedge clk or negedge rstN) begin diff --git a/rtl/rv32g_pkg.sv b/rtl/rv32g_pkg.sv @@ -0,0 +1,85 @@ +package rv32g_pkg; + typedef logic [31:0] reg_t; + + typedef enum logic [3:0] {// rv32i + ALU_NONE, + ALU_ADD, + ALU_SUB, + ALU_XOR, + ALU_OR, + ALU_AND, + ALU_SLL, + ALU_SRL, + ALU_SRA, + ALU_SLT, + ALU_SLTU + // TODO rv32m + // ALU_MUL, + // ALU_DIV, + // ALU_REM, + // TODO rv32a + // TODO rv32f + // TODO rv32d + } aluop_t; + + typedef enum logic [1:0] {ALUOP1_NONE, + ALUOP1_REG, // pretty much every intruction except AUIPC + ALUOP1_PC // AUIPC is special :) + } aluop1src_t; + + typedef enum logic [1:0] {ALUOP2_NONE, + ALUOP2_REG, // R-type and S-type instructions + ALUOP2_IMM // sign-extended immediate for I-type and JALR + } aluop2src_t; + + typedef enum logic [3:0] {MEM_NONE, + MEM_LB, + MEM_LH, + MEM_LW, + MEM_LBU, + MEM_LHU, + MEM_SB, + MEM_SH, + MEM_SW + } memop_t; + + typedef enum logic [2:0] {BRANCH_NONE, + BRANCH_BEQ, + BRANCH_BNE, + BRANCH_BLT, + BRANCH_BGE, + BRANCH_BLTU, + BRANCH_BGEU + } branchop_t; + + typedef enum logic [1:0] {PC_SEQ, // PC = PC + 4 (regular) + PC_IMM, // PC = PC + imm (branch and jal) + PC_ALU // PC = rs1 + imm (jalr) + } pcsrc_t; + + typedef enum logic [2:0] {WB_NONE, // no register writeback + WB_PC, // JAL writes using PC adder + WB_ALU, // R-type and I-type instructions + WB_MEM, // All load instructions + WB_IMM // LUI writes back an immediate value + } wbsrc_t; + + // very rudimentary. privileged spec (chapter 3) defines this formally, but left to implementation + // on unprivileged spec. + typedef enum logic [1:0] {EXC_NONE, + EXC_ILL_INST, // illegal instruction + EXC_CALL, // ECALL + EXC_BKPT // EBREAK + } exception_t; + + typedef struct packed { + aluop_t aluop; + aluop1src_t aluop1src; + aluop2src_t aluop2src; + memop_t memop; + pcsrc_t pcsrc; + branchop_t branchop; + wbsrc_t wbsrc; + exception_t exception; + } ctrl_t; +endpackage: rv32g_pkg diff --git a/rtl/stage_decode.sv b/rtl/stage_decode.sv @@ -1,94 +1,12 @@ -// TODO move main typedefs to package -typedef enum logic [3:0] {// rv32i - ALU_NONE, - ALU_ADD, - ALU_SUB, - ALU_XOR, - ALU_OR, - ALU_AND, - ALU_SLL, - ALU_SRL, - ALU_SRA, - ALU_SLT, - ALU_SLTU - // TODO rv32m - // ALU_MUL, - // ALU_DIV, - // ALU_REM, - // TODO rv32a - // TODO rv32f - // TODO rv32d -} aluop_t; - -typedef enum logic [1:0] {ALUOP1_NONE, - ALUOP1_REG, // pretty much every intruction except AUIPC - ALUOP1_PC // AUIPC is special :) -} aluop1src_t; - -typedef enum logic [1:0] {ALUOP2_NONE, - ALUOP2_REG, // R-type and S-type instructions - ALUOP2_IMM // sign-extended immediate for I-type and JALR -} aluop2src_t; - -typedef enum logic [3:0] {MEM_NONE, - MEM_LB, - MEM_LH, - MEM_LW, - MEM_LBU, - MEM_LHU, - MEM_SB, - MEM_SH, - MEM_SW -} memop_t; - -typedef enum logic [2:0] {BRANCH_NONE, - BRANCH_BEQ, - BRANCH_BNE, - BRANCH_BLT, - BRANCH_BGE, - BRANCH_BLTU, - BRANCH_BGEU -} branchop_t; - -typedef enum logic [1:0] {PC_SEQ, // PC = PC + 4 (regular) - PC_IMM, // PC = PC + imm (branch and jal) - PC_ALU // PC = rs1 + imm (jalr) -} pcsrc_t; - -typedef enum logic [2:0] {WB_NONE, // no register writeback - WB_PC, // JAL writes using PC adder - WB_ALU, // R-type and I-type instructions - WB_MEM, // All load instructions - WB_IMM // LUI writes back an immediate value -} wbsrc_t; - -// very rudimentary. privileged spec (chapter 3) defines this formally, but left to implementation -// on unprivileged spec. -typedef enum logic [1:0] {EXC_NONE, - EXC_ILL_INST, // illegal instruction - EXC_CALL, // ECALL - EXC_BKPT // EBREAK -} exception_t; - -typedef struct packed { - aluop_t aluop; - aluop1src_t aluop1src; - aluop2src_t aluop2src; - memop_t memop; - pcsrc_t pcsrc; - branchop_t branchop; - wbsrc_t wbsrc; - exception_t exception; -} ctrl_t; - module stage_decode - (input logic [31:0] inst, - input logic [31:0] regfile [0:31], - output ctrl_t ctrl, - output logic [31:0] imm, - output logic [31:0] rs1_val, - output logic [31:0] rs2_val, - output logic [4:0] rd_num); + import rv32g_pkg::*; + (input logic [31:0] inst, + input logic [31:0] regfile [0:31], + output ctrl_t ctrl, + output logic [31:0] imm, + output logic [31:0] rs1_val, + output logic [31:0] rs2_val, + output logic [4:0] rd_num); typedef enum logic [3:0] {INVALIDTYPE, RTYPE,