chipsalliance / rocket-chip

Rocket Chip Generator
Other
3.17k stars 1.12k forks source link

simulating verilog using cadence incisive instead of VCS #1046

Closed ouldelhacen closed 2 years ago

ouldelhacen commented 6 years ago

Hello, I am trying to simulate the rocket chip Verilog using cadence simulator instead of vcs (cd vsim;make run) I would like to know what to modify to do so! … is there an example of the makefrag and other files to modify somewhere!! Thanks for your help Rgds

terpstra commented 6 years ago

Try modifying vsim/Makefrag, specifically the VCS and VCS_OPTS variables. Then run 'make' in vsim.

ouldelhacen commented 6 years ago

Hi, Thanks for your comment, Yes that's what I tried to do, the simulation crashes at startup ncsim> ncsim: ../fesvr/elfloader.cc:27: std::map<std::basic_string, long unsigned int> load_elf(const char, memif_t, reg_t): Assertion `buf != ((void ) -1)' failed. make: *** [simv-freechips.rocketchip.system-DefaultConfig] Error 255

There is something still missing or maybe I did a mistake translating the VCS options into Irun. If somebody has tried the exercise with Incisive, It would be nice if he can share his experience. thanks

adich0 commented 6 years ago

What does your irun command look like?

ouldelhacen commented 6 years ago

irun -64 -access +rwc +sv -I/home/aouldelhacen/design/rocket-chip/riscv-tools/include -Wcxx -std=c++11 -verbose -ccargs /home/aouldelhacen/design/rocket-chip/riscv-tools/lib /home/aouldelhacen/design/rocket-chip/riscv-tools/lib/libfesvr.so -incdir /home/aouldelhacen/design/rocket-chip/vsim/generated-src +define+CLOCK_PERIOD=1.0 /home/aouldelhacen/design/rocket-chip/vsim/generated-src/freechips.rocketchip.system.DefaultConfig.v /home/aouldelhacen/design/rocket-chip/vsim/generated-src/freechips.rocketchip.system.DefaultConfig.behav_srams.v /home/aouldelhacen/design/rocket-chip/vsrc/TestDriver.v /home/aouldelhacen/design/rocket-chip/vsrc/SimDTM.v /home/aouldelhacen/design/rocket-chip/vsrc/jtag_vpi.v /home/aouldelhacen/design/rocket-chip/vsrc/plusarg_reader.v /home/aouldelhacen/design/rocket-chip/vsrc/ClockDivider2.v /home/aouldelhacen/design/rocket-chip/vsrc/ClockDivider3.v /home/aouldelhacen/design/rocket-chip/vsrc/AsyncResetReg.v /home/aouldelhacen/design/rocket-chip/csrc/SimDTM.cc /home/aouldelhacen/design/rocket-chip/csrc/jtag_vpi.c +define+PRINTF_COND=TestDriver.printf_cond +define+STOP_COND=!TestDriver.reset +define+RANDOMIZE_MEM_INIT +define+RANDOMIZE_REG_INIT +define+RANDOMIZE_GARBAGE_ASSIGN +define+RANDOMIZE_INVALID_ASSIGN +libext+.v -gui -controlassert /home/aouldelhacen/design/rocket-chip/vsim/assert_off.v -timescale 1ns/10ps

adich0 commented 6 years ago

Something about the SimDTM DPI doesn't play well with Incisive. I was never quite able to get a simulation running past time 0 with it in. If all you care about is simulating the DUT, I would generate a configuration of Rocket without the debug ports connected and provide your own stimulus.

ouldelhacen commented 6 years ago

Strange that it does not work with it!..Ok I will try to remove it and see what happen. thanks

jm4rtin commented 6 years ago

I'm trying to generate and simulate a TinyConfig with Incisive. I went into src/main/scala/system/TestHarness.scala and commented out these two lines: dut.reset := reset | dut.debug.ndreset dut.connectDebug(clock, reset, io.success)

This removes my need for the DPI library (which I think needs C++11 and causes major issues on the RHEL7 system I have Incisive on). I gave up trying to generate the core on RHEL7 and I'm doing that in an Ubuntu VM now. I then copy over the generated core for simulation.

