muir↗CADR PRESERVED.
QUUX EVOLVED.

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 to 0o766006, 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 at 0o140000 that 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.

FIG. 01 — HOW THE FABRIC DOES ITMUIR-FPGA
the same cable in the fabric: two ways in, one DBGIN page a board told to be the debugger the CADR, in the fabric DBGIN the debuggee’s end, MIT’s own logic, and never switched off DBGOUT the four registers CC writes, on this machine’s own Unibus the join: one DBGIN page, and two masters that can reach it the register window 0x8000_1000 sixteen words on a general-purpose port muir-sim, on the Arm cores a CADR that runs CC, reaching the window with --debug-cable-connect Pmod JA eight pins the ribbon a board with nothing set: a debuggee the CADR, in the fabric DBGIN answering the board at the other end of the ribbon DBGOUT built here too, and this board could be told to be the debugger instead the join: one DBGIN page, and two masters that can reach it Pmod JA eight pins muir-sim, on the Arm cores this board stays debuggable from here whatever the ribbon does the register window 0x8000_1000 sixteen words on a general-purpose port and a board is told which end of the cable it is debug-cable-connect ask to be the debugger on the connector. The first board told is the one that has it debug-cable-disconnect give the role back. A board with nothing set is a debuggee, which is what a CADR is debug-cable-wiring auto, straight or crossover: which way round the ribbon was made debug-cable read it back: the role this board has, what is on the connector, and the frame counters The console’s own words. The card’s file of flags carries the same one, and the start-up script applies it at boot.
Only the connector changes hands. A board’s own DBGIN page is never switched off, so a debugger board stays debuggable through its window.

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.

FIG. 02 — THE CABLEMUIR-FPGA
the cable Pmod JA on both boards this board’s header 1 2 3 4 5 6 7 8 9 10 11 12 the other board’s header 1 2 3 4 5 6 7 8 9 10 11 12 the ribbon pin 1 to pin 1, and so on signal signal signal signal ground joined 3.3 V OPEN signal signal signal signal ground joined 3.3 V OPEN Pins 1 to 4 are one group and pins 7 to 10 the other. Whichever board is the debugger drives one group and the debuggee drives the other, and neither group is ever driven from both ends, which is what makes this full duplex with nothing to turn around. Pins 5 and 11 are ground and pins 6 and 12 are 3.3 V. A cable for this link joins the eight signal pins and the two grounds and leaves the two supply pins open, because a ribbon that joined them would tie two boards’ regulators together. and a ribbon between two host sockets exchanges the header’s two rows pins 1 to 4 pins 7 to 10 pins 1 to 4 pins 7 to 10 each board’s pins 1 to 4 land on the other’s 7 to 10, in order a connector pressed on the other way up does this, and one was Only the DEBUGGER compensates for it. A debuggee drives the high four pins and listens on the low four whatever it is told, because one end compensating is what straightens a mirrored ribbon and two ends compensating would cross it again.
The connector is Pmod JA on the Arty Z7-20. A board told to be the debugger listens on both groups of pins first, so a ribbon made the wrong way up is found rather than trusted.

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.

FIG. 03 — THE CABLE ON THE PMOD BOARDSMUIR-FPGA
the debug cable on a Pmod JA on the Arty Z7-20, PMOD1 on the Kria KR260; the pin each meets at the far Pmod, on a straight ribbon and on a mirrored one pin 1 debugger strobe Arty JA Y18 Kria PMOD1 H12 straight: pin 1 mirrored: pin 7 pin 2 guard, driven low Arty JA Y19 Kria PMOD1 E10 straight: pin 2 mirrored: pin 8 pin 3 debugger data Arty JA Y16 Kria PMOD1 D10 straight: pin 3 mirrored: pin 9 pin 4 guard, driven low Arty JA Y17 Kria PMOD1 C11 straight: pin 4 mirrored: pin 10 pin 5 ground no package pin straight: pin 5, joined mirrored: pin 11, joined pin 6 3.3 V no package pin OPEN at both ends pin 7 debuggee strobe Arty JA U18 Kria PMOD1 B10 straight: pin 7 mirrored: pin 1 pin 8 guard, driven low Arty JA U19 Kria PMOD1 E12 straight: pin 8 mirrored: pin 2 pin 9 debuggee data Arty JA W18 Kria PMOD1 D11 straight: pin 9 mirrored: pin 3 pin 10 guard, driven low Arty JA W19 Kria PMOD1 B11 straight: pin 10 mirrored: pin 4 pin 11 ground no package pin straight: pin 11, joined mirrored: pin 5, joined pin 12 3.3 V no package pin OPEN at both ends Pins 1 to 4 and 7 to 10 are the eight signals. Pins 5 and 11 are ground and the cable joins them; pins 6 and 12 are each board’s own 3.3 V, and the cable leaves them open at both ends.
Each pin with what it carries, its package pin on each Pmod board, and the pin of the far Pmod it meets on a straight ribbon and on a mirrored one.

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.

