FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

オープンソース・アウトオブオーダCPU NaxRiscvを概観する (4. 波形のトレース)

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com

msyksphinz.hatenablog.com

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
    }