This screed is my personal opinion as a long term developer using many types of microcontrollers.
It does not apply to Linux systems or similar that load from a disk-like device and run from RAM.
The debugger commands for reset should reset everything except the debug module itself,
and nonvolatile items like a real-time clock.
Not just CPU(s), I/O, interrupts and enable, but also all clock and power domain controllers,
watchdogs that are on by default and etc.
Why? So that the debugger can always start the system.
Pin reset, power-on reset and (if implemented) watchdog reset and reset by software should reset everything.
In my opinion, the reset pin should also be bidirectional, so that attached devices are reset as well. (This is required for devices
that have safety or mission-assurance requirements. The whole system has to enter a known state.
Using a GPIO and diode is typical but shows IC designers don’t understand.)
There -should- be a register that explicitly tells the source of the most recent reset.
(A one-of-N bit register is popular. Easy to implement, I think.)
Otherwise, end-user software engineers have to reverse engineer the reset source from side-effects.
This is amazingly wasteful busy-work, easily prevented in design.
I think watchdog devices should be included with the CPU IP, and there should be a trim or battery-backed RAM register
option for it to be on by default. And of course, attaching a debugger should turn it off.
Why? Most customer provided start-up code I have seen is so fragile that it needed an on-by-default watchdog to start in EMI.
A 1.5 second watchdog is useful and typical, but some safety and mission assurance people want it to be programmable to as
little as 1/20 second, usually for medical ventilators, drones or other critical controls.
One absolutely treasured I/O device (loved by customers) I’ve seen was a single-pin wired-or fault bus that could cause a reset, NMI, wake from a no-CPU battery mode, Interrupt or be read and written like an I/O pin.
Reset interacts strongly with the debugger.
I’ve never seen debug done perfectly on first-silicon except after an FPGA prototype or three.
And, unfortunately, without a debug channel, first silicon is pretty much dead in the water.
RISC-V had -two- standard debugger schemes the last time I checked.
Really pick the most flexible one and do it well.
If there is no program in the device, the CPU(s) should halt,
probably after a double error exception or something of the sort.
Ideally, it should enter a low power mode.
If you’re a CPU IP vendor, please plan for some of your customers to have a boot ROM. Processes without flash really require it.
If you provide I/O devices, boot ROM template code using the standard I/O devices (i.e. UARTs or USB) is a nice addition.
Be sure to validate an FPGA version, here, too. (That’s where your template code will come from.)
The debugger must be able to recover the CPU(s) from these conditions, usually with reset,
and run starting at an arbitrary commanded address.
When debugging, use the debugger’s standard scheme to set the CPU’s starting address, not the CPU’s.
Why? A typical way to load code to a microcontroller in a Princeton cycle device (like RISC-V) is with a download driver in RAM, loaded by the debugger. The download driver is usually half-written by the application engineering team that sells a completed IC.
The other half is a template provided by the debugger software people, who are often associated with the compiler vendor.
Since this strange little piece of code is in RAM, obviously it is not in code at the standard starting place.
One of the interesting mistakes I’ve seen with using CPU IP is to start a coprocessor’s shared RAM at the
bottom address of RAM, where most debuggers also try to put their download drivers.
So, don’t do that. And, try to head off the mistake with documentation, and provide ways to recover.
So, nag debugger vendors to have flexible options for reset and the address of the download driver.
Download drivers should always be relocatable code.
Try to make a trace module available, and so cheap that it’s almost a crime to leave it out.
E.g., maybe make the difficult hardware parts into a little piece of optional interrupt code, provided with the CPU IP.
I, and most end-user programmers have spent weeks chasing issues that trace would find in seconds.
And always, always, the trace module was left out because it was “too expensive.” I.e. too much silicon.
Sometimes the associated flash array was a quarter meg, and 1K of trace -code- would be perfectly affordable
Best wishes. I hope this helps…
You received this message because you are subscribed to the Google Groups "RISC-V HW Dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to hw-dev+un...@groups.riscv.org.
To view this discussion on the web visit https://groups.google.com/a/groups.riscv.org/d/msgid/hw-dev/fb744c93-5e7f-403b-98f9-8f1eccafdf68n%40groups.riscv.org.