lowRISC / ibex-demo-system

A demo system for Ibex including debug support and some peripherals
Apache License 2.0
54 stars 43 forks source link

Unable to load a new program using OpenOCD if the current program doesn't run in an infinite loop #48

Open nuntipat opened 1 year ago

nuntipat commented 1 year ago

I created a new test program and used the CMake build script in the sw directory to build it. However, after the FPGA is programmed, the load_demo_system.sh script only works the first time and consistently fails on subsequent attempts. (Note: I have adapted the design to work on the PYNQ-Z2 board, but that shouldn't be the root of the problem as the script worked the first time.)

Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'ftdi device_desc' not 'ftdi_device_desc'
DEPRECATED! use 'ftdi vid_pid' not 'ftdi_vid_pid'
DEPRECATED! use 'ftdi channel' not 'ftdi_channel'
DEPRECATED! use 'ftdi layout_init' not 'ftdi_layout_init'
Warn : `riscv set_prefer_sba` is deprecated. Please use `riscv set_mem_access` instead.
force hard breakpoints
Info : ftdi: if you experience problems at higher adapter clocks, try the command "ftdi tdo_sample_edge falling"
Info : clock speed 10000 kHz
Info : JTAG tap: riscv.cpu tap/device found: 0x23727093 (mfg: 0x049 (Xilinx), part: 0x3727, ver: 0x2)
Info : JTAG tap: arm_unused.tap tap/device found: 0x4ba00477 (mfg: 0x23b (ARM Ltd), part: 0xba00, ver: 0x4)
Info : datacount=2 progbufsize=8
Error: unable to halt hart 0
Error:   dmcontrol=0x80000001
Error:   dmstatus =0x00000c82
Error: Fatal: Hart 0 failed to halt during examine()
Warn : target riscv.cpu examination failed
Info : starting gdb server for riscv.cpu on 3333
Info : Listening on port 3333 for gdb connections
Error: Target not examined yet

The reason, as far as I can tell, is that my program returns 0 and transfers control back to crt0.S instead of running in an infinite loop like the other demo program. The problem is solved by adding a while(1) loop at the end of the program, although a sleep_loop in crt0.S should have also worked. Further investigation indicates that the design appears to be stopped after writing 1 to SIM_CTRL_BASE + SIM_CTRL_CTRL, preventing the design from receiving commands from openocd until the FPGA is reprogrammed.

main_entry:
  /* jump to main program entry point (argc = argv = 0) */
  addi x10, x0, 0
  addi x11, x0, 0
  jal x1, main

  /* Halt simulation */
  li x5, SIM_CTRL_BASE + SIM_CTRL_CTRL
  li x6, 1
  sw x6, 0(x5)

  /* If execution ends up here just put the core to sleep */
sleep_loop:
  wfi
  j sleep_loop

Should we put the code to halt simulation under #ifdef, which can be controlled by the CMake option? Or should we make a modification such that the design can only be halted in the simulator but not in the FPGA? Thank you for your suggestion, and either way, I would be happy to create a PR for the fix.

#ifdef HALT_SIM_WHEN_EXIT
  /* Halt simulation */
  li x5, SIM_CTRL_BASE + SIM_CTRL_CTRL
  li x6, 1
  sw x6, 0(x5)
#endif
marnovandermaas commented 1 year ago

I think you're right that this is not the desired behavior. In the hardware there is a flag controlling whether the simulation control is generated: https://github.com/lowRISC/ibex-demo-system/blob/main/rtl/system/ibex_demo_system.sv#L394-L409

Maybe we can use that same flag in the assembly file?

nuntipat commented 1 year ago

I think that naming the flags VERILATOR is not self-explanatory, but I'm okay with either name. Please see my pull request #53 and let me know whether it is the right fix and which name you prefer. Thank you.