rv32g-core

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

commit 1384860501c9f2aa08e81a6a7754614107877ac8
parent 6e3e57beecc47d358c5706f7eef0efc2ee64ea3d
Author: Vineet Kumar <git@vineetk.net>
Date:   Tue,  9 Jun 2026 18:44:22 -0400

implement better testing infrastructure

Diffstat:
M.gitignore | 1+
A.gitmodules | 3+++
MMakefile | 87+++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------
Drom.txt | 287-------------------------------------------------------------------------------
Mrtl/tb_rv32g.sv | 7+++++--
Atests/elf2hex | 12++++++++++++
Atests/riscv-tests | 1+
7 files changed, 85 insertions(+), 313 deletions(-)

diff --git a/.gitignore b/.gitignore @@ -1,2 +1,3 @@ #* obj_dir +tests/.test_list diff --git a/.gitmodules b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "tests/riscv-tests"] + path = tests/riscv-tests + url = https://github.com/riscv-software-src/riscv-tests/ diff --git a/Makefile b/Makefile @@ -1,44 +1,83 @@ 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} ${SRCDIR}/unified_memory.sv +PKG_SRC := ${SRCDIR}/rv32g_pkg.sv +TB_SRC := ${SRCDIR}/tb_rv32g.sv +SV_SRCS := ${SRCDIR}/rv32g_hart.sv ${wildcard ${SRCDIR}/stage_*.sv} ${SRCDIR}/unified_memory.sv + +# tests +TEST_DIR := tests/riscv-tests/isa +SIM := $(OBJDIR)/Vtb_rv32g +ELF2HEX := tests/elf2hex +LOG_DIR := $(TEST_DIR)/logs +TEST_LIST := $(TEST_DIR)/test_list + +# main +.PHONY: all lint synth sim_compile sim tests clean clean-tests all: lint synth -lint: ${PKG_SRC} ${SV_SRCS} +lint: $(PKG_SRC) $(SV_SRCS) verilator --lint-only --timing \ +1800-2023ext+.sv \ --top tb_rv32g \ - ${PKG_SRC} ${TB_SRC} ${SV_SRCS} + $(PKG_SRC) $(TB_SRC) $(SV_SRCS) synth: - yosys -m slang -p 'read_slang ${PKG_SRC} ${SV_SRCS}; synth_gowin -top rv32g_hart' + yosys -m slang -p 'read_slang $(PKG_SRC) $(SV_SRCS); synth_gowin -top rv32g_hart' -sim_compile: lint ${PKG_SRC} ${TB_SRC} ${SV_SRCS} +sim_compile: 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} + $(PKG_SRC) $(TB_SRC) $(SV_SRCS) sim: sim_compile - ./${OBJDIR}/Vtb_rv32g - -tests: sim_compile - cd tests/isa && \ - make XLEN=32 && \ - rm -f *.dump && \ - for i in rv32ui-*; do \ - riscv32-unknown-elf-objcopy -O binary $$i file.bin; \ - hexdump -v -e '1/4 "%08x\n"' file.bin >$$i.hex; \ - rm file.bin; \ - done && \ - for i in rv32ui-*.hex; do \ - echo $$i; \ - ../../${OBJDIR}/Vtb_rv32g $$i; \ - done + ./$(SIM) + +# tests +$(TEST_DIR)/%.hex: $(TEST_DIR)/% | $(TEST_LIST) + find ${TEST_DIR} -type f -executable -exec $(ELF2HEX) {} \; + +$(TEST_DIR)/%.pass: $(TEST_DIR)/%.hex sim_compile + @mkdir -p $(LOG_DIR) + @printf "%20s: " $(basename $(notdir $<)) + @pass=$$(readelf -s $(basename $<) | awk '/pass$$/ {print $$2}'); \ + fail=$$(readelf -s $(basename $<) | awk '/fail$$/ {print $$2}'); \ + $(SIM) +rom=$< > $(LOG_DIR)/$*.log; \ + if grep -q "^IF: pc: $$fail" $(LOG_DIR)/$*.log; then \ + echo "fail"; \ + elif grep -q "^IF: pc: $$pass" $(LOG_DIR)/$*.log; then \ + echo "pass"; \ + else \ + echo "ERROR (neither pass nor fail address reached)"; \ + exit 1; \ + fi + @touch $@ + +$(TEST_LIST): + @cd $(TEST_DIR) && \ + $(MAKE) -k XLEN=32 || true && \ + $(RM) *.dump && \ + names=$$(for f in rv32ui-*; do \ + [ -f "$$f" ] && [ ! "$$f" = "*.dump" ] && echo "$${f}"; \ + done | tr '\n' ' ') && \ + echo "TEST_NAMES := $$names" > $(notdir $@) + +-include $(TEST_LIST) +TEST_TARGETS := $(addprefix $(TEST_DIR)/,$(addsuffix .pass,$(TEST_NAMES))) + +# build and run all tests +.PHONY: tests +tests: $(TEST_LIST) $(TEST_TARGETS) + @echo ${TEST_LIST} + @echo "All tests ran." + +# clean +clean-tests: + $(RM) $(TEST_DIR)/*.hex $(TEST_DIR)/*.pass $(TEST_DIR)/*.log $(TEST_LIST) clean: - rm -rf ${OBJDIR} + rm -rf $(OBJDIR) + $(MAKE) clean-tests diff --git a/rom.txt b/rom.txt @@ -1,287 +0,0 @@ -0500006f -34202f73 -00800f93 -03ff0863 -00900f93 -03ff0463 -00b00f93 -03ff0063 -00000f13 -000f0463 -000f0067 -34202f73 -000f5463 -0040006f -5391e193 -00001f17 -fc3f2223 -00001f17 -fc0f2023 -ff1ff06f -00000093 -00000113 -00000193 -00000213 -00000293 -00000313 -00000393 -00000413 -00000493 -00000513 -00000593 -00000613 -00000693 -00000713 -00000793 -00000813 -00000893 -00000913 -00000993 -00000a13 -00000a93 -00000b13 -00000b93 -00000c13 -00000c93 -00000d13 -00000d93 -00000e13 -00000e93 -00000f13 -00000f93 -f1402573 -00051063 -00000297 -01028293 -30529073 -74445073 -00000297 -01028293 -30529073 -18005073 -00000297 -02028293 -30529073 -800002b7 -fff28293 -3b029073 -01f00293 -3a029073 -30405073 -00000297 -01428293 -30529073 -30205073 -30305073 -00000193 -00000297 -ed428293 -30529073 -00100513 -01f51513 -00054c63 -0ff0000f -00100193 -05d00893 -00000513 -00000073 -00000293 -00028a63 -10529073 -0000b2b7 -10928293 -30229073 -30005073 -00000297 -01428293 -34129073 -f1402573 -30200073 -00200193 -00000693 -00068713 -00000393 -26771c63 -00300193 -00100693 -00168713 -00200393 -26771263 -00400193 -00300693 -00768713 -00a00393 -24771863 -00500193 -00000693 -80068713 -80000393 -22771e63 -00600193 -800006b7 -00068713 -800003b7 -22771463 -00700193 -800006b7 -80068713 -800003b7 -80038393 -20771863 -00800193 -00000693 -7ff68713 -7ff00393 -1e771e63 -00900193 -800006b7 -fff68693 -00068713 -800003b7 -fff38393 -1e771063 -00a00193 -800006b7 -fff68693 -7ff68713 -800003b7 -7fe38393 -1c771263 -00b00193 -800006b7 -7ff68713 -800003b7 -7ff38393 -1a771663 -00c00193 -800006b7 -fff68693 -80068713 -7ffff3b7 -7ff38393 -18771863 -00d00193 -00000693 -fff68713 -fff00393 -16771e63 -00e00193 -fff00693 -00168713 -00000393 -16771463 -00f00193 -fff00693 -fff68713 -ffe00393 -14771a63 -01000193 -800006b7 -fff68693 -00168713 -800003b7 -12771e63 -01100193 -00d00593 -00b58593 -01800393 -12759463 -01200193 -00000213 -00d00093 -00b08713 -00070313 -00120213 -00200293 -fe5216e3 -01800393 -10731063 -01300193 -00000213 -00d00093 -00a08713 -00000013 -00070313 -00120213 -00200293 -fe5214e3 -01700393 -0c731a63 -01400193 -00000213 -00d00093 -00908713 -00000013 -00000013 -00070313 -00120213 -00200293 -fe5212e3 -01600393 -0a731263 -01500193 -00000213 -00d00093 -00b08713 -00120213 -00200293 -fe5218e3 -01800393 -08771063 -01600193 -00000213 -00d00093 -00000013 -00a08713 -00120213 -00200293 -fe5216e3 -01700393 -04771c63 -01700193 -00000213 -00d00093 -00000013 -00000013 -00908713 -00120213 -00200293 -fe5214e3 -01600393 -02771663 -01800193 -02000093 -02000393 -00709e63 -01900193 -02100093 -03208013 -00000393 -00701463 -02301063 -0ff0000f -00018063 -00119193 -0011e193 -05d00893 -00018513 -00000073 -0ff0000f -00100193 -05d00893 -00000513 -00000073 -c0001073 -00000013 -00000013 -00000013 -00000013 -00000013 -00000013 -00000013 -00000013 -00000013 -00000013 -00000013 -00000013 -00000013 diff --git a/rtl/tb_rv32g.sv b/rtl/tb_rv32g.sv @@ -23,6 +23,8 @@ module tb_rv32g exception_t exception; + string rom_filename; + // debug stuff int cycle_cnt = 0; @@ -34,8 +36,9 @@ module tb_rv32g end initial begin - $display("Reading rom.txt"); - $readmemh("rom.txt", u_mem.mem); + if (!$value$plusargs("rom=%s", rom_filename)) rom_filename = "rom.txt"; + $display("Reading rom from %s", rom_filename); + $readmemh(rom_filename, u_mem.mem); rstN = 0; imem_addr = 0; diff --git a/tests/elf2hex b/tests/elf2hex @@ -0,0 +1,12 @@ +#!/bin/sh +riscv32-unknown-elf-objcopy -O verilog --verilog-data-width=4 "${1}" file.bin; +awk ' + /^@/ { + base = 0x20000000 + addr = strtonum("0x" substr($0,2)) + idx = addr - base + printf "@%X\n", idx + next + } + { gsub(/ /, "\n"); print }' file.bin >"${1}".hex +rm file.bin diff --git a/tests/riscv-tests b/tests/riscv-tests @@ -0,0 +1 @@ +Subproject commit 34e6b6d1e7936b526075432fb730d89148623484