I'm not running from the make script as I really don't want it trying to generate anything since I copied it over. Here is how I invoked Incisive manually: irun -sv -clean top.sv freechips.rocketchip.system.TinyConfig.behav_srams.v freechips.rocketchip.system.TinyConfig.v vsrc/plusarg_reader.v vsrc/AsyncResetReg.v -gui -debug -define RANDOMIZE_MEM_INI -define RANDOMIZE_REG_INIT -define RANDOMIZE_GARBAGE_ASSIGN -define RANDOMIZE_INVALID_ASSIGN -define PRINTF_COND=1 -define CLOCK_PERIOD=1.0

My top.sv simply instantiates the TestHarness and hooks up a clock and reset line. I then toggle the reset in an attempt for it to start executing code. This is where I'm having issues.

I found many PC values inside the core. ex_reg_pc looks like a valid bootrom address mem_reg_pc looks random

ex_pc_valid and ex_reg_pc blow up with don't cares shortly after reset is released but before the bootrom is read.

It seems to be trying to execute a bad instruction from a randomly generated register value: C0: 0 [0] pc=[30ca0f61] W[r 0=00000000][0] R[r11=00000000] R[r11=00000000] inst=[00002386] DASM(00002386)

riscsim

You can see the bootrom loading code (at the right address) that I assume is going into the instruction cache. All of the debug signals are being driven. Some portions of the AXI/TL bus seem to have don't cares. Is that normal when they are not in use?

  1. Is there some specific procedure I have to go through to get it to properly execute code?
  2. How can I inspect the general purpose registers (in the simulation not over the debug)? They seem to be generated as signals that don't make sense.
adich0 commented 6 years ago

If you copied and pasted your command exactly, there seems to be a typo in one of your -defines, namely RANDOMIZE_MEM_INIT.

Assuming that's not your problem, have you modified the reset vector and/or bootrom.S at all? Out of the box, my simulation jumped to 0x10040 (although I'm a couple weeks out of sync with the latest commit).

jm4rtin commented 6 years ago

Thank you for the fast reply. You're correct about my typo. I have another question now. Why do I need to initialize that? It seems like the CPU is letting bad code enter the pipeline and execute before the PC is reset to the appropriate address: riscsim

adich0 commented 6 years ago

