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 fputc
must 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! !