Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C code simulation using Verilator #66

Open
kuoyaoming93 opened this issue May 28, 2022 · 6 comments
Open

C code simulation using Verilator #66

kuoyaoming93 opened this issue May 28, 2022 · 6 comments
Labels
question Further information is requested

Comments

@kuoyaoming93
Copy link
Contributor

Hi @michael-platzer

I'm working in the optimization of some algorithms in C, and I would like to use Vicuna to speedup the operations.
I don't have any FPGA board with me now, that's why I want to simulate all using Verilator, to extract some metrics regarding the improvement.

  1. Is there any starting point that I could look into?
  2. Is there any printf to report the results in simulation?

Thank you in advance,
Yao-Ming

@michael-platzer
Copy link
Contributor

Hi @kuoyaoming93

my apologies for the incomplete documentation, I am hoping to improve it very soon!

The best starting point for simulating Vicuna with Verilator is to compile your program to a *.vmem file (see the sw directory) and then go to the sim directory, where you can start simulation using the command make verilator. Note that this command attempts to read a file called progs.csv, which contains information on the programs that you wish to run. You may optionally specify an alternative filename and the desired main core (Ibex or CV32E40X) using the environment variables PROG_PATHS_LIST and CORE_DIR, respectively, as follows:

make verilator PROG_PATHS_LIST=/path/to/my/prog_list.txt CORE_DIR=/path/to/vicuna/cv32e40x/

The file progs.csv is actually not a CSV (despite the misleading default name), but a text file which may specify several *.vmem files that are executed one after the other (with resets in between). Each line of this file is expected to contain 7 values (separated by spaces) as follows:

/path/to/my_prog.vmem pre_dump.vmem 0 1000 post_dump.vmem 0 1000

where /path/to/my_prog.vmem is the *.vmem file of the program you wish to execute (generated as described in the sw directory), pre_dump.vmem is the destination filename for a memory dump prior to starting execution of the program and post_dump.vmem is the destination filename for a memory dump after execution completed. The two numbers following each of these dump filenames are the start and end address of the memory region that shall be dumped in hexadecimal notation.

If you do not want to dump any memory to a file you may simply use a progs.csv with the following content:

/path/to/my_prog.vmem /dev/null 0 0 /dev/null 0 0

Note that simulation continues until your program attempts to access memory address 0 (which happens upon exceptions, thus an exception will halt simulation). To intentionally end simulation you may simply jump to address 0 using the assembly instruction jr x0.

Unfortunately, there is currently no printf or similar output for simulation (although that would certainly be a great addition). However, you could modify the Verilator simulation source file verilator_main.cpp. For instance, you could add some code to the if statement on line 183 that prints to stdout when writing a certain address, e.g.:

if (addr == 0x20000) {
    putc(top->mem_wdata_o & 0xFF, stdout);
}

Please let me know if you encounter any issues while following these instructions.

@michael-platzer michael-platzer added the question Further information is requested label May 30, 2022
@kuoyaoming93
Copy link
Contributor Author

kuoyaoming93 commented May 31, 2022

Thank you for your quick response @michael-platzer!

I can do printf C function and replicate all the info you provided. If you wish I could provide the basic functions for C printf function.

Example C code:

#include <stdint.h>
#include <runtime.h>
#include <printf.h>

#define q_field 16

int16_t wires_idx[q_field][q_field] = {
    {0,8,16,24,32,40,48,56,64,72,80,88,96,104,112,120},
    {8,0,40,72,120,16,88,112,80,24,64,48,104,96,56,32},
    {16,40,0,48,80,8,24,96,120,88,32,72,56,112,104,64},
    {24,72,48,0,56,88,16,32,104,8,96,40,80,64,120,112},
    {32,120,80,56,0,64,96,24,40,112,16,104,48,88,72,8},
    {40,16,8,88,64,0,72,104,32,48,120,24,112,56,96,80},
    {48,88,24,16,96,72,0,80,112,40,56,8,32,120,64,104},
    {56,112,96,32,24,104,80,0,88,120,48,64,16,40,8,72},
    {64,80,120,104,40,32,112,88,0,96,8,56,72,24,48,16},
    {72,24,88,8,112,48,40,120,96,0,104,16,64,80,32,56},
    {80,64,32,96,16,120,56,48,8,104,0,112,24,72,88,40},
    {88,48,72,40,104,24,8,64,56,16,112,0,120,32,80,96},
    {96,104,56,80,48,112,32,16,72,64,24,120,0,8,40,88},
    {104,96,112,64,88,56,120,40,24,80,72,32,8,0,16,48},
    {112,56,104,120,72,96,64,8,48,32,88,80,40,16,0,24},
    {120,32,64,112,8,80,104,72,16,56,40,96,88,48,24,0}
};

int main(void) 
{
    int i = 0;
    for(i=0; i<q_field;i++)
        printf("wires_idx[0][i]: %d\n\r",wires_idx[0][i]);

    printf("Hello world!\n\r");


    asm volatile("jr x0;");
    return 0;
}

Output:
Captura de pantalla de 2022-05-31 14-15-10

@kuoyaoming93
Copy link
Contributor Author

Hi @michael-platzer,

It seems that CSR performance is not enabled in verilator, right?
When I try to use mcycle(h) in Verilator, it drops an "Illegal Instruction" in studout.

@michael-platzer
Copy link
Contributor

Hi @kuoyaoming93 thanks for the feedback!

These CSR registers are part of the main core. I do not know whether these are enabled by default, but the documentation of Ibex and CV32E40X should have more details on these.

FYI, I am about to merge a large PR that changes many of the RTL source files and introduces a new way to configure Vicuna. However, my instructions above for simulating using Verilator should still work.

@michael-platzer
Copy link
Contributor

A slight inconvenience of the changes in #43 is that the Verilator 4.210 is now required to simulate Vicuna. If your distribution only features older versions, you can compile version 4.210 from source as follows:

git clone https://github.com/verilator/verilator
unset VERILATOR_ROOT
cd verilator
git checkout tags/v4.210
autoconf
./configure --prefix /opt/verilator
make
sudo make install
echo 'export PATH=/opt/verilator/bin:$PATH' | sudo tee -a /etc/profile

Note that the last two lines are optional, you may as well run Verilator from the build directory.

@kuoyaoming93
Copy link
Contributor Author

Hi @michael-platzer, thank you for your feedback.
The version I have is: Verilator 4.212 2021-09-01

I will check in detail the config of Ibex, and see why I can access to mcycle(h) in FPGA implementation, but not in Verilator.
Are there maybe configuration mismatches among verilator simulation and FPGA demo?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants