This is a GDB server stub written in SystemVerilog (and a bit of DPI-C). It is primarily designed for RISC-V standard processors, but it can be modified to connect to other processor families.
Advantages:
-
can be used on RTL CPU without explicit debug functionality,
-
real time debugging, no simulation time is consumed by the debugger (useful for bitbanging and real time interrupts),
-
read/write access to registers and memories using direct references,
-
hardware breakpoints/watchpoints.
Disadvantages/limitations:
-
non synthesizable,
-
writing to registers/memory can have unpredictable effects (seriously),
-
RTL modifications are still needed to be able to change the SW execution flow (jump, …),
-
lack of system bus access, since it would consume simulation time,
-
access by reference results in multiple drivers to memory/register file arrays, necessitating the use of
always
instead ofalways_ff
to implement them, this results in missing simulator optimizations and subsequently slower simulations.
acronym | definition |
---|---|
GRP |
General Purpose Registers (register file) |
PC |
Program Counter |
FPR |
Floating-Point Registers (register file) |
CSR |
Configuration Status Registers |
HDL |
|
RTL |
|
ROM |
|
RAM |
The GDB server stub is connected to SoC signals:
-
following the system clock and driving the reset,
-
monitoring CPU IFU/LSU interfaces to trigger breakpoints/watchpoints (can also be used to detect illegal instruction execution),
-
register files (GPR/FPR) and individual registers (PC/CSR) inside the CPU should be connected using bidirectional hierarchical path names,
-
memory arrays inside memory modules should be connected using bidirectional hierarchical path names.
The connection to a GDB/LLDB client uses a Unix or TCP server socket.
The implementation is a mix of DPI-C
and pure SystemVerilog code.
The DPI-C
code implements minimal socket functionality,
while SystemVerilog implements packet parsing, responses
and integration with the CPU.
The DPI-C
implements socket functionality missing from the SystemVerilog language.
-
opening/closing of Unix server sockets, (TODO: TCP sockets)
-
blocking/non-blocking rend/receive access to sockets.
Note
|
While it would be partially possible to use a Linux character device model
and existing SystemVerilog file IO functionality to implement communication with GDB,
SystemVerilog only provides blocking fread /fgetc functions.
Non-blocking read functionality is essential for implementing the GCC continue command,
where the HDL simulation is running and consuming simulation time,
while periodically (every clock cycle) checking for GDB commands.
|
TODO (simple):
-
add support for more packets (
q*
queries,v*
, …), -
query for capabilities,
-
advanced mode,
-
mode without acknowledge,
-
expand support for additional formats of partially supported packets,
-
write regression tests (simple but a lot of work),
-
integration with GUI tools,
-
support for TCP sockets,
-
support for handling illegal instructions,
-
backtracing,
-
support for binary memory access packets (
x
/X
), but this is not really necessary, -
workarounds for Verilator issues,
-
LLDB support,
-
support for pausing the simulation (
$stop()
), to be able to see waveforms, also enabling/disabling waveform dumping, -
…
TODO (difficult):
-
understand packet patterns used by GDB,
-
what state the system should start in (reset/running/breakpoint/…)?,
-
inserting/removing breakpoints/watchpoints and relation to step/continue,
-
software breakpoints inserting/removing is done with
z/Z
packets orm/M
(memory access), -
I/C (32/16 bit EBREAK instruction) breakpoints.
-
check whether there are race conditions to fix,
-
the code currently only runs in Questa, try to port to other simulators,
-
generalize access to more than one memory, and additional registers (CSR) (full generalization requires the SystemVerilog simulator to support the
alias
keyword), -
…
Additional maintenance
commands can be found here (useful for RESET functionality?):
-
Zephyr RTOS gdbstub
-
OpenOCD gdb_server
-
RISC-V based Virtual Prototype (VP) gdb-mc
This links are CPU intensive:
Connecting to Python:
Talk about adding socket support to SystemVerilog