muir-fpga · debugging
Debugging a
Lisp Machine.
A CADR is debugged by another CADR. This page is how MIT did that, and how a board here does it.
The debugger is not a program on a host. It is a second Lisp Machine, running bus cycles on the first over a cable of twenty-one wires, as though it were that machine’s own processor.
The program that drives the cable is CC, and it is Lisp software on the debugging machine.
Every board running the CADR is a debuggee the moment it is powered, which is what a CADR is with nothing set, and one of them can be told to be the debugger instead.
01 / MIT’S WAY
How MIT debugged
a CADR.
The debugger’s DBGOUT connector goes to the debuggee’s DBGIN connector on its bus interface board, and a debugger works the cable by writing four registers of its own. The CADR’s page draws the cable, its twenty-one wires and the four strobes they make.
What CC does over the cable, every one of them a bus cycle on the other machine:
CC-STOP-MACH: one write of 0 to0o766006, and the machine halts where it stands.SPY-READ: any of the sixteen diagnostic registers, which is the machine’s whole state as the console sees it.CC-EXECUTE: forces a microinstruction into the instruction register, which is how a scratchpad is read.DBG-READ-XBUS: writes Unibus map entry 17 and reads main memory through the window at0o140000that the map translates.DBG-RESET: the modifier register’s bit 1, which resets the debuggee’s Unibus and bus interface, and halts it.PROG.BOOT: bit 7 of a write to the mode register, one of the three ways a CADR can be told to boot.
02 / ON THE BOARDS
How the fabric
does it.
MIT’s DBGIN logic is in the machine here, and so are the four DBGOUT registers CC writes, so a board can be either end of the cable.
03 / BETWEEN TWO BOARDS
The cable.
A cable for this link joins the eight signals and the two grounds, and leaves the 3.3 V supply pins open at both ends.
04 / THE TWO PMOD BOARDS
The cable on
the Pmod boards.
The Arty Z7-20 carries the cable on Pmod JA and the Kria KR260 on PMOD1, the first of its four Pmod headers. On each the eight signal pins are 3.3 V, each with a pull-down, so an unplugged connector reads zero.
The eight signals are on pins 1 to 4 and 7 to 10 of each connector, in the same order, so a straight ribbon between any two of them joins each signal to its counterpart. The Arty’s package pins are from Digilent’s file; the Kria’s are AMD’s.
A mirrored ribbon is one pressed on the other way up, which joins each row to the other, and the debugger finds it under auto.
The grounds are joined and the supplies are not. Pins 5 and 11 are ground and the cable joins them. Pins 6 and 12 carry each board’s own 3.3 V, and the cable leaves them open at both ends. Neither board’s .xdc file names a supply pin, so nothing in the design can drive one.
The Arty has run this cable.
A ribbon between its JA connector and another board’s has carried the link, each board running Lisp throughout; the table below says what it carried.
The Kria’s pin order is AMD’s, and it has not been checked on a wire.
The Kria’s package pins and the order of its eight signals come from AMD’s board files for the KR260. That the first eight pins in those files are header pins 1 to 4 and 7 to 10 is the order every Pmod pin file uses, and no schematic of the carrier is published to check it against. The Kria’s cable has not been run on the boards: the connector is built into this board’s CADR, the console reads a debuggee on it with nothing attached, and it has crossed nothing.
05 / A GPIO HEADER, NOT A PMOD
The cable on
the DE25-Nano.
That board has no Pmod, so its end of the cable is eight pins of a 2x20 GPIO header: JP1 pins 31 to 38, with the header’s own ground on pin 30. The signals are on the odd pins and each guard is the even pin beside its signal.
06 / FRAMES ON EIGHT PINS
The protocol
on the wire.
Twenty-one wires do not fit on eight pins, so the levels cross as frames: four pins each way, and neither group is ever driven from both ends.
07 / ON SILICON
What has run
on a board.
All three pieces have run on silicon: the window, the ribbon, and CC across the ribbon, both ways round, a write into a register of the far machine among them. Over the guarded carrier, what has crossed is every cycle a CC session is built out of, typed at a Listener; the CC program itself has not run over it.
| What | How it was shown | Shown |
|---|---|---|
| The machine halted, and its registers read | CC through the register window, each register equal to the console’s reading of the same halt | yes |
| The scratchpads | CC’s reads over the window, equal to the console’s readout of the same words | yes |
| Main memory, through the map | Words read through the mapped window, each equal to the console’s reading of the same address; a write through the map moved MD and spent no microcycle | yes |
| The ribbon between two boards | The role taken and given back on a real cable between two Pmod JA connectors, the far end answering | yes |
| A mirrored ribbon, found by the fabric | The board told to connect reported the crossover it had found; forced the wrong way round, nothing answered | yes |
| Two idle boards on that ribbon | Both read a debuggee with nothing driving the connector; the role bit tells the two apart | yes |
| Neither machine noticing | Both boards ran Lisp throughout, at the rate they run at with no cable in them | yes |
| CC over the ribbon | Halted, read and started again, both ways round, every word equal to the far board’s own console and readout | yes |
| Every microcycle accounted for | The far machine’s cycle counter moved by one for each scratchpad read, and the debuggee’s own window saw no request at all | yes |
| The guards, and the frames refused | 0 refused in twenty-four readings; two frames on the other board are unaccounted for | yes |
| A debug cycle over the guarded carrier | A status read typed at the debugger’s Listener, both ways round; no register of the far machine crossed | yes |
| CC over the guarded carrier | All sixteen of the far machine’s diagnostic registers read over the guarded ribbon at one halt, each equal to the far board’s own console, and the machine stepped and started over it; CC’s own sequences typed at a Listener, and not the program run | yes |
| A write over the ribbon | MD written over the ribbon by CC’s own CC-WRITE-MD; the far board’s own console read 0xa53c5ac3 where it read 0x0a0005c2 before and after the restore, and no microcycle was spent | yes |
| The Kria KR260’s connector | Nothing. No ribbon has joined PMOD1 to another board, so its eight pins have crossed nothing; the console reads a debuggee on it with nothing attached | not yet |
| The DE25-Nano’s connector | Nothing. No cable from a 2x20 header to a Pmod has been made, so those eight pins have crossed nothing; what reads them is lint and a check on the pin map | not yet |
yes means a board itself has shown it, which is not the claim a board drawing’s green makes: green says a block is this project’s work and done, which is built and checked rather than run on that board.
08 / SOURCES
Where each drawing
came from.
Each figure above was read from the sources listed here. A number with a leading 0o is octal, which is how MIT writes an address.
| Figure | Read from |
|---|---|
| the same cable in the fabric | rtl/machine/cadr_dbgin.sv, cadr_busint_regs.sv, rtl/plumbing/cadr_debug_window.sv, cadr_dbg_join.sv; docs/console.md |
| the cable | rtl/plumbing/cadr_dbg_cable.sv, and each board’s own .xdc, whose pins come from Digilent’s published files |
| the cable on the Pmod boards | boards/arty-z7-20/cadr_arty.xdc for the Arty’s pins, which are Digilent’s; boards/kria-kr260/cadr_kr260.xdc for the Kria’s, which are AMD’s; docs/debug-cable.md for the roles |
| the cable on the DE25-Nano | boards/de25-nano/de25_nano_pins.tcl and cadr_de25.sv for the pins, docs/debug-cable.md for the roles; that board’s user manual, Figure 3-18 for the header and Figure 2-1 for where it sits on the board |
| one frame on the wire | rtl/plumbing/cadr_dbg_tx.sv and cadr_dbg_rx.sv: the marker, the parity, the beats and the gap |
| what the frame carries | rtl/plumbing/cadr_dbg_cable.sv, which packs both frames in one expression, counted off BUSINT.netlist |