4. Simulating the Core¶
The Chromite repository also contains a simple test-soc for the purpose of simulating applications and verifying the core.
To create a verilated executable follow the steps in Section 3 and then run the following command:
$ make link_verilator_elf
This will generate a
bin folder containing the verilated
chromite_core executable. This can be used
for simulation as described in Section 4.
Please note that the bram-based memory in the test-bench can only hold upto 32MB of code. Thus the elf2hex arguments will need to applied accordingly.
The elf2hex program is available from the modified spike application.
The size of the BRAM Memory can be changed by changing the configuration bsc_compile_options.test_memory_size in the configuration YAML.
4.1. BootRom Content¶
By default, on system-reset the core will always jump to
0x1000 which is mapped to the bootrom.
The bootrom is initialized using the file
boot.mem. The bootrom after a few instructions
causes a re-direction jump to address
0x80000000 where the application program is expected to be.
It is thus required that all programs are linked with text-section begining at
The rest of the boot-rom holds a dummy device-tree-string information.
boot.mem file is generated in the
bin folder using the following command:
$ make generate_boot_files
You can skip executing the bootrom by changing the reset_pc field in the configuration
YAML. However, the verilated executable will still require a dummy
boot.mem file to initiate
4.1.1. Verilated Executable¶
We use verilator to simulate the core and the test-soc described above. In order to generate the verilated executable do the following (you can skip this is you have already followed the steps so far)
$ cd chromite $ python -m configure.main -ispec sample_config/default.yaml $ make -j<jobs> generate_verilog $ make link_verilator_elf generate_boot_files
The above should result in following files in the
4.1.2. Executing User Programs¶
Let’s assume the software program that you would like to simulate on the core is called
prog.elf (compiled using standard riscv-gcc).
In order to run this elf on the chromite verilated executable you can do the following:
$ ./chromite_core +elf=<path to prog.elf>
Since the boot code in the bootrom implicitly jumps to
0x80000000 the programs
should also be compiled at
4.2. Hello World¶
To run hello-world first ensure the verilated executable is available in the bin folder (use steps mentionedin in Section 4.1.1. After which run the following:
$ make hello Hello World
To run dhrystone first ensure the verilated executable is available in the bin folder (use steps mentionedin in Section 4.1.1. After which run the following:
$ make dhrystone ITERATIONS=10000 Microseconds for one run through Dhrystone: 10.0 Dhrystones per Second: 98448.0
The above numbers are obtained by using the samples/rv64imacsu/* config files which have been configured for high performance. The performance numbers will change based on the config used to generate the core instance.
To run coremarks first ensure the verilated executable is available in the bin folder (use steps mentionedin in Section 4.1.1. After which run the following:
$ make coremarks ITERATIONS=35 2K performance run parameters for coremark. CoreMark Size : 666 Total ticks : 12323206 Total time (secs): 12 Iterations/Sec : 2 Iterations : 35 Compiler version : riscv64-unknown-elf-9.2.0 Compiler flags : -mcmodel=medany -DCUSTOM -DPERFORMANCE_RUN=1 -DMAIN_HAS_NOARGC=1 \ -DHAS_STDIO -DHAS_PRINTF -DHAS_TIME_H -DUSE_CLOCK -DHAS_FLOAT=0 \ -DITERATIONS=35 -O3 -fno-common -funroll-loops -finline-functions \ -fselective-scheduling -falign-functions=16 -falign-jumps=4 \ -falign-loops=4 -finline-limit=1000 -nostartfiles -nostdlib \ -ffast-math -fno-builtin-printf -march=rv64imafdc -mexplicit-relocs Memory location : STACK seedcrc : 0xe9f5 crclist : 0xe714 crcmatrix : 0x1fd7 crcstate : 0x8e3a crcfinal : 0xcf56 Correct operation validated. See README.md for run and reporting rules.
The above numbers are obtained by using the samples/default.yaml config file which has been configured for high performance. The performance numbers will change based on the config used to generate the core instance.
4.4.1. Notes on Simulation¶
4.5. Support for PutChar¶
The test-soc for simulation contains a simple uart. The
putchar function for the same is available
This has to be used in the printf functions. The output of the
putchar is captured in a separate
file app_log during simulation.
4.6. Simulation Arguments (plusargs)¶
./chromite_core +elf=<elf-path> +rtldump: if the core has been configured with
trace_dump: true, then a
rtl.dumpfile is created which shows the log of instruction execution. Each line in the file has the following format:
<privilege-mode> <program-counter> <instruction> <register-updated> <register value>
To enable printing of debug statements from the bluespec code, one can pass custom logger arguments to the simulation binary as follows
./chromite_core +elf=<elf-path> +fullverbose: prints all the logger statements across all modules and all levels of verbosity
./chromite_core +elf=<elf-path> +mstage1 +l0: prints all the logger statements within module stage1 which are at verbosity level 0.
./chromite_core +elf=<elf-path> +mstage2 +mstage4 +l0 +l3: prints all the logger statements within modules stage2 and stage4 which are at verbosity levels 0 and 3 only.
To print the cycle difference between 2 consecutive instruction commits you can use
+instr_latency along with rtldump to appen this in the rtl.dump file itself.
To exit the simulation when a self-loop is encountered use +halt_selfloop with the compiled binary
app_logfile is also created which captures the output of the uart, typically used in the
putcharfunction in C/C++ codes as mentioned above.
4.7. Connect to GDB in Simulation¶
A debugger implementation following the riscv-debug-draft-014 has been integrated with the core.
This can be instantiated in the design by configuring with:
Perform the following steps to connect to the core executable with a gdb terminal. This assumes you have installed openocd and is available as part of you $PATH variable.
sample_config/default.yaml to enable: debugger_support and open_ocd.
Generate a new executable with this config to support jtag remote-bitbang in the
$ python -m configure.main -ispec sample_config/default.yaml $ make gdb # generate executable with open-ocd vpi enabled in the test-bench
Simulate the RTL In a new terminal do the following:
$ cd chromite/bin/ $ ./chromite_core +elf=<elf-path> > /dev/null
Connect to OpenOCD Open a new terminal and type the following:
$ cd chromite/test_soc/gdb_setup/ $ openocd -f shakti_ocd.cfg
Connect to GDB Open yet another terminal and type the following:
$ cd chromite/test_soc/gdb_setup $ riscv64-unknown-elf-gdb -x gdb.script
In this window you can now perform gdb commands like :
set $pc, i r, etc
To reset the SoC via the debugger you can execute the following within the gdb shell:
$ monitor reset halt $ monitor gdb_sync $ stepi $ i r
The above will not reset memories like the BRAM Memory.