
Yarvi项目也是一个verilog的RISC-V项目使用Makefile以方便快速体验。如下是本次一键式体验记录。chipcampchipcamp:~/src/riscv$ git clone https://gitcode.com/chipcamp/yarvi.gitCloning into yarvi...remote: Enumerating objects: 3273, done.remote: Total 3273 (delta 0), reused 0 (delta 0), pack-reused 3273 (from 1)Receiving objects: 100% (3273/3273), 2.82 MiB | 486.00 KiB/s, done.Resolving deltas: 100% (2614/2614), done.chipcampchipcamp:~/src/riscv$ cd yarvichipcampchipcamp:~/src/riscv/yarvi$ ls -ltotal 32drwxrwxr-x 2 chipcamp chipcamp 4096 Oct 7 14:15 comments-rw-rw-r-- 1 chipcamp chipcamp 775 Oct 7 14:15 COPYINGdrwxrwxr-x 2 chipcamp chipcamp 4096 Oct 7 14:15 doc-rw-rw-r-- 1 chipcamp chipcamp 435 Oct 7 14:15 Makefile-rw-rw-r-- 1 chipcamp chipcamp 3583 Oct 7 14:15 README.mddrwxrwxr-x 2 chipcamp chipcamp 4096 Oct 7 14:15 rtldrwxrwxr-x 8 chipcamp chipcamp 4096 Oct 7 14:15 swdrwxrwxr-x 9 chipcamp chipcamp 4096 Oct 7 14:15 targetchipcampchipcamp:~/src/riscv/yarvi$ cat Makefile# Remove fmax and the grepall: comply test ipc# grep MHz target/OrangeCrab/nextpnr-ecp5.out|tail -1alu_bench:$(MAKE) -s -C rtl# Its my experience that compliance tests catches many bugs that rv32-tests doesntcomply:$(MAKE) -s -C sw/rv32-compliancetest:$(MAKE) -s -C sw/rv32-testsecho Expect 46 passingipc:# $(MAKE) -s -C sw/dhrystone$(MAKE) -s -C target/verisimfmax:-$(MAKE) -C target/OrangeCrab sweepchipcampchipcamp:~/src/riscv/yarvi$ makemake -s -C sw/rv32-complianceI-ADD-01 PASSEDI-ADDI-01 PASSEDI-AND-01 PASSEDI-ANDI-01 PASSEDI-AUIPC-01 PASSEDI-BEQ-01 PASSEDI-BGE-01 PASSEDI-BGEU-01 PASSEDI-BLT-01 PASSEDI-BLTU-01 PASSEDI-BNE-01 PASSEDI-CSRRC-01 PASSEDI-CSRRCI-01 PASSEDI-CSRRS-01 PASSEDI-CSRRSI-01 PASSEDI-CSRRW-01 PASSEDI-CSRRWI-01 PASSEDI-DELAY_SLOTS-01 PASSEDI-EBREAK-01 PASSEDI-ECALL-01 PASSEDI-ENDIANESS-01 PASSEDI-FENCE.I-01 PASSEDI-IO PASSEDI-JAL-01 PASSEDI-JALR-01 PASSEDI-LB-01 PASSEDI-LBU-01 PASSEDI-LH-01 PASSEDI-LHU-01 PASSEDI-LUI-01 PASSEDI-LW-01 PASSEDI-MISALIGN_JMP-01 PASSEDI-MISALIGN_LDST-01 PASSEDI-NOP-01 PASSEDI-OR-01 PASSEDI-ORI-01 PASSEDI-RF_size-01 PASSEDI-RF_width-01 PASSEDI-RF_x0-01 PASSEDI-SB-01 PASSEDI-SH-01 PASSEDI-SLL-01 PASSEDI-SLLI-01 PASSEDI-SLT-01 PASSEDI-SLTI-01 PASSEDI-SLTIU-01 PASSEDI-SLTU-01 PASSEDI-SRA-01 PASSEDI-SRAI-01 PASSEDI-SRL-01 PASSEDI-SRLI-01 PASSEDI-SUB-01 PASSEDI-SW-01 PASSEDI-XOR-01 PASSEDI-XORI-01 PASSEDmake -s -C sw/rv32-testsrv32ui-p-add PASSEDrv32ui-p-addi PASSEDrv32ui-p-and PASSEDrv32ui-p-andi PASSEDrv32ui-p-auipc PASSEDrv32ui-p-beq PASSEDrv32ui-p-bge PASSEDrv32ui-p-bgeu PASSEDrv32ui-p-blt PASSEDrv32ui-p-bltu PASSEDrv32ui-p-bne PASSEDrv32ui-p-fence_i PASSEDrv32ui-p-jal PASSEDrv32ui-p-jalr PASSEDrv32ui-p-lb PASSEDrv32ui-p-lbu PASSEDrv32ui-p-lh PASSEDrv32ui-p-lhu PASSEDrv32ui-p-lui PASSEDrv32ui-p-lw PASSEDrv32ui-p-or PASSEDrv32ui-p-ori PASSEDrv32ui-p-sb PASSEDrv32ui-p-sh PASSEDrv32ui-p-simple PASSEDrv32ui-p-sll PASSEDrv32ui-p-slli PASSEDrv32ui-p-slt PASSEDrv32ui-p-slti PASSEDrv32ui-p-sltiu PASSEDrv32ui-p-sltu PASSEDrv32ui-p-sra PASSEDrv32ui-p-srai PASSEDrv32ui-p-srl PASSEDrv32ui-p-srli PASSEDrv32ui-p-sub PASSEDrv32ui-p-sw PASSEDrv32ui-p-xor PASSEDrv32ui-p-xori PASSEDrv32ui-v-add FAILEDrv32ui-v-addi FAILEDrv32ui-v-and FAILEDrv32ui-v-andi FAILEDrv32ui-v-auipc FAILEDrv32ui-v-beq FAILEDrv32ui-v-bge FAILEDrv32ui-v-bgeu FAILEDrv32ui-v-blt FAILEDrv32ui-v-bltu FAILEDrv32ui-v-bne FAILEDrv32ui-v-fence_i FAILEDrv32ui-v-jal FAILEDrv32ui-v-jalr FAILEDrv32ui-v-lb FAILEDrv32ui-v-lbu FAILEDrv32ui-v-lh FAILEDrv32ui-v-lhu FAILEDrv32ui-v-lui FAILEDrv32ui-v-lw FAILEDrv32ui-v-or FAILEDrv32ui-v-ori FAILEDrv32ui-v-sb FAILEDrv32ui-v-sh FAILEDrv32ui-v-simple FAILEDrv32ui-v-sll FAILEDrv32ui-v-slli FAILEDrv32ui-v-slt FAILEDrv32ui-v-slti FAILEDrv32ui-v-sltiu FAILEDrv32ui-v-sltu FAILEDrv32ui-v-sra FAILEDrv32ui-v-srai FAILEDrv32ui-v-srl FAILEDrv32ui-v-srli FAILEDrv32ui-v-sub FAILEDrv32ui-v-sw FAILEDrv32ui-v-xor FAILEDrv32ui-v-xori FAILEDrv32mi-p-breakpoint PASSEDrv32mi-p-csr PASSEDrv32mi-p-illegal FAILEDrv32mi-p-ma_addr PASSEDrv32mi-p-ma_fetch PASSEDrv32mi-p-mcsr FAILEDrv32mi-p-sbreak PASSEDrv32mi-p-scall PASSEDrv32si-p-csr FAILEDrv32si-p-dirty FAILEDrv32si-p-ma_fetch FAILEDrv32si-p-sbreak FAILEDrv32si-p-scall FAILEDrv32si-p-wfi PASSEDrv32um-p-div FAILEDrv32um-p-divu FAILEDrv32um-p-mul FAILEDrv32um-p-mulh FAILEDrv32um-p-mulhsu FAILEDrv32um-p-mulhu FAILEDrv32um-p-rem FAILEDrv32um-p-remu FAILEDrv32um-v-div FAILEDrv32um-v-divu FAILEDrv32um-v-mul FAILEDrv32um-v-mulh FAILEDrv32um-v-mulhsu FAILEDrv32um-v-mulhu FAILEDrv32um-v-rem FAILEDrv32um-v-remu FAILEDTotal: 108Passing: 46Failing: 62Expect 46 passingmake -s -C target/verisim%Error:../../rtl/yarvi.v:809:4: Unknown verilator lint message code: UNUSEDSIGNAL, in /*verilator lint_off UNUSEDSIGNAL*/809 | /*verilator lint_off UNUSEDSIGNAL*/| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%Error:../../rtl/yarvi.v:822:4: Unknown verilator lint message code:UNUSEDSIGNAL, in /*verilator lint_on UNUSEDSIGNAL*/822 | /*verilator lint_on UNUSEDSIGNAL*/| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~%Error: Exiting due to 2 error(s)make[1]: *** [Makefile:17: obj_dir/Vyarvi] Error 1make: *** [Makefile:19: ipc] Error 2chipcampchipcamp:~/src/riscv/yarvi$----make的前两步骤都OK分别对应于sw/rv32-compliance/Makefile和sw/rv32-tests/Makefile。它们的内容如下所示(部分内容作了删减以便于阅读)。----make的第三个步骤不OK显然这是在Ubuntu22 LTS版本下的verilator的apt包版本低所引起的在Ubuntu24.04 LTS版本下实测则没有该问题。----下面则把三个步骤下的Makefile分别看以下。第一个Makefile----yarvi/sw/rv32-compliance/Makefile允许使用iverilog或verilator进行仿真。----在%.icarus的编译中使用了iverilog -o $ $(ICARUS_SRC) $(SRC)其中的$就是各种.icarus文件或vvp脚本文件有多个而$(SRC)则是rtl目录下的多个.v文件$(ICARUS_SRC)则是target/sim/toplevel.v文件即作为顶层模块的testbench文件。----yarvi/sw/rv32-compliance/Makefile还还还使用了spike所生成的.ref文件(trace文件)这是在%.comply的构建目标中列出的使用diff命令来比较RTL的结果和spike的Trace文件.ref。chipcampchipcamp:~/src/riscv/yarvi$ cat sw/rv32-compliance/MakefileCORE../../rtl/include $(CORE)/Makefile.common# ChipCamp: patsubst is an inline command in Make.ICARUS_SRC../../target/sim/toplevel.vSRC$(patsubst %,$(CORE)/%,$(YARVISRC))HDR$(patsubst %,$(CORE)/%,$(YARVIHDR))CONFIG$(YARVICONFIG) -DSIMULATION -DQUIET -DDISASSEMBLE -DINIT_MEM\$\# Pick your favorite simulator, Icarus Verilog (icarus) or Verilator (verilator)SIMicarus#SIMverilator not quite ready yet.PRECIOUS: %.hex %.0.hex %.1.hex %.2.hex %.3.hex %.$(SIM)TESTS \I-ADD-01.elf \I-ADDI-01.elf \I-AND-01.elf \I-ANDI-01.elf \I-BEQ-01.elf \I-XOR-01.elf \I-XORI-01.elfcompliance:$(patsubst %.elf,%.comply,$(TESTS))newtest:$(patsubst %,$(TESTDIR)%.trace,$(TESTS))printf Total: %3d\n $$(echo $(TESTS) | wc -w)printf Passing: %3d\n $$(ls $(patsubst %,$(TESTDIR)%.trace.pass,$(TESTS)) 2 /dev/null| wc -l)printf Failing: %3d\n $$(ls $(patsubst %,$(TESTDIR)%.trace.fail,$(TESTS)) 2 /dev/null| wc -l)%.spike:%spike $ $ 21%.icarus:%.hex %.0.hex %.1.hex %.2.hex %.3.hex $(ICARUS_SRC) $(SRC) $(HDR)$(QUIET)iverilog\-DBEGIN_SIGNATUREnm $(basename $).elf|egrep begin_signature$$|cut -d -f1 \-DEND_SIGNATUREnm $(basename $).elf|egrep end_signature$$|cut -d -f1 \-DTOHOSTnm $(basename $).elf|egrep tohost$$|cut -d -f1 \-I$(CORE)/ $(CONFIG) \-o $$(ICARUS_SRC) $(SRC)%.verilator:%.hex %.0.hex %.1.hex %.2.hex %.3.hex $(SRC) $(HDR) sim_main.cpp$(QUIET)verilator -CFLAGS -O3 -O3 -Wall --cc --exe sim_main.cpp \--top-module yarvi \-DBEGIN_SIGNATUREnm $(basename $).elf|egrep begin_signature$$|cut -d -f1 \-DEND_SIGNATUREnm $(basename $).elf|egrep end_signature$$|cut -d -f1 \-DTOHOSTnm $(basename $).elf|egrep tohost$$|cut -d -f1 \$(UNDEFS) \-I$(CORE)/ $(CONFIG) \-Mdir $ $(SRC)make -C $ -f Vyarvi.mk Vyarvi%.trace:%.$(SIM)$(QUIET)./$^ \INIT0$(basename $).0.hex \INIT1$(basename $).1.hex \INIT2$(basename $).2.hex \INIT3$(basename $).3.hex \ $$(QUIET)if grep -q TOHOST 00000001 $;then \touch $.pass; else ln -fs $ $.fail; fi%.run:%.verilator$/Vyarvi \INIT0$(basename $).0.hex \INIT1$(basename $).1.hex \INIT2$(basename $).2.hex \INIT3$(basename $).3.hex%.run:%.icarus./$^ \INIT0$(basename $).0.hex \INIT1$(basename $).1.hex \INIT2$(basename $).2.hex \INIT3$(basename $).3.hex%.comply:%.$(SIM)$(QUIET)./$^ \INIT0$(basename $).0.hex \INIT1$(basename $).1.hex \INIT2$(basename $).2.hex \INIT3$(basename $).3.hex \| tee $(basename $).catch | \grep ^Signature -A999999|egrep ^[0-9a-f]$$ | \ifdiff-$(basename $).ref;then \printf %-20s PASSED\n $(basename $); touch $.pass; \else\printf %-20s FAILED\n $(basename $); ln -fs $ $.fail; fi# ######## Begin: Add by ChipCamp 20251226clean:rm -f *.icarus *.pass *.fail *.catch *.vcd *.0.hex *.1.hex *.2.hex *.3.hexdeepclean:rm -f *.icarus *.pass *.fail *.catch *.vcd *.hex *.dis *.bin----每一个测试用例(如I-ADD)都生成了一个vpp文件(*.icarus)以及相应的spike对照参考文件(*.ref)以及RTL运行所需要的四个hex文件(*.hex)以及comply结果文件(使用diff对RTL仿真结果和spike的ref文件比对的结果)。第二个Makefile如下。----yarvi/sw/rv32-tests/Makefile允许使用iverilog或verilator进行仿真。----yarvi/sw/rv32-tests/Makefile和上面的相比似乎没有和spike所生成的.ref文件(trace文件)进行比对----yarvi/sw/rv32-tests/Makefile测试套中包含了UIP、UIV、MI、SI、UM等不同的扩展。其中还有一个fence.i的扩展该扩展不在常见的risca ISA手册中而在扩展的手册中(tbd)。chipcampchipcamp:~/src/riscv/yarvi$ cat sw/rv32-tests/MakefileCORE../../rtlinclude $(CORE)/Makefile.commonTIMEOUT16000SRC../../target/sim/toplevel.v $(patsubst %,$(CORE)/%,$(YARVISRC))HDR$(patsubst %,$(CORE)/%,$(YARVIHDR))CONFIG$(YARVICONFIG) -DSIMULATION -DDISASSEMBLE.PRECIOUS: %.hex %.0.hex %.1.hex %.2.hex %.3.hex %.binall:newtestTESTSET_UIP \rv32ui-p-add \rv32ui-p-addi \rv32ui-p-and \rv32ui-p-andi \rv32ui-p-auipc \rv32ui-p-fence_i\rv32ui-p-jal \rv32ui-p-jalr \rv32ui-p-lb \rv32ui-p-sw \rv32ui-p-xor \rv32ui-p-xoriTESTSET_UIV\rv32ui-v-add \rv32ui-v-addi \rv32ui-v-and \rv32ui-v-andi \rv32ui-v-auipc \rv32ui-v-fence_i\rv32ui-v-jal \rv32ui-v-jalr \rv32ui-v-xoriTESTSET_MI \rv32mi-p-breakpoint \rv32mi-p-csr \rv32mi-p-illegal \rv32mi-p-ma_addr \rv32mi-p-ma_fetch \rv32mi-p-mcsr \rv32mi-p-sbreak \rv32mi-p-scallTESTSET_SI \rv32si-p-csr \rv32si-p-dirty \rv32si-p-ma_fetch \rv32si-p-sbreak \rv32si-p-scall \rv32si-p-wfiTESTSET_UM \rv32um-p-div \rv32um-p-divu \rv32um-p-mul \rv32um-p-mulh \rv32um-p-mulhsu \rv32um-p-mulhu \rv32um-p-rem \rv32um-p-remu \rv32um-v-div \rv32um-v-divu \rv32um-v-mul \rv32um-v-mulh \rv32um-v-mulhsu \rv32um-v-mulhu \rv32um-v-rem \rv32um-v-remuTESTSET_ALL$(TESTSET_UIP) $(TESTSET_UIV) $(TESTSET_MI) $(TESTSET_SI) $(TESTSET_UA) $(TESTSET_UC) $(TESTSET_UD) $(TESTSET_UF) $(TESTSET_UM)TESTS$(TESTSET_UIP)TESTS$(TESTSET_ALL)newtest:$(patsubst %,$(TESTDIR)%.trace,$(TESTS))printf Total: %3d\n $$(echo $(TESTS) | wc -w)printf Passing: %3d\n $$(ls $(patsubst %,$(TESTDIR)%.trace.pass,$(TESTS)) 2 /dev/null| wc -l)printf Failing: %3d\n $$(ls $(patsubst %,$(TESTDIR)%.trace.fail,$(TESTS)) 2 /dev/null| wc -l)multisim:$(patsubst %,$(TESTDIR)%.multisim,$(TESTS))%.multisim: %multisim -c $%.spike: %spike $ $ 21yarvi.sim: $(SRC) $(HDR)$(QUIET)iverilog-I$(CORE) $(CONFIG) -DTOHOST80001000 -o $$(SRC)%.trace:%.0.hex%.1.hex%.2.hex%.3.hexyarvi.sim$(QUIET)./yarvi.sim \INIT0$(basename $).0.hex \INIT1$(basename $).1.hex \INIT2$(basename $).2.hex \INIT3$(basename $).3.hex \ $$(QUIET)if grep -q TOHOST 1 $;then \printf %-20s PASSED\n $(basename $); touch $.pass; \else\printf %-20s FAILED\n $(basename $); ln -fs $ $.fail; fi%.run:%.0.hex %.1.hex%.2.hex %.3.hex yarvi.sim./yarvi.sim \INIT0$(basename $).0.hex \INIT1$(basename $).1.hex \INIT2$(basename $).2.hex \INIT3$(basename $).3.hexclean:rm -f *.icarus *.pass *.fail *.catch *.vcd *.trace *.0.hex *.1.hex *.2.hex *.3.hex yarvi.simdeepclean:rm -f *.icarus *.pass *.fail *.catch *.vcd *.trace *.dis yarvi.sim *.hex *.dis *.bin# make rv32ui-p-add.run# make rv32ui-v-add.run# make rv32ui-p-add.dis# make rv32ui-v-add.dischipcampchipcamp:~/src/riscv/yarvi$第三个Makefile如下。----明确使用verilator进行仿真因为仿真运行负载大必须要用更快的仿真那就必须是Verilator。chipcampchipcamp:~/src/riscv/yarvi$ cat target/verisim/MakefileCORE../../rtlinclude $(CORE)/Makefile.commonSRC ../../rtl/yarvi.v \../../rtl/yarvi_disass.v \../../rtl/alu.v \../../rtl/yarvi_dec_reg_usage.v \../../rtl/yarvi_ld_align.v \../../rtl/yarvi_st_align.v \altsyncram.v lpm_add_sub.vCONFIG-I$(CORE) $(YARVICONFIG) -DINIT_MEM\dhry.hex\ -DQUIET -DTOHOST10000000 -DKEEP_GOING#TRACE--traceTRACEobj_dir/Vyarvi:$(SRC) sim_main.cpp Makefile dhry.0.hex dhry.1.hex dhry.2.hex dhry.3.hexverilator-Wall --top-module yarvi \$(CONFIG) --cc $(SRC) --exe sim_main.cppmake-C obj_dir -f Vyarvi.mk Vyarvi$INIT0dhry.0.hex INIT1dhry.1.hex INIT2dhry.2.hex INIT3dhry.3.hexsim:obj_dir/Vtoplevel dhry.0.hex dhry.1.hex dhry.2.hex dhry.3.hexfor x in *.mif;do grep : $$x|sed -e s,^.*:,, -e s,;,, $$x.txt;done./obj_dir/VtoplevelINIT0dhry.0.hex INIT1dhry.1.hex INIT2dhry.2.hex INIT3dhry.3.hexobj_dir/Vtoplevel: $(SRC)verilator --cc toplevel.v ../../../red-lava/simulation/altsyncram.v --exe sim_main.cpp 21 /dev/nullmake -C obj_dir -j -f Vtoplevel.mk /dev/null 21# Begin Added by ChipCamp 20251226clean:rm -f dhry.0.hex dhry.1.hex dhry.2.hex dhry.3.hexrm -rf ./obj_dirEND关键词risc-v, yarvi, spike, iverilog, verilator.摘要本文记录了开源risc-v项目yarvi的make过程。在ubuntu 22.02下配套的verilator仿真失败但在ubuntu24.04 LTS下的verilator仿真则OK因此仍然可以看作是一个零门槛上手的项目。这个项目的Makefile仿真脚本还包含了使用spike所生成的参考trace文件(.ref文件)作为比较基准、使用diff来判断RTL的仿真结果是否正确这是一个值得参考的范式。在picorv32的项目中也有使用spike指令集仿真器运行代码的Trace作为RTL仿真结果的参考。