I don't have much proof to support this, but I think it might be a simulation artifact. If you don't have those `defines included, Xs get propagated all over the place.

jm4rtin commented 6 years ago

I do understand that on a real system the value isn't X (it's 1 or 0) and so it probably wouldn't break anything to let random data into the processor during the boot sequence. That being said, why isn't the processor stalled waiting for the first PC value and instruction? Why is it filling the pipeline with random data?

I find it desirable for a design to work with X and not random data as it's clear when you read something unknown that you shouldn't have. Take for example the case when you load firmware into an SOC design and you need to verify boot code going into ROM. If memory is read before being written you get X and you can clearly see the mistake which would otherwise cause random behavior. This has actually helped us catch errors in the past. Sure you could keep randomizing memory to see the different behavior but that will never be exhaustive, takes more time, and could still miss the bug.

It seems like a bad idea for the CPU to start in an undefined state (even if it's just a subset of the CPU control signals that is undefined and causing this).

mwachs5 commented 6 years ago

The trace shows the pipeline at ALL cycles, not just for committed instructions. In the snippet of trace that you've shown, no operations have been committed. The pipeline has to have something in it every cycle, but I'd look for the places where the trace has [1] pc=... for instructions that actually committed.

mwachs5 commented 6 years ago

Also to answer some of your other questions...

To actually see what instructions the processor is "trying" to execute, my favorite place to look is where the instructions are provided to the core by the ICache. So, for TinyConfig, that would be the signals:

ExampleRocketSystem.tile.rocket.core.io_imem_resp*

when ready and valid are asserted together, you can look at the bits_pc and bits_data to see what PC and data are, to see if they are what you expect.

LGKev commented 6 years ago

how did you load the executable to your core @jm4rtin and hello from the springs!

jm4rtin commented 6 years ago

I started by modifying the code in the bootrom/ directory as desired. I then generated a ROM with scripts/vlsi_rom_gen and used the +maskromhex option to load the hex file that the bootrom/Makefile built into the simulation. At one point I modified the script to support multiple ROMs. Eventually I replaced the generated ROM with a model we already had and placed the core into one of our existing SoC designs. Eventually it went onto an FPGA. The code was stuffed into the FPGA bitstream with the data2mem Xilinx tool by our build system. I ran the ASIC synthesis and CoreMark on the FPGA to compare the core to processor that design originally had. It's been too rainy down here.

jrpetrus commented 5 years ago

@jm4rtin - Have you made progress with Cadence Incisive in the past year? I'm also curious about your vlsi_rom_gen / +maskromhex solution. I am stuck with an empty .rom.conf file in generated-src and don't know how to proceed. I am considering a hack to convert the test ELFs to HEX on-the-fly.

@mwachs5 - Is Mentor Questa known to work? I have access to that but not VCS.

These are my irun options:

IUS = irun -64
IUS_OPTS = -sv -vtimescale '1ns/10ps' \
    -Wcxx -std=c++11 \
    -I$(RISCV)/include \
    -L$(RISCV)/lib -lfesvr \
    -incdir $(generated_dir) \
    -define CLOCK_PERIOD=1.0  \
    -define PRINTF_COND='$(TB).printf_cond' \
    -define STOP_COND='!$(TB).reset' \
    -define RANDOMIZE_MEM_INIT \
    -define RANDOMIZE_REG_INIT \
    -define RANDOMIZE_GARBAGE_ASSIGN \
    -define RANDOMIZE_INVALID_ASSIGN \
    -define RANDOMIZE_DELAY=2 \
    +libext+.v \
    $(sim_vsrcs) \
    -cpost $(sim_csrcs) -end \
    -update

Compiles and elaborates without issue.

My problem is the run command line, and I think I need to pass an ELF binary via the command line, but you can't really do that with irun:

$ irun -64 -sv -vtimescale '1ns/10ps' -Wcxx -std=c++11 -I/app/rocket-riscv/include -L/app/rocket-riscv/lib -lfesvr -incdir /mnt/riscv/freechips/rocket-chip/vsim/generated-src -define CLOCK_PERIOD=1.0 -define PRINTF_COND='TestDriver.printf_cond' -define STOP_COND='!TestDriver.reset' -define RANDOMIZE_MEM_INIT -define RANDOMIZE_REG_INIT -define RANDOMIZE_GARBAGE_ASSIGN -define RANDOMIZE_INVALID_ASSIGN -define RANDOMIZE_DELAY=2 +libext+.v (verilog files...)  -cpost (cc files...) -end -update -run +permissive +ntb_random_seed_automatic +permissive-off +permissive +verbose +max-cycles=100000000 +permissive-off /mnt/riscv/freechips/rocket-chip/vsim/output/rv64um-v-mulh

irun(64): 15.20-s005: (c) Copyright 1995-2016 Cadence Design Systems, Inc.
irun: *E,FMUK: The type of the file (/mnt/riscv/freechips/rocket-chip/vsim/output/rv64um-v-mulh) could not be determined.

If I drop the ELF, Incisive starts but it looks like riscv-fesvr/htif.cc throws an exception. Maybe there is another way to explicitly name the binary, such as +load_elf=whatever?

ncsim> run
testing $random 2c6a0d58
C0:          0 [0] pc=[fd7e960bfd] W[r 0=0000000000000000][0] R[r18=3541c06a3541c069] R[r 4=0000000000000009] inst=[06491ecf] DASM(06491ecf)
irun: invalid option -- '6'
terminate called after throwing an instance of 'std::invalid_argument'
  what():  Unknown argument (did you mean to enable +permissive parsing?)
f123-adm commented 4 years ago

Hello ,I am have same problem. I am trying to simulate the rocket chip Verilog (TestHarness module) using cadence simulator(xrun) instead of vcs. Thanks for your answers ,its very help me to go forward ,but I find a new erorr . My run command xrun : xrun -linedebug -access rwc -top mytop -f mytop_list.lst -gui -64 -sv -debug -define CLOCK_PERIOD=1.0 -define RANDOMIZE_MEM_INIT -define RANDOMIZE_REG_INIT -define RANDOMIZE_GARBAGE_ASSIGN -define RANDOMIZE_INVALID_ASSIGN -define RANDOMIZE_DELAY=2 And after 43 current cycle number dont increase. snapshot4 Thanks for your attention! Hope on your answers.

sequencer commented 2 years ago

irun is currently not supported. but essentially we need a irun backend. This should depends on #2953 but the priority of this should be low. closing to clean up the issue list, but I think this issue could be moved to GitHub discussion when we have one.