Xuantie openC906 simulation bug (printf cannot output)


Preface

        This article mainly solves the BUG that Printf cannot print normally on the terminal during the simulation process of C906.

        (Recently, I am also working on a Linux system based on C906. If you are interested, you can click the star

                https://github.com/sususjysjy/Linux-on-c906-with-litex.git


1. Open-C906

        Recently, we have to build a Linux system running on Riscv. There are not many open source Riscv cores, and we also need to meet the requirements of MMU. Rocket Chip, Vexriscv, and Xiangshan are all good choices, but unfortunately they are all Spinal or Scala. I really don’t know how to use them, so I can only use Pingtou Ge’s open source CPU.

        The open source ones with MMU only have cores starting with C, so after weighing resources, I finally chose C906.

2. C906 simulation environment

        Other bloggers have already explained the construction of Pingtouge simulation platform in detail. I will mainly talk about the CASE routine after construction.

1.Script modification

        First look at MAKEFILE. The default sim software of C906 is iverilog, but the compilation speed is too slow, so iverilog is changed to vcs for compilation.

################################################################################
# Simulation related
################################################################################
SIM = iverilog
DUMP = off

//修改后

################################################################################
# Simulation related
################################################################################
SIM = vcs
DUMP = on
 
 

2.CASE routine

        You can take a look at the CASE of C906 first.

        Let's run coremark and you can see the terminal results.

       

        It can be seen that the simulation is successful, but there is no output from the terminal. Check the coremark source file to see if there is printf content.

  #define FREQ 100000000 
  
  vtimer_end= get_vtimer(); 
  vcycles = vtimer_end - vtimer_start;
  vcycles = vcycles/iterations;
  printf ("\nVCUNT_SIM: CoreMark has been run %d times, one times cost %d cycles !\n",iterations,vcycles);
  float score;
//  score = FREQ/(float)vcycles;
//  printf ("\nVCUNT_SIM: CoreMark 1.0 : %f iterations/sec\n",score); //CoreMark = iterations of a sec
  score = 1000000/(float)vcycles; //to relieve relations with FREQ
  printf ("\nVCUNT_SIM: CoreMark 1.0 : %f (iterations/sec)/MHz\n",score); //CoreMark = iterations of a sec
  sim_end();

        The code outputs the running score results, but the terminal does not print them correctly. Then we need to trace the print register address defined by the bottom layer of printf. You can see that it is 0x6000fff8. At the same time, we also need to find whether the printing address specified in tb is the same.

int fputc(int ch, FILE *stream)
{ 
  asm(
      "li   x13, 0x6000fff8 \n\t" 
      "sw   %0, 0(x13) \n\t"
      : :"r" (ch): "x13" );
}
  else if((cpu_awlen[3:0] == 4'b0) &&
     (cpu_awaddr[31:0] == 32'h10015000) &&
      cpu_wvalid)

         In fact, we found a problem here. The address defined by the underlying lib is 0x6000fff8, and the address monitored by the axi bus for reading data is 0x10015000. The two cannot correspond, so when executing printf, the register with the correct address is not read to read the address. Naturally There will be no output from the terminal.

3.BUG modification

        So the first thing that comes to mind is to change the two addresses to be the same. We change them both to 0x10015000 and run CASE again.

        It's strange that it still doesn't print.

        Check the reason. The printed address cannot be the address in tb, nor can it be the address used by the c910 core. The function's write fputcmust reach the top without stopping at the cache (so it must be in an uncacheable area). The manual says that when virtual memory is not used, the PMA settings can be there C906_RTL_FACTORY/gen_rtl/mmu/rtl/sysmap.h , and we see that until now 0x8fffffff, that area is cacheable (c910's settings are different). Then, until 0xbfffffff, it is not cacheable.

        So we found the reason. The printed address must be defined in the non-cacheable area, so it is larger than0x8fffffff,我们将打印地址设置为0x90000000,重新运行CASE。

        

         ok, you can output in the terminal normally! !

Guess you like

Origin blog.csdn.net/m0_45287781/article/details/133365665