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

NaxRISCV Bare Metal Demo not working #2169

Closed
BMorgan1296 opened this issue Jan 26, 2025 · 9 comments
Closed

NaxRISCV Bare Metal Demo not working #2169

BMorgan1296 opened this issue Jan 26, 2025 · 9 comments

Comments

@BMorgan1296
Copy link

BMorgan1296 commented Jan 26, 2025

Hi,

I am experimenting with different cores and found that the bare metal demo does not work for NaxRISCV under simulation or FPGA.

I am able to boot, but only get the "Liftoff!" printout and nothing else once it jumps into the demo.bin. This is due to the processor stalling on the interrupt handling routines specified in demo's main.c:

int main(void)
{
// #ifdef CONFIG_CPU_HAS_INTERRUPT      //       <-- If I comment these out I get the donut :)
//	 irq_setmask(0);
//	 irq_setie(1);
// #endif
	uart_init();

	donut_cmd();

	help();
	prompt();

	while(1) {
		console_service();
	}

	return 0;
}

Having spent a bit of time figuring out why, this seems related to #1754, #1584, #2023, where the processor did not have its interrupt handling defined.

I checked /soc/cores/cpu/naxriscv/irq.h and the interrupt handling is all there, which I assume is used to tell the core when I type into the terminal and press enter etc.

I have found that the set global interrupts function, irq_setie(1); is causing the CPU to halt execution when it tries to enable the interrupst with the following: asm volatile ("csrrs x0, " "mstatus" ", %0" :: "i"(CSR_MSTATUS_MIE));

Which translates to asm volatile ("csrrs x0, " "mstatus" ", %0" :: "i"(0x8));

I have tested and setting this mstatus register to 0x0 doesn't halt the processor, as based off the instruction set, a value of 0x0 will not write to the register.

Cheers.

@BMorgan1296
Copy link
Author

BMorgan1296 commented Jan 26, 2025

Ok I have figured it out.

The NaxRISCV is booting into user mode, and for comparison, the VexRISCV is in machine mode.

Mstatus for the NaxRISCV is 0x2000, i.e. MPP field which is bits 11,12 = 0x00 == User mode.

Mstatus for the NaxRISCV is 0x1800, i.e. MPP field which is bits 11,12 = 0x11 == Machine mode.

Just figuring out how to change this now :)

EDIT:
I tried to brute force my way and change the raw Verilog before simulation:

PrivilegedPlugin_logic_machine_mstatus_mpp <= 2'b11;

But this didn't help!

Then I found this in crt0.S for the NaxRISCV:

  call plic_init // initialize external interrupt controller
  li t0, 0x800   // external interrupt sources only (using LiteX timer);
                 // NOTE: must still enable mstatus.MIE!
  csrw mie,t0

I change it to

  li t0, 0x808

And now all is working. Is this the appropriate method to do enable interrupts, or does // NOTE: must still enable mstatus.MIE! mean this should be done at a later time?

@Dolu1990
Copy link
Collaborator

Hi ^^

The NaxRISCV is booting into user mode

NaxRiscv boot in machine mode.
The mstatus.mpp field doesn't indicate the current privilege mode, the the privilege mode which will be taken on the next mret instruction.

If do baremetal stuff only, you never need to change the mpp value, because once the CPU enter an interrupt, the MPP field is changed to the privilege the CPU was in (machine).

And now all is working. Is this the appropriate method to do enable interrupts

This seems ok to me ^^

@BMorgan1296
Copy link
Author

BMorgan1296 commented Jan 27, 2025

Ok I’ll check other CPUs for this same issue first and make a PR to fix this so the bare metal demo works.

One question though, why is it halting on irq_setie(1);?

@Dolu1990
Copy link
Collaborator

One question though, why is it halting on irq_setie(1);?

It shouldn't, it is like, as you said, if NaxRiscv wasn't in machine mode anymore.
A simulation wave can easily show the issue ^^
Can you send me all the modified files + command lines you used ?

@BMorgan1296
Copy link
Author

I made a PR #2170 showing what I changed (a single character in litex/soc/cores/cpu/naxriscv/crt0.S lol).
Commands I ran were (after Litex installation):

litex_sim --integrated-main-ram-size=0x10000 --cpu-type=naxriscv  --no-compile-gateware
litex_bare_metal_demo --build-path=build/sim/
litex_sim --integrated-main-ram-size=0x10000 --cpu-type=naxriscv --ram-init=demo.bin

@Dolu1990
Copy link
Collaborator

Thanks ^^
That is weird, on my side, all is going well :