FIG. 04 — THE CABLE ON THE DE25-NANOMUIR-FPGA
the debug cable on the DE25-Nano JP1 pins 31 to 38, with the header’s ground on pin 30 — the same eight signals the Zynq boards put on one Pmod the board from above, roughly DC 5 V HDMI MIPI USB-C USB-C Ethernet SW x4 KEY, LED Agilex 5 pins 31–38 pin 11 — 5 V pin 1 JP1 — the manual’s GPIO 0, forty pins pins 39, 40 — the last pair JP2 — the manual’s GPIO 1; nothing here uses it finding it JP1 is the header on the edge between the power jack and the USB sockets. The other edge, with the switches, the buttons and the LEDs along it, carries JP2. Pin 1 is at the power-jack end. Pins 31 to 38 are not at the far end. Pins 39 and 40 are the last pair, so the eight are the four pairs before them: count four pairs back from the end. Pin 30, the ground this cable joins, is the pair before pin 31. The two supply pins are pin 11 and pin 29, and a cable joins neither of them. the twelve pins at that end, at a size that can be read the run from pin 30 to pin 38 is ground, signal, guard, signal, guard, signal, guard, signal, guard, so no two signals are adjacent in the ribbon 3.3 V NEVER JOINED 29 30 ground to the Pmod’s ground debugger strobe to Pmod 1 31 32 guard, driven low to Pmod 2 debugger data to Pmod 3 33 34 guard, driven low to Pmod 4 debuggee strobe to Pmod 7 35 36 guard, driven low to Pmod 8 debuggee data to Pmod 9 37 38 guard, driven low to Pmod 10 not used 39 40 not used odd even PIN 11 IS 5 V AND PIN 29 IS 3.3 V, AND NEITHER IS EVER JOINED TO ANYTHING. ONLY THE GROUND ON PIN 30 IS JOINED. Two boards’ regulators tied together is not something either of them is built for, and a manufactured ribbon joins every conductor unless it is stopped. Neither supply pin is a fabric pin, so nothing in this design can drive one either. The guards are a decision and not a measurement. On the Zynq boards the maker’s schematics show those pins routed as coupled pairs; no schematic is published for this board and its manual says nothing about how JP1 is routed, so the arrangement was carried across because it is what the other two boards run. If a cable here ever misbehaves, that is the first assumption to revisit. No such cable exists. The far end is a Pmod and this end is a 2x20 header, and nobody has made the adapter. The connector is built, linted and read by a check, and nothing of it has run on hardware.
The drawing answers the three questions somebody holding wire has: which of the board’s two headers, which end of it, and which pins must never be joined. Its notes say why the guards are there and that no such cable has been made.

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.

FIG. 05 — ONE FRAME, ON THE WIREMUIR-FPGA
one frame on the wire one strobe and one data line each way, twenty-four beats, and the gap after them marker 01 parity the payload: twenty-one bits, the most significant first strobe data 0 0 1 1 P 2 20 3 19 4 18 5 17 6 16 7 15 8 14 9 13 10 12 11 11 12 10 13 9 14 8 15 7 16 6 17 5 18 4 19 3 20 2 21 1 22 0 23 the gap 18 ticks Six ticks a beat, and eighteen of silence after the last. Any interval longer than twelve ticks with no transition is between frames, so the next transition after it is beat zero. That costs no wire and no slot, and it puts a receiver that has just come up back in step within one frame. The snapshot is taken once, at the first beat, and the receiver moves its outputs once, at the last, so a frame is presented whole or not at all. A carrier that delivered a frame bit by bit would hand back every hazard the cable has no defense against: a late address bit makes the wrong strobe, a late data line is latched instead of the intended word, and a write flag that moves inside a request inverts the cycle.
One signal to a pair of pins, the partner driven low as a guard: twenty-four beats, 162 ticks, a fraction of the 11.05 microseconds a debug cycle is allowed.
FIG. 06 — WHAT CROSSES, EACH WAYMUIR-FPGA
what the frame carries the debugger’s frame: twenty of MIT’s signals, and one bit that is the carrier’s own role -DEBUG IN REQ DEBUG IN WR DEBUG IN A<1:0> DBD<15:0> 20 19 18 17-16 15-0 the debuggee’s frame: nineteen of MIT’s, one of the carrier’s, and one spare role spare, sent as 0 DEBUG IN ACK which bytes of DBD this end is driving DBD<15:0> 20 19 18 17-16 15-0 The fields are drawn to the space their names need rather than to their width in bits. The two byte-drive bits are the return’s own. MIT’s cable carried the byte nobody drives on its pull-ups, and a ribbon has none, so the resolution is made at the debugger’s end instead: a byte nobody drives arrives as ones, which is what an open cable reads as. The role bit is neither MIT’s nor the machine’s. It says whether the board that sent this frame is the debugger, and two idle boards use it to tell each other apart.
Twenty of MIT’s signals cross one way and nineteen the other. The twenty-first bit each way is the carrier’s own, and it is how two debuggees know neither is a debugger.

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.

WhatHow it was shownShown
The machine halted, and its registers readCC through the register window, each register equal to the console’s reading of the same haltyes
The scratchpadsCC’s reads over the window, equal to the console’s readout of the same wordsyes
Main memory, through the mapWords 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 microcycleyes
The ribbon between two boardsThe role taken and given back on a real cable between two Pmod JA connectors, the far end answeringyes
A mirrored ribbon, found by the fabricThe board told to connect reported the crossover it had found; forced the wrong way round, nothing answeredyes
Two idle boards on that ribbonBoth read a debuggee with nothing driving the connector; the role bit tells the two apartyes
Neither machine noticingBoth boards ran Lisp throughout, at the rate they run at with no cable in themyes
CC over the ribbonHalted, read and started again, both ways round, every word equal to the far board’s own console and readoutyes
Every microcycle accounted forThe far machine’s cycle counter moved by one for each scratchpad read, and the debuggee’s own window saw no request at allyes
The guards, and the frames refused0 refused in twenty-four readings; two frames on the other board are unaccounted foryes
A debug cycle over the guarded carrierA status read typed at the debugger’s Listener, both ways round; no register of the far machine crossedyes
CC over the guarded carrierAll 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 runyes
A write over the ribbonMD 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 spentyes
The Kria KR260’s connectorNothing. No ribbon has joined PMOD1 to another board, so its eight pins have crossed nothing; the console reads a debuggee on it with nothing attachednot yet
The DE25-Nano’s connectorNothing. 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 mapnot 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.

FigureRead from
the same cable in the fabricrtl/machine/cadr_dbgin.sv, cadr_busint_regs.sv, rtl/plumbing/cadr_debug_window.sv, cadr_dbg_join.sv; docs/console.md
the cablertl/plumbing/cadr_dbg_cable.sv, and each board’s own .xdc, whose pins come from Digilent’s published files
the cable on the Pmod boardsboards/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-Nanoboards/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 wirertl/plumbing/cadr_dbg_tx.sv and cadr_dbg_rx.sv: the marker, the parity, the beats and the gap
what the frame carriesrtl/plumbing/cadr_dbg_cable.sv, which packs both frames in one expression, counted off BUSINT.netlist