stnolting / neorv32-riscof

✔️Port of RISCOF to check the NEORV32 for RISC-V ISA compatibility.
https://github.com/stnolting/neorv32
BSD 3-Clause "New" or "Revised" License
25 stars 6 forks source link

Error on running tests on DUT #10

Closed Abdulwadoodd closed 2 years ago

Abdulwadoodd commented 2 years ago

Hi, I'm getting errors on running tests on DUT. It might be ghdl. I'm new to this simulation environment and vhdl as well. Following is the error message for each test run by riscof.

ERROR | ./neorv32_riscof_tb.vhd:21:10: unit "numeric_std" not found in library "ieee"
../neorv32/rtl/core/neorv32_package.vhd:37:10: unit "numeric_std" not found in library "ieee"
../neorv32/rtl/core/neorv32_top.vhd:42:10: unit "numeric_std" not found in library "ieee"
./neorv32_riscof_tb.vhd:180:38: no declaration for "to_integer"
./neorv32_riscof_tb.vhd:180:30: target is not a variable name
./neorv32_riscof_tb.vhd:181:38: no declaration for "to_integer"
./neorv32_riscof_tb.vhd:181:30: target is not a variable name
./neorv32_riscof_tb.vhd:182:38: no declaration for "to_integer"
./neorv32_riscof_tb.vhd:182:30: target is not a variable name
./neorv32_riscof_tb.vhd:183:38: no declaration for "to_integer"
./neorv32_riscof_tb.vhd:183:30: target is not a variable name
./neorv32_riscof_tb.vhd:191:69: no declaration for "to_integer"
./neorv32_riscof_tb.vhd:192:69: no declaration for "to_integer"
./neorv32_riscof_tb.vhd:193:69: no declaration for "to_integer"
./neorv32_riscof_tb.vhd:194:69: no declaration for "to_integer"

I've installed ghdl using sud apt-get install ghl. Every other pre-requisite (toolchain, neorv32, riscof, arch-tests) is setup properly. Please help me resolve this error.

Also, no MAKEFILE is generated for DUT (neorv32) by RISCOF as it is generated for Reference (SAIL). How can we generate the Makefile for DUT as well?

Abdulwadoodd commented 2 years ago

Tests are running perfectly now. I have downloaded the ghdl from here, extract it, and set the path of the bin directory to the $PATH variable and ghdl is good to go.

But the MAKEFILE for DUT is still missing in the riscof_work directory after the tests run successfully. How can we get it generated?

stnolting commented 2 years ago

Tests are running perfectly now. I have downloaded the ghdl from here, extract it, and set the path of the bin directory to the $PATH variable and ghdl is good to go.

I also had some version issues at first (had multiple GHDL installations on my system). Anyway, great to hear that your setup works! :+1:

But the MAKEFILE for DUT is still missing in the riscof_work directory after the tests run successfully. How can we get it generated?

What MAKEFILE do you mean / for which purpose?

The executable for each test case is generated by a simple makefile in sim. But that's all. The rest of the framework's DUT-side is controlled by the Python script in plugin-neorv32.

Abdulwadoodd commented 2 years ago

I meant the Makefile generated by RISCOF. (Though, I am not sure if it is actually a Makefile or some log file that contains the executed commands) When we run the tests by RISCOF command or by running run.sh, there is a directory created called riscof_work. Inside this directory, there is a file (besides other files and directories) named Makefile.Reference-sail_c_simulator. I believe this file contains the command that was run on SAIL. But there is no file that shows the commands that were executed for DUT.

My purpose is the backtrack/debug and see if the right commands were executed for DUT, which means, to check if we are writing DUT's plugin (here: riscof_neorv32.py) in the right way or not. But how can I do that if RISCOF does not generate that file for DUT but only for REFERENCE?

stnolting commented 2 years ago

Ah, now I understand what you mean :wink:

There is nothing like a command log (like the ref's makefile) for the DUT because there is no such mechanisms implemented. However, you can add the verbose flag (-v debug; "debug" level) to the RISCOF script run.sh:

# run riscof
riscof -v debug run --config=config.ini \
           --suite=riscv-arch-test/riscv-test-suite/ \
           --env=riscv-arch-test/riscv-test-suite/env \
           --no-browser

This will dump all commands executed by the DUT (and it's framework) to the console:

simulation finished @226125ns
test='/mnt/n/Projects/neorv32-riscof/riscv-arch-test/riscv-test-suite/rv32i_m/B/src/andn-01.S'
   DEBUG | DUT executing cp -f ./sim/*.signature /mnt/n/Projects/neorv32-riscof/riscof_work/rv32i_m/B/src/andn-01.S/dut/.
   DEBUG | /mnt/n/Projects/neorv32-riscof
   DEBUG | cp -f ./sim/*.signature /mnt/n/Projects/neorv32-riscof/riscof_work/rv32i_m/B/src/andn-01.S/dut/.
   DEBUG | Running Test: /mnt/n/Projects/neorv32-riscof/riscv-arch-test/riscv-test-suite/rv32i_m/B/src/bclr-01.S on DUT
   DEBUG | Compiling test: /mnt/n/Projects/neorv32-riscof/riscv-arch-test/riscv-test-suite/rv32i_m/B/src/bclr-01.S
   DEBUG | /mnt/n/Projects/neorv32-riscof/riscof_work/rv32i_m/B/src/bclr-01.S/dut
   DEBUG | riscv32-unknown-elf-gcc -march=rv32izbs          -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g         -T /mnt/n/Projects/neorv32-riscof/plugin-neorv32/env/link.ld         -I /mnt/n/Projects/neorv32-riscof/plugin-neorv32/env/         -I /mnt/n/Projects/neorv32-riscof/riscv-arch-test/riscv-test-suite/env /mnt/n/Projects/neorv32-riscof/riscv-arch-test/riscv-test-suite/rv32i_m/B/src/bclr-01.S -o main.elf  -DTEST_CASE_1=True -DXLEN=32 -mabi=ilp32
   DEBUG | DUT executing cp -f /mnt/n/Projects/neorv32-riscof/riscof_work/rv32i_m/B/src/bclr-01.S/dut/main.elf ./sim/main.elf
   DEBUG | /mnt/n/Projects/neorv32-riscof
   DEBUG | cp -f /mnt/n/Projects/neorv32-riscof/riscof_work/rv32i_m/B/src/bclr-01.S/dut/main.elf ./sim/main.elf
   DEBUG | DUT executing make -C ./sim clean main.hex
   DEBUG | /mnt/n/Projects/neorv32-riscof
   DEBUG | make -C ./sim clean main.hex
   DEBUG | make: Entering directory '/mnt/n/Projects/neorv32-riscof/sim'
make: Leaving directory '/mnt/n/Projects/neorv32-riscof/sim'
   DEBUG | DUT executing sh ./sim/ghdl_run.sh -gRISCV_B=true
   DEBUG | /mnt/n/Projects/neorv32-riscof
   DEBUG | sh ./sim/ghdl_run.sh -gRISCV_B=true
   DEBUG | Using custom simulation arguments: -gRISCV_B=true
../neorv32/rtl/core/neorv32_top.vhd:401:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Peripherals = MTIME UART0
../neorv32/rtl/core/neorv32_top.vhd:428:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Boot configuration = direct boot from memory (processor-external memory).
../neorv32/rtl/core/neorv32_cpu.vhd:154:3:@0ms:(assertion note): The NEORV32 RISC-V Processor - github.com/stnolting/neorv32
../neorv32/rtl/core/neorv32_cpu.vhd:157:3:@0ms:(assertion note): NEORV32 CPU CONFIG NOTE: Core ISA ('MARCH') = RV32IB_Zicsr_Zicntr_Zifencei
../neorv32/rtl/core/neorv32_cpu.vhd:176:3:@0ms:(assertion warning): NEORV32 CPU WARNING! Assuming this is a simulation.
../neorv32/rtl/core/neorv32_cpu.vhd:184:3:@0ms:(assertion note): NEORV32 CPU CONFIG NOTE: Boot from address 0x00000000.
../neorv32/rtl/core/neorv32_cpu.vhd:217:3:@0ms:(assertion note): NEORV32 CPU CONFIG NOTE: <FAST_MUL_EN> enabled. Trying to infer DSP blocks for multiplications.
../neorv32/rtl/core/neorv32_cpu.vhd:220:3:@0ms:(assertion note): NEORV32 CPU CONFIG NOTE: <FAST_SHIFT_EN> enabled. Implementing full-parallel logic / barrel shifters.
../neorv32/rtl/core/neorv32_cpu_cp_bitmanip.vhd:176:3:@0ms:(assertion note): NEORV32 CPU: Implementing bit-manipulation (B) sub-extensions Zba Zbb Zbc Zbs
../neorv32/rtl/core/neorv32_wishbone.vhd:149:3:@0ms:(assertion note): NEORV32 PROCESSOR CONFIG NOTE: Ext. Bus Interface - PIPELINED Wishbone protocol, auto-timeout (16 cycles), LITTLE-endian byte order, ASYNC RX path, ASYNC TX path
U@ (=z'@0Zw={D#/?]K{8*Na$$L"HWyvYa"_
./neorv32_riscof_tb.vhd:212:13:@107445ns:(assertion warning): Finishing simulation.
simulation finished @107445ns
Abdulwadoodd commented 2 years ago

Thank you so much, Sir! This is exactly what I wanted.

One more point: ebreak and c.ebreak tests are failing on neorv32. And upon debugging, I see that the sail-riscv and neorv32 deal differently with mtval CSR , which means, sail-riscv stores the address of the instruction that is causing the trap (which is ebreak) while neorv32 does something else. Is that a bug, or I'm misunderstanding the behavior of mtval defined in the spec?

stnolting commented 2 years ago

The RISC-V priv. spec. explicitly allows that a platform can define the events that write to mtval (see https://github.com/riscv-software-src/riscv-config/issues/16).

The Sail model stores the address of the causing break instruction to mtval, but this is redundant as mepc already points to that address. The NEORV32 clears mtval on break instruction to save some hardware resources.

There is some explanation text in the README: Compatibility-Issues

That is why I have added a patch to circumvent this problem, as Sail does not yet support mtval configuration options.

Abdulwadoodd commented 2 years ago

Awesome, I overlooked the patch part and the Compatibility Issue. Surely, sail-riscv is broken here.

Thank you for explaining everything. And lastly, neorv32 is the most amazing thing that I've come across this week. As a recently graduated student, It is my dream to build a RISC-V processor (in Verilog/System-Verilog because no experience with vhdl yet :/ ) that has all of these capabilities and is able to boot Linux. But I guess, it will take some time to grasp more software skills. You have done really amazing job. Thank you for creating it making it an open-source project.

One last thing, Do you plan to add A extension to neorv32, as the documentation does not mention it, apparently?

stnolting commented 2 years ago

Thank you very much for the nice words!

(in Verilog/System-Verilog because no experience with vhdl yet :/ )

Not a re-implemenation in Verilog, but anyway: neorv32-verilog :wink:

able to boot Linux

This is also my dream / long-term goal. 😅

One last thing, Do you plan to add A extension to neorv32, as the documentation does not mention it, apparently?

The default use case of the NEORV32 is a single-core setup, so the A extension does not make a lot of sense here. However, atomic accesses might be useful (even in a single-core setup) when dealing with semaphores, mutexes and stuff like that (especially, when interrupted by interrupts).

So, yes, the A extension is on my TODO list.

Abdulwadoodd commented 2 years ago

Not a re-implemenation in Verilog, but anyway: neorv32-verilog wink

Awesome

This is also my dream / long-term goal. sweat_smile

Looking forward, and hoping to learn more from it :)

atomic accesses might be useful (even in a single-core setup) when dealing with semaphores, mutexes, and stuff like that (especially, when interrupted by interrupts).

Not aware of these stuff right now but will learn soon hopefully.

Thank you for the help. It solved my problem and it's been a nice discussion.