<DUMP ON>
        __   _ __      _  __
       / /  (_) /____ | |/_/
      / /__/ / __/ -_)>  <
     /____/_/\__/\__/_/|_|
   Build your hardware, easily!

 (c) Copyright 2012-2024 Enjoy-Digital
 (c) Copyright 2007-2015 M-Labs

 BIOS built on Jan 29 2025 13:05:03
 BIOS CRC passed (09980d8b)

 LiteX git sha1: c213c4274

--=============== SoC ==================--
CPU:		NaxRiscv 32-bit @ 1MHz
BUS:		wishbone 32-bit @ 4GiB
CSR:		32-bit data
ROM:		128.0KiB
SRAM:		8.0KiB
MAIN-RAM:	64.0KiB

--========== Initialization ============--


--============== Boot ==================--
Booting from serial...
Press Q or ESC to abort boot completely.
sL5DdSMmkekro
Timeout
Executing booted program at 0x40000000

--============= Liftoff! ===============--

LiteX minimal demo app built Jan 29 2025 13:01:43

Available commands:
help               - Show this command
reboot             - Reboot CPU
donut              - Spinning Donut demo
helloc             - Hello C
litex-demo-app> donut   
litex-demo-app> donut
Donut demo...

                                                                               
                                                                               
                                                                               
                                 $@@$$@@$$$@@$                                 
                             $$$$$###########$$$$$                             
                           $####**!!!!!!!!!!!**###$$                           
                         ####**!===============!**####                         
                       *##**!!!===;::::::::;;===!!!*###*                       
                      !****!!===;:~--,,.,,-~~:;===!!*****                      
                     =****!!==;;:-,........,--:;;=!!!****=                     
                     !***!!!==;:--...........-~:;=!!!!***!                     
                     !***!!!=;;:-,..       ..,-:;==!!!**!!                     
                    ;!!**!!!==;:-,.         ~;==!!!!**!!!=:                    
                     =!!!****!*!!!==       =!!********!!!=                     
                     ;=!!!*****#*#####***########****!!==;                     
                     -;=!!****####$$$$$@@@$$$$###****!!=;-                     
                      ~:=!!****###$$$$@@@@$$$$###**!!==;-                      
                       ,:;=!!**####$$$$$$$$$####**!!=;:-                       
                         -:;=!!!**###########**!!!=;:-                         
                           -:;;==!!!*******!!!==;::-                           
                             .-~::;;=======;;::~-.                             
                                 ..,,-----,,,.                                 
  • I checked in the waveform, i can see the interrupts going just well
  • You tried with upstream litex right ?
  • You may have a old NaxRiscv netlist, to be sure, delete pythondata-cpu-naxriscv/pythondata_cpu_naxriscv/verilog/NaxRiscvLitex_*.v

Hmm, so that is weird i can't reproduce the issue.
I would say the way to move forward with this, is for me to get your simulation waveform.
For instance, i used :
litex_sim --integrated-main-ram-size=0x10000 --cpu-type=naxriscv --ram-init=demo.bin --trace --trace-fst --trace-start=575000000000 --trace-end=590000000000
(the commits done by the CPU can be visualized by naxes_0_thread_core/commit_pc_X and commit_mask

I'm happy to take a look into your wave.fst ^^

@BMorgan1296
Copy link
Author

BMorgan1296 commented Jan 29, 2025

Hi, thanks for that. I’ll check my repo is all updated and get you those waveforms tomorrow.

Could you let me know what your Verilator version was too?

@Dolu1990
Copy link
Collaborator

Thanks ^^

I'm using : Verilator 4.218 2022-01-17 rev v4.218

@BMorgan1296
Copy link
Author

BMorgan1296 commented Jan 30, 2025

So I installed fresh, and ran just the above 3 simulation commands

Relevant dependencies are:

  • sbt 1.6.0 (Ubuntu Java 11.0.25)
  • Verilator 5.020 2024-01-01 rev (Debian 5.020-1)

and... it worked! I honestly have no clue what has changed as I had encountered the error when installing Litex on a different machine. I did install with 2024.12 once, maybe that interfered.

I have checked and the following likewise works:

python3 -m litex_boards.targets.digilent_arty --variant=a7-100 --build --cpu-type=naxriscv --cpu-variant=standard --bus-standard=wishbone --vivado-max-threads=16
litex_bare_metal_demo --build-path=build/digilent_arty
python3 -m litex_boards.targets.digilent_arty --variant=a7-100 --load --cpu-type=naxriscv --cpu-variant=standard --bus-standard=wishbone
litex_term /dev/ttyUSB1 --kernel=demo.bin

Thank you for your time, I'm glad a simple reinstall fixed the issue.

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

No branches or pull requests

2 participants