Skip to main content

Module terminal_protocol

Module terminal_protocol 

Source
Expand description

The Fabric Terminal’s wire protocol and screen, in one place: the link between a host and the terminal board (Board B, the Nexys A7-100T) that puts a LOGOS editor on a VGA screen, takes a keyboard on the board’s USB port, and runs each program on the fabric engine beside them.

The link is one UART, its bytes framed by SLIP (RFC 1055): a frame ends with SLIP_END, and an END or SLIP_ESC inside a frame travels as ESC + SLIP_ESC_END / SLIP_ESC_ESC. A receiver that starts mid-frame, or loses a byte, is back in step at the next END. A frame’s first byte is its kind: host kinds travel host → board, board kinds board → host.

The screen is text: COLS × ROWS cells of 8 × 16 pixels on 640 × 480 at 60 Hz. A cell is 16 bits — glyph (7 bits), blink, foreground and background from the 16-colour PALETTE — addressed row << 7 | col, so no multiply sits in the pixel path. The bottom PANEL_ROWS rows belong to the activity panel the board draws itself from the engine’s probes; text written there is covered.

Every byte and dimension the RTL uses is filled into its templates from here by fill_verilog, and a host that is not Rust reads table_json (fabric_terminal --table). Nothing restates a value.

Modules§

board
Frame kinds a board sends.
host
Frame kinds a host sends.

Structs§

Cell
One cell: its attribute and glyph bytes as they travel and as the text buffer holds them.
SlipDecoder
A SLIP receiver: bytes in, whole frames out. An empty frame (two ENDs in a row) is no frame; an ESC followed by anything but ESC_END / ESC_ESC drops the frame it is in.

Constants§

ACTIVITY_FIELDS
board::ACTIVITY’s payload, field by field: (name, bytes each, how many), every count big-endian. The per-block and per-cell clocks are one count per block slot and per cell slot of Board B’s engine.
BAUD
The link’s baud rate: 100 clocks per bit at the board’s 100 MHz, and FTDI’s 3 MHz base divided by 3, so both ends run it exactly.
BOARD_HZ
The board clock in Hz.
CLOCKS_PER_PIXEL
COLS
Text columns.
DEL_GLYPH
The character slot 0x7F holds.
ENGINE_CLKS_PER_BIT
ENGINE_CLOCK_DIVIDER
The fabric engine’s clock divider from the board clock, and its UART’s clocks per bit: the board feeds the engine’s loader through an internal UART at BOARD_HZ / ENGINE_CLOCK_DIVIDER / ENGINE_CLKS_PER_BIT baud.
ENGINE_FRAME_MAX
The most engine bytes one host::ENGINE frame carries: the board’s engine FIFO holds one frame.
FEATURE_ENGINE
board::PONG’s feature bit for an image with the fabric engine: ENGINE frames reach an engine that answers. Without it (the screen-and-keyboard shell) ENGINE bytes are taken and dropped.
FEATURE_SMALL
board::PONG’s feature bit for an image with the small-text plane and host::WINDOW.
FEATURE_TOTALS
board::PONG’s feature bit for an image that keeps the run’s totals: host::TOTALS is answered.
FONT8_ROWS
The small font: glyph g’s row r is row FONT8_ROWS[r] of g in the 8×16 font — the rows that keep its round letters round, its digits whole and its box-drawing lines joined from one small row to the next.
GLYPHS
Glyphs in the font ROM: a cell’s glyph field is 7 bits.
GLYPH_ROWS
Glyph height in pixels (width is 8).
HEAT
The heat ramp a tile or square is painted with, by level: level k means the block or cell ran between 2^(k-1) and 2^k - 1 engine cycles in the last frame (level 0: not at all) — a frame holds at most panel_frame_samples engine cycles, so 14 is the hottest a frame reaches. Dark blue through cyan, green, yellow and orange to red.
H_TIMING
640 × 480 at 60 Hz: (visible, front porch, sync, back porch) per axis in pixels / lines, sync active low, one pixel per 4 board clocks (25 MHz; monitors lock to it within the standard’s 0.7% of 25.175 MHz).
PALETTE
The 16 colours a cell can name, as the board’s 4-bit-per-channel DAC drives them (0xRGB), in CGA order.
PANEL_BLOCK_COL
PANEL_BLOCK_ROW
PANEL_BLOCK_TILE
PANEL_CELL_COL
PANEL_CELL_ROW
PANEL_CYCLES_COL
PANEL_DIGIT
PANEL_GAUGE_UNLIT
PANEL_HEAP_COL
PANEL_HEAP_LIT
PANEL_LABEL_ROW
PANEL_OUTLINE
The panel’s other colours (0xRGB): the outline of the tile or square the engine is in, the cycle digits, and the gauges’ lit and unlit segments. Everything else in a panel region is black.
PANEL_ROWS
Rows at the bottom that the activity panel draws over.
PANEL_STACK_COL
PANEL_STACK_LIT
PANEL_TITLE_ROW
The activity panel, drawn by the board from the fabric engine’s probes over the bottom PANEL_ROWS rows. The host writes the panel’s text (title, labels) as ordinary cells; the board paints its graphics over the cells named here, every frame, with nothing from the host:
PONG_FIELDS
board::PONG’s payload, a byte each in this order; a two-byte count is high byte first.
PS2_FRAMING_ERROR
A PS/2 frame whose start bit was not 0 or stop bit not 1.
PS2_NO_ACK
A host-to-device byte the device never acknowledged.
PS2_PARITY_ERROR
A PS/2 byte whose odd parity did not hold.
ROWS
Text rows.
SLIP_END
SLIP frame delimiter.
SLIP_ESC
SLIP escape.
SLIP_ESC_END
An END inside a frame, after ESC.
SLIP_ESC_ESC
An ESC inside a frame, after ESC.
SMALL_COLS
SMALL_FIRST_ROW
The small-text plane: text-buffer rows SMALL_FIRST_ROW..SMALL_FIRST_ROW + SMALL_ROWS, of which columns 0..SMALL_COLS hold cells. PUT, FILL and READ address them like any row; host::WINDOW puts them on screen.
SMALL_ROWS
TOTALS_FIELDS
board::TOTALS’s payload, field by field, as ACTIVITY_FIELDS is laid out.
UI_GLYPHS
The characters the font holds below the printable range, slot i holding character i: light and double box lines, blocks and shades, arrows, markers and a tick — what a terminal UI draws with. Slots 0x20–0x7E are ASCII and slot 0x7F holds DEL_GLYPH. A host maps a Unicode character to its slot by this table, and scripts/dev/gen-terminal-font.py builds the font ROM by it.
VERSION
The protocol’s version, as board::PONG reports it.
V_TIMING

Functions§

activity_bytes
The length of board::ACTIVITY’s payload.
cell_address
A text-buffer address: row << 7 | col.
clocks_per_bit
Clocks per UART bit on the board for BAUD.
fill_verilog
Fill a terminal Verilog template from this module: __V_<NAME>__ becomes a byte as a Verilog literal (8'hC0), __X_<NAME>__ the hex a comment quotes (0xC0), __N_<NAME>__ a decimal number, __C_<NAME>__ a colour (12'hFFF), __PALETTE_CASE__ the palette as case arms (4'd1: palette = 12'h00A;), __HEAT_CASE__ the heat ramp the same way, and __DIGIT_ROM_CASE__ the font’s digit glyphs keyed {digit, row}. Panics on a placeholder this module does not define, so a template cannot name a value nobody owns.
glyph_slot
The font slot that draws ch: ASCII as itself, UI_GLYPHS and DEL_GLYPH by their slots, anything else as ?.
heat_level
The heat level a count of engine clocks paints: its bit length.
panel_frame_samples
The most engine clocks one frame of the activity panel can count: snapshots are a frame apart on the engine’s clock, so a frame’s counts span a frame’s board clocks over ENGINE_CLOCK_DIVIDER, plus the one sample a snapshot can slip by.
slip_encode
One frame as SLIP puts it on the wire: the escaped bytes, then END.
table_json
The whole protocol as JSON, for a host that is not Rust.
totals_bytes
The length of board::TOTALS’s payload.
verilog_numbers
The integer parameters the RTL takes from here: __N_<NAME>__ becomes the decimal number.