From a22f935d827879706a9b4ae481e05f22810f8b61 Mon Sep 17 00:00:00 2001 From: Warrick Lo Date: Tue, 16 Jun 2026 22:13:10 +0000 Subject: regfile: refactor: 'chunks' are now 'slices' The term 'slice' is more consistent with old CPU architectures and academic literature. Signed-off-by: Warrick Lo --- rtl/regfile.sv | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'rtl/regfile.sv') diff --git a/rtl/regfile.sv b/rtl/regfile.sv index 1758c1a..8ca992c 100644 --- a/rtl/regfile.sv +++ b/rtl/regfile.sv @@ -8,40 +8,40 @@ * Register file * * This module contains the register file for the RISC-V core. Each word is - * partitioned into chunks (default 8 bits). A global chunk selector determines - * which chunk of each word is accessed for both read and write operations. + * partitioned into slices (default 8 bits). A global slice selector determines + * which slice of each word is accessed for both read and write operations. * * The register file has one synchronous write port and a configurable number of * read ports (default 2). Register 0 is fixed to 0 for all reads. */ module regfile #( - parameter int unsigned WORD_WIDTH = 32, - parameter int unsigned ADDR_WIDTH = 4, - parameter int unsigned CHUNK_WIDTH = 8, + parameter int unsigned WORD_WIDTH = 32, + parameter int unsigned ADDR_WIDTH = 4, + parameter int unsigned SLICE_WIDTH = 8, parameter int unsigned NUM_READ_PORTS = 2, localparam int unsigned NUM_WORDS = 2 ** ADDR_WIDTH, - localparam int unsigned NUM_CHUNKS = WORD_WIDTH / CHUNK_WIDTH + localparam int unsigned NUM_SLICES = WORD_WIDTH / SLICE_WIDTH ) ( input logic clk_i, input logic rst_ni, - input logic [$clog2(NUM_CHUNKS)-1:0] chunk_sel_i, + input logic [$clog2(NUM_SLICES)-1:0] slice_sel_i, - input logic [NUM_READ_PORTS-1:0][ ADDR_WIDTH-1:0] raddr_i, - output logic [NUM_READ_PORTS-1:0][CHUNK_WIDTH-1:0] rdata_o, + input logic [NUM_READ_PORTS-1:0][ADDR_WIDTH-1:0] raddr_i, + output logic [NUM_READ_PORTS-1:0][SLICE_WIDTH-1:0] rdata_o, input logic wen_i, - input logic [ADDR_WIDTH-1:0] waddr_i, - input logic [CHUNK_WIDTH-1:0] wdata_i + input logic [ADDR_WIDTH-1:0] waddr_i, + input logic [SLICE_WIDTH-1:0] wdata_i ); logic [NUM_WORDS-1:0][WORD_WIDTH-1:0] register; always_comb begin for (int i = 0; i < NUM_READ_PORTS; i++) begin : gen_read_block - rdata_o[i] = (raddr_i[i] == 0) - ? '0 : register[raddr_i[i]][chunk_sel_i*CHUNK_WIDTH +: CHUNK_WIDTH]; + rdata_o[i] = (raddr_i[i] == '0) + ? '0 : register[raddr_i[i]][slice_sel_i*SLICE_WIDTH +: SLICE_WIDTH]; end : gen_read_block end @@ -50,7 +50,7 @@ module regfile #( register <= '0; end else if (wen_i && (waddr_i != '0)) begin /* verilog_lint: waive dff-name-style */ - register[waddr_i][chunk_sel_i*CHUNK_WIDTH +: CHUNK_WIDTH] <= wdata_i; + register[waddr_i][slice_sel_i*SLICE_WIDTH +: SLICE_WIDTH] <= wdata_i; end end -- cgit v1.2.3 From ef9254b3303a03ea4ab3c32aaf1d79df651e3b92 Mon Sep 17 00:00:00 2001 From: Warrick Lo Date: Wed, 17 Jun 2026 00:44:02 +0000 Subject: Move design parameters to config_pkg Signed-off-by: Warrick Lo --- rtl/config_pkg.sv | 17 +++++++++++++++++ rtl/montreal_pkg.sv | 8 ++++++++ rtl/regfile.sv | 22 ++++++++++++---------- 3 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 rtl/config_pkg.sv create mode 100644 rtl/montreal_pkg.sv (limited to 'rtl/regfile.sv') diff --git a/rtl/config_pkg.sv b/rtl/config_pkg.sv new file mode 100644 index 0000000..0120b14 --- /dev/null +++ b/rtl/config_pkg.sv @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: CERN-OHL-P-2.0 */ + +package config_pkg; + + /* Word width as defined in the RISC-V spec. */ + localparam int unsigned XLEN = 32; + + /* We use a byte-sliced datapath, inspired by the + * classic bit-sliced architecture of old CPUs. */ + localparam int unsigned SLICE_WIDTH = 8; + + /* The RV32E ISA defines 16 general-purpose registers. + * We have two read ports to allow for pipelined reads. */ + localparam int unsigned REG_ADDR_WIDTH = 4; + localparam int unsigned REG_NUM_READ_PORTS = 2; + +endpackage : config_pkg diff --git a/rtl/montreal_pkg.sv b/rtl/montreal_pkg.sv new file mode 100644 index 0000000..b3a13a0 --- /dev/null +++ b/rtl/montreal_pkg.sv @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: CERN-OHL-P-2.0 */ + +package montreal_pkg; + + typedef logic unsigned [config_pkg::XLEN-1:0] word_t; + typedef logic unsigned [config_pkg::SLICE_WIDTH-1:0] slice_t; + +endpackage : montreal_pkg diff --git a/rtl/regfile.sv b/rtl/regfile.sv index 8ca992c..e18301a 100644 --- a/rtl/regfile.sv +++ b/rtl/regfile.sv @@ -15,18 +15,20 @@ * read ports (default 2). Register 0 is fixed to 0 for all reads. */ -module regfile #( - parameter int unsigned WORD_WIDTH = 32, - parameter int unsigned ADDR_WIDTH = 4, - parameter int unsigned SLICE_WIDTH = 8, - parameter int unsigned NUM_READ_PORTS = 2, - - localparam int unsigned NUM_WORDS = 2 ** ADDR_WIDTH, - localparam int unsigned NUM_SLICES = WORD_WIDTH / SLICE_WIDTH +module regfile + import montreal_pkg::*; +#( + parameter int unsigned XLEN = config_pkg::XLEN, + parameter int unsigned SLICE_WIDTH = config_pkg::SLICE_WIDTH, + parameter int unsigned ADDR_WIDTH = config_pkg::REG_ADDR_WIDTH, + parameter int unsigned NUM_READ_PORTS = config_pkg::REG_NUM_READ_PORTS, + + localparam int unsigned NUM_WORDS = 2 ** ADDR_WIDTH, + localparam int unsigned SLICE_ADDR_WIDTH = $clog2(XLEN / SLICE_WIDTH) ) ( input logic clk_i, input logic rst_ni, - input logic [$clog2(NUM_SLICES)-1:0] slice_sel_i, + input logic [SLICE_ADDR_WIDTH-1:0] slice_sel_i, input logic [NUM_READ_PORTS-1:0][ADDR_WIDTH-1:0] raddr_i, output logic [NUM_READ_PORTS-1:0][SLICE_WIDTH-1:0] rdata_o, @@ -36,7 +38,7 @@ module regfile #( input logic [SLICE_WIDTH-1:0] wdata_i ); - logic [NUM_WORDS-1:0][WORD_WIDTH-1:0] register; + logic [NUM_WORDS-1:0][XLEN-1:0] register; always_comb begin for (int i = 0; i < NUM_READ_PORTS; i++) begin : gen_read_block -- cgit v1.2.3 From 2455fed25341b39d505bcdad9ae2b07c6cd42a73 Mon Sep 17 00:00:00 2001 From: Warrick Lo Date: Thu, 18 Jun 2026 09:39:41 -0700 Subject: Move typedefs to types.svh from montreal_pkg Yosys has poor support of packaged types. We will move typedefs to header files to prepare for formal verification with sby and the Tiny Tapeout flow later on, which uses yosys. Additionally, a debug port has been exposed to help verify the internal state of the regfile registers. Signed-off-by: Warrick Lo --- rtl/config_pkg.sv | 2 +- rtl/montreal_pkg.sv | 8 -------- rtl/regfile.sv | 21 +++++++++++++++++---- rtl/types.svh | 9 +++++++++ 4 files changed, 27 insertions(+), 13 deletions(-) delete mode 100644 rtl/montreal_pkg.sv create mode 100644 rtl/types.svh (limited to 'rtl/regfile.sv') diff --git a/rtl/config_pkg.sv b/rtl/config_pkg.sv index 0120b14..01d6c20 100644 --- a/rtl/config_pkg.sv +++ b/rtl/config_pkg.sv @@ -7,7 +7,7 @@ package config_pkg; /* We use a byte-sliced datapath, inspired by the * classic bit-sliced architecture of old CPUs. */ - localparam int unsigned SLICE_WIDTH = 8; + localparam int unsigned SLICE_WIDTH = 8; /* The RV32E ISA defines 16 general-purpose registers. * We have two read ports to allow for pipelined reads. */ diff --git a/rtl/montreal_pkg.sv b/rtl/montreal_pkg.sv deleted file mode 100644 index b3a13a0..0000000 --- a/rtl/montreal_pkg.sv +++ /dev/null @@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: CERN-OHL-P-2.0 */ - -package montreal_pkg; - - typedef logic unsigned [config_pkg::XLEN-1:0] word_t; - typedef logic unsigned [config_pkg::SLICE_WIDTH-1:0] slice_t; - -endpackage : montreal_pkg diff --git a/rtl/regfile.sv b/rtl/regfile.sv index e18301a..66af045 100644 --- a/rtl/regfile.sv +++ b/rtl/regfile.sv @@ -15,9 +15,9 @@ * read ports (default 2). Register 0 is fixed to 0 for all reads. */ -module regfile - import montreal_pkg::*; -#( +`include "types.svh" + +module regfile #( parameter int unsigned XLEN = config_pkg::XLEN, parameter int unsigned SLICE_WIDTH = config_pkg::SLICE_WIDTH, parameter int unsigned ADDR_WIDTH = config_pkg::REG_ADDR_WIDTH, @@ -26,6 +26,14 @@ module regfile localparam int unsigned NUM_WORDS = 2 ** ADDR_WIDTH, localparam int unsigned SLICE_ADDR_WIDTH = $clog2(XLEN / SLICE_WIDTH) ) ( +/* Expose the internal register state for formal verification. + * Yosys/SBY cannot reliably reference hierarchical signals after + * elaboration and optimisation. */ +`ifdef FORMAL + /* verilog_lint: waive port-name-suffix */ + output word_bank_t register_dbg, +`endif + input logic clk_i, input logic rst_ni, input logic [SLICE_ADDR_WIDTH-1:0] slice_sel_i, @@ -38,7 +46,12 @@ module regfile input logic [SLICE_WIDTH-1:0] wdata_i ); - logic [NUM_WORDS-1:0][XLEN-1:0] register; + word_bank_t register; + +/* Debug signal for formal verification. See above. */ +`ifdef FORMAL + assign register_dbg = register; +`endif always_comb begin for (int i = 0; i < NUM_READ_PORTS; i++) begin : gen_read_block diff --git a/rtl/types.svh b/rtl/types.svh new file mode 100644 index 0000000..ca8a675 --- /dev/null +++ b/rtl/types.svh @@ -0,0 +1,9 @@ +`ifndef TYPES_SVH +`define TYPES_SVH + +typedef logic [config_pkg::XLEN-1:0] word_t; +typedef logic [2 ** config_pkg::REG_ADDR_WIDTH - 1:0][config_pkg::XLEN-1:0] word_bank_t; + +typedef logic [config_pkg::SLICE_WIDTH-1:0] slice_t; + +`endif /* TYPES_SVH */ -- cgit v1.2.3