NaxRiscvのデザインをシミュレーションし、FST波形を出力してみようと思う。
$ sbt "runMain naxriscv.Gen64" $ cd $NAXRISCV/src/test/cpp/naxriscv $ make compile TRACE=yes
シミュレーションで波形を生成するためのコマンドは以下だ:
$ ./obj_dir/VNaxRiscv --trace --trace-ref --name coremark --load-elf ../../../../ext/NaxSoftware/baremetal/coremark/build/rv64ima/coremark.elf --pass-symbol pass
2K performance run parameters for coremark. CoreMark Size : 666 Total ticks : 2025329 Total time (secs): 2025329.000000 Iterations/Sec : 0.000005 Iterations : 10 Compiler version : GCC11.1.0 Compiler flags : -DPERFORMANCE_RUN=1 -march=rv64ima -mabi=lp64 -mcmodel=medany -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -I../driver -O3 -fno-common -funroll-loops -finline-functions -falign-functions=16 -falign-jumps=4 -falign-loops=4 -finline-limit=1000 -fno-if-conversion2 -fselective-scheduling -fno-crossjumping -freorder-blocks-and-partition -DCORE_DEBUG=0 -lgcc -lc -nostartfiles -ffreestanding -Wl,-Bstatic,-T,../common/app.ld,-Map,coremark.map,--print-memory-usage Memory location : STACK seedcrc : 0xe9f5 [0]crclist : 0xe714 [0]crcmatrix : 0x1fd7 [0]crcstate : 0x8e3a [0]crcfinal : 0xfcaf Correct operation validated. See README.md for run and reporting rules. CoreMark 1.0 : 0.000005 / GCC11.1.0 -DPERFORMANCE_RUN=1 -march=rv64ima -mabi=lp64 -mcmodel=medany -Wno-pointer-to-int-cast -Wno-int-to-pointer-cast -I../driver -O3 -fno-common -funroll-loops -finline-functions -falign-functions=16 -falign-jumps=4 -falign-loops=4 -finline-limit=1000 -fno-if-conversion2 -fselective-scheduling -fno-crossjumping -freorder-blocks-and-partition -DCORE_DEBUG=0 -lgcc -lc -nostartfiles -ffreestanding -Wl,-Bstatic,-T,../common/app.ld,-Map,coremark.map,--print-memory-usage / STACK 4.94 Coremark/MHz SUCCESS coremark
波形を開いて確認してみよう。
この波形がこの辺の実装に相当していると思う:
NaxRiscv/src/main/scala/naxriscv/fetch/PcPlugin.scala
val fetchPc = new Area{ //PC calculation without Jump val output = Stream(PC) val pcReg = Reg(PC) init(resetVector) addAttribute(Verilator.public) val correction = False val correctionReg = RegInit(False) setWhen(correction) clearWhen(output.fire) val corrected = correction || correctionReg val pcRegPropagate = False val inc = RegInit(False) clearWhen(correction || pcRegPropagate) setWhen(output.fire) clearWhen(!output.valid && output.ready) val pc = pcReg + (U(inc) << sliceRange.high+1) val flushed = False when(inc) { pc(sliceRange) := 0 } when(jump.pcLoad.valid) { correction := True pc := jump.pcLoad.pc flushed := True } when(init.booted && (output.ready || correction || pcRegPropagate)){ pcReg := pc } pc(0) := False if(!RVC) pc(1) := False val fetcherHalt = False output.valid := !fetcherHalt && init.booted output.payload := pc }