rv32g-core

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

commit 882db63ddf63461fedb7bbfc77c3b0f385a858bc
parent 95b479231c2f5959608a338830ef10baa65446f7
Author: Vineet Kumar <git@vineetk.net>
Date:   Sun,  7 Jun 2026 17:56:11 -0400

add very basic testbench

Diffstat:
MMakefile | 12+++++++++++-
Mmanifest.scm | 8++++++--
Arom.txt | 2++
Mrtl/rv32g_hart.sv | 1+
Artl/tb_rv32g.sv | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
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