commit 882db63ddf63461fedb7bbfc77c3b0f385a858bc
parent 95b479231c2f5959608a338830ef10baa65446f7
Author: Vineet Kumar <git@vineetk.net>
Date: Sun, 7 Jun 2026 17:56:11 -0400
add very basic testbench
Diffstat:
5 files changed, 71 insertions(+), 3 deletions(-)
diff --git a/Makefile b/Makefile
@@ -2,6 +2,7 @@ SRCDIR := rtl
OBJDIR := obj_dir
PKG_SRC := ${SRCDIR}/rv32g_pkg.sv
+TB_SRC := ${SRCDIR}/tb_rv32g.sv
SV_SRCS := ${SRCDIR}/rv32g_hart.sv ${wildcard ${SRCDIR}/stage_*.sv}
all: lint synth
@@ -9,10 +10,19 @@ all: lint synth
lint: ${PKG_SRC} ${SV_SRCS}
verilator --lint-only --timing \
+1800-2023ext+.sv \
- ${PKG_SRC} ${SV_SRCS}
+ --top tb_rv32g \
+ ${PKG_SRC} ${TB_SRC} ${SV_SRCS}
synth:
yosys -m slang -p 'read_slang ${PKG_SRC} ${SV_SRCS}; synth_gowin -top rv32g_hart'
+sim: lint ${PKG_SRC} ${TB_SRC} ${SV_SRCS}
+ verilator --binary --exe --build --timing \
+ --top tb_rv32g \
+ -j 0 -o Vtb_rv32g \
+ --trace-fst \
+ ${PKG_SRC} ${TB_SRC} ${SV_SRCS}
+ ./${OBJDIR}/Vtb_rv32g
+
clean:
rm -rf ${OBJDIR}
diff --git a/manifest.scm b/manifest.scm
@@ -1,6 +1,10 @@
(use-modules (gnu packages base)
- (gnu packages electronics))
+ (gnu packages commencement)
+ (gnu packages electronics)
+ (gnu packages python))
-(packages->manifest (list gnu-make
+(packages->manifest (list gcc-toolchain
+ gnu-make
+ python
verilator
yosys))
diff --git a/rom.txt b/rom.txt
@@ -0,0 +1,2 @@
+00000001
+00000002
diff --git a/rtl/rv32g_hart.sv b/rtl/rv32g_hart.sv
@@ -39,6 +39,7 @@ module rv32g_hart
stage_fetch u_fetch(.pc, .imem_addr, .imem_data, .inst);
always_ff @(posedge clk or negedge rstN) begin
+ $display("PC: %h, Next PC: %h, rstN: %d, imem_valid: %d, imem_data: %h", pc, next_pc, rstN, imem_valid, imem_data);
if (!rstN) pc <= '0;
else if (imem_valid) pc <= next_pc;
else begin
diff --git a/rtl/tb_rv32g.sv b/rtl/tb_rv32g.sv
@@ -0,0 +1,51 @@
+timeunit 1ns; timeprecision 1ps;
+
+module tb_rv32g
+ ();
+
+ logic clk;
+ logic rstN;
+
+ logic [31:0] imem [0:255];
+ logic [31:0] imem_addr;
+ logic [31:0] imem_data;
+ logic imem_valid;
+
+ logic [31:0] dmem [0:1023];
+ logic [31:0] dmem_addr;
+ logic [31:0] dmem_data;
+ logic dmem_valid;
+ logic [31:0] dmem_wdata;
+ logic dmem_we;
+ logic [3:0] dmem_be;
+
+ // 100 MHz clock generation
+ // T = 1/f/2 = 1/(100*10^6)/2 = 1e-8/2 = 5ns
+ initial forever #5ns clk = ~clk;
+
+ initial begin
+ $display("Reading rom.txt");
+ $readmemh("rom.txt", imem);
+
+ rstN = 0;
+ imem_addr = 0;
+ dmem_addr = 0;
+ imem_valid = 1;
+ dmem_valid = 1;
+
+ #5 rstN = 1;
+ $display("Reset now deactivated");
+ end
+
+ assign imem_data = imem[imem_addr >> 2];
+ assign dmem_data = dmem[dmem_addr];
+ assign imem_valid = (imem_data !== 32'h00000000 && imem_data !== 32'hffffffff) ? 1 : 0;
+
+ rv32g_hart dut(.clk, .rstN,
+ .imem_addr, .imem_data, .imem_valid,
+ .dmem_addr, .dmem_data, .dmem_valid,
+ .dmem_wdata, .dmem_we, .dmem_be);
+
+ always if (!imem_valid) $finish();
+
+endmodule