Skip to main content

Module qor_harness

Module qor_harness 

Source
Expand description

qor_harness — the measurement harness of the comparative-synthesis bench.

Every candidate implementation of a kernel (LOGOS’s own RTL, an HLS tool’s output, a third-party design) is measured inside the same generated wrapper, qorbist_<candidate>(clk, rst, sig):

  • Stimulus. A 64-bit xorshift state (13, 7, 17) seeded with SEED advances once per operation the candidate accepts. Each input field reads its own lane word (lane_word: a rotation of the state XOR a per-lane constant) and shapes it into the kernel’s declared domain (Field). Values never depend on the candidate’s timing, so every candidate of a kernel sees the same operand sequence.
  • Signature. Each result the candidate produces folds into a 64-bit MISR (misr_step over fold). The MISR advances on result-valid only, so the signature is independent of latency, initiation interval and stalls: two candidates of one kernel are functionally equal on the stimulus exactly when their signatures are, and both must equal the golden signature the LOGOS VM (or the oracle the RTL generator is locked to) predicts.
  • Boundary. The candidate is instantiated under (* keep_hierarchy *) as u_dut, so synthesis cannot fold the shaped stimulus into it and its area and power are reported for that instance alone. An input its binding does not name is held at 0, never left floating. The wrapper exposes only clk, rst and a 16-bit sig, which is what the gate-level power flow drives.

A kernel is a Kernel contract (ports, widths, domains, golden); a candidate is a Candidate (top module, clock, reset, Protocol, and a port binding). check_ports refuses a binding that does not fit the DUT’s real ports before any harness is emitted.

Structs§

Bind
Contract bits [lsb, lsb + width) of port contract connect to DUT port dut. Several binds to one input DUT port concatenate, the first in the least significant bits; an input DUT port wider than what is bound to it is sign-extended when the topmost bound contract field is signed, else zero-extended. An output DUT port contributes its low width bits.
Candidate
One implementation of a kernel, as the harness drives it.
DcrBus
A device’s configuration-register port: valid with rw high writes data to register addr; with rw low it reads, and the device answers on rsp_valid.
DcrWrite
One configuration-register write.
Drive
DUT input dut takes value in beat beat of every call; a port is 0 in the beats that do not drive it.
DutPort
A port of the DUT’s top module, as its netlist declares it.
Field
How one 64-bit chunk of an input port is drawn from its lane word: lanes packed sub-lanes of width bits each. A single-lane field is base + slice (sign-extended when signed) as a 64-bit value; a packed field (lanes > 1) carries no offset and packs each sub-lane’s raw slice.
ImageLine
One constant line of a device’s memory (a program image): its line address and its bytes in hex, the byte at the highest address first.
InPort
An input port of a kernel contract: bits wide, one Field per 64-bit chunk (least significant first). A port with hold > 1 (a power of two) keeps the value drawn at its first operation for hold operations — a weight tile reused across rows.
Kernel
A kernel of the bench: its contract and its golden.
LineBus
The memory a device reads and writes whole lines of, served by the harness over ports channels: each a request (<prefix>_req_valid, _rw, _byteen, _addr — a line address — _data, _tag, _ready) and a read response (<prefix>_rsp_valid, _data, _tag, _ready); a write has no response. Each signal carries every port’s value side by side, port 0 in the most significant bits when msb_first. The harness accepts every request and answers each read in order on its port from the next cycle on, with the line as it is when answered: an ideal memory, never a candidate’s bottleneck.
LineRegion
Lines of a device’s memory holding contract ports from line base_line on: the listed ports in order, each as words_per_port words, packed from the region’s first byte. An input region answers reads with the call’s operands; an output region keeps the device’s writes.
Manifest
ManifestEntry
A third-party candidate: the harness-facing description, the tool (a key of scripts/qor/qor-tools.toml), the source it read and the exact command that generated its files.
ManifestFile
One generated RTL file of a third-party candidate and the SHA3-256 of its bytes.
ManifestRefusal
A candidate a tool would not build — its crash, its error, or its deadline — kept in the manifest so the comparison prints a refusal in that cell rather than a silent gap.
MemBind
Contract ports carried through a memory interface instead of scalar ports. The memory’s words are the listed contract ports in order, each split into words_per_port words (least significant first), so one wide port can become an array and several ports one array.
OutPort
An output port of a kernel contract.
RegSlot
One cycle of a register-file transfer: contract bits [lsb, lsb + width) of port contract.
Reset
A DUT reset input.
Run
A finished testbench run: results folded, the signature, total cycles, the cycle the first result was folded on, and the (ops, cycles) mark at half the run.

Enums§

Dir
A DUT port’s direction.
DriveValue
What a beat schedule drives onto one DUT input port in one beat.
Golden
The reference a kernel’s results are checked against.
MemKind
The memory protocol a MemBind speaks.
Mode
Which values a field draws: uniformly over its domain, or only its two ends.
Protocol
How the harness hands operands to a candidate and collects its results.
QorError
Why a harness, golden, or run was refused.
SourceKind
Where a kernel’s LOGOS candidate comes from: compiled from a LOGOS program by the compiler, or written by one of the RTL generators in this module tree.

Constants§

GEMM_ACC_BITS
The accumulator width every GEMM candidate’s output carries.
GEMM_BITS
GEMM_DIM
GEMM tile rows and columns, and the operand width.
GEMM_MATCHED_ACC_BITS
The narrower accumulator Gemmini’s default configuration gives its mesh (spatialArrayOutputType SInt(20)): wide enough for every sum of eight int8 products, so the matched rows compute the same results with less state.
K6_PORTS_EVERY
The K6 ports engine’s register placement: a register after every K6_PORTS_EVERY-th level of each lane’s multiply tree and after its last (simt_ports). MEASURED (2026-10-18, Sky130 HD: yosys 0.33 with OpenLane v1’s DELAY 0 ABC script at a 2 ns target, OpenSTA at the typical corner, no wires; a step every clock throughout): every level = 536,394 µm² at 3.35 ns and 8 clocks; every second = 488,462 at 3.86 and 5; every third = 468,797 at 5.10 and 4; the product only = 437,985 at 8.30 and 3; no register in the tree = 423,320 at 9.27 and 2. Every second is within 5% of every level in steps a second per area, with 39% of its flip-flops and three clocks fewer.
K6_STREAMED_EVERY
The streamed K6 engine’s register placement: a register after every K6_STREAMED_EVERY-th level of its multiply tree (LaneArith::Streamed). MEASURED (2026-10-17, Artix-7 fabric map, yosys 0.33 synth_xilinx + nextpnr-xilinx, median of the seeds that routed): every level = 3421 LUTs at 128.2 MHz and 24 clocks an operation, 1.56 million results a second per thousand LUTs; every second = 3403 at 106.6 MHz and 21 clocks, 1.49; every third = 3394 at 90.7 and 20, 1.34; the whole tree in one stage = 3387 at 63.7 and 19, 0.99. Fewer registers hold half (every second) to a quarter (one stage) of the flip-flops.
LANE_MIX
The per-lane constant multiplier: lane k XORs k · LANE_MIX into its rotated state.
MANIFEST
The manifest of third-party candidates.
SEED
The stimulus state after reset.
SIMT_LANES
SIMT lanes of the K6 engine.

Functions§

advance
The stimulus state n steps after s.
beat_capture_depths
The results each slot of a beat schedule must be able to hold. The harness folds one result per cycle in operation order, so a slot whose result arrives while an earlier slot of its call is still outstanding waits — and when the call after it delivers that slot again before the fold reaches it (results handed back last first), the slot queues two. Found by running the schedule itself: slot j of call n is captured at n * period + captures[j] and folded once every earlier result has been. A schedule that brings more results per call than a call has cycles outruns the fold and is refused.
check_ports
Refuse a candidate whose binding, clock, reset or protocol ports do not fit its DUT’s ports.
contract_ref
A contract reference port or port@j: the port and the batch slot (operation j of the batch a batched candidate takes per call).
emit_fold_wrapper
The synthesis wrapper qorsyn_<name>(clk, rst, sig) of a design measured without a functional contract (a memory controller, whose functional gate is a board memtest): every input of top from a register the seeded xorshift64 stimulus refills each cycle, one rotated lane word per 64 bits as the harness draws operands; every output bit folded into a registered 64-bit XOR whose low 16 bits are sig; the design kept whole as u_dut, so its cells and its register-to-register paths are what synthesis and place-and-route measure.
emit_harness
The wrapper qorbist_<candidate>(clk, rst, sig) around c for kernel k in mode. Call check_ports first: the wrapper assumes the binding fits.
emit_harness_as
emit_harness as the module name — the harness hardened as a block of its own, whose top module the flow names after the block.
emit_pass_wrapper
The power block <name> of a design measured without a functional harness — a memory controller, driven at gate level by the K7 traffic testbench: its clock and reset renamed clk and rst (active high), every other port passed straight through under its own name, the design kept whole as u_dut, so the flow’s cells are told apart from its own. A port named clk or rst that is not the clock or reset would collide, and is refused.
emit_testbench
A testbench that resets the harness for five cycles and runs it until ops results are folded. It prints QOR first cycles <n> when the first result is folded, QOR mid ops <n> cycles <n> at half the run, and QOR ops <n> misr <hex> cycles <n> at the end; an unknown MISR bit prints QOR X op <n> and stops. Two watchdogs end a run that cannot finish: max_cycles in all (QOR TIMEOUT ops <n>), and max_idle cycles without a folded result (QOR TIMEOUT idle <max_idle> cycles ops <n> cycle <n>), which refuses a candidate that has stopped answering long before the whole budget would.
emit_testbench_as
emit_testbench around the harness module m — one emitted by emit_harness_as.
emit_trace_testbench
emit_testbench’s run with every folded result printed as QOR r <op> <port hex>... (kernel output order, each port in hex at its contract width), for locating the first operation a candidate gets wrong.
emit_trace_testbench_as
emit_trace_testbench around the harness module m — one emitted by emit_harness_as.
fold
One result folded to 64 bits: chunk c (counted across ports in order) rotated left by c.
gemm_os_candidate
The LOGOS output-stationary GEMM array streaming one tile every GEMM_DIM beats: beat t carries lane t of every row’s activations and weight row t, the first beat raises first, and row i of a tile is read os_streaming_result_offset cycles after its first beat.
gemm_os_candidate_acc
gemm_os_candidate with acc_bits-wide accumulators (each sum sign-extended onto its output port), named for the width when it is not the contract’s.
gemm_ws_candidate
The LOGOS weight-stationary GEMM tile with run-time weights on the K3 beat schedule of period period: load the tile’s weight rows, stream its activation rows, drain; row t’s result emerges pipelined_latency cycles after its activation.
gemm_ws_candidate_acc
gemm_ws_candidate with acc_bits-wide accumulators (each sum sign-extended onto its output port), named for the width when it is not the contract’s.
gemm_ws_period
The period of one weight-stationary call: GEMM_DIM weight-row loads, GEMM_DIM activation rows, then the drain until the last row has passed every column — the weights live in the PEs, so the next call’s loads must wait for it.
golden
The golden results of k over stim.
harness_module
The harness module’s name for c.
jump_rows
The 64×64 GF(2) matrix of n stimulus steps as rows: bit i of advance(s, n) is the parity of s & rows[i] (xorshift is linear, so n steps are one matrix).
kernel
The kernel with id id.
kernels
The kernels of the bench, in id order.
lane_word
The 64-bit word input lane k reads from state s.
logos_candidate
The LOGOS candidate of kernel id: its harness-facing description and its Verilog files (file name, contents). K1, K2 and K6 are compiled from their LOGOS programs; K4 and K5 come from the RTL generators; the remaining kernels’ candidates are built by their own protocols.
logos_candidates
Every LOGOS candidate of kernel id, the default first. K1 has the decision fabric in registers, sequenced one cell a cycle, pipelined one carry chain to a stage for a fabric with carry chains (fabric_pipe::decision_ops, DECISION_CHAIN_BUDGET), pipelined for standard cells (each compare’s sums folded into it, DECISION_CELLS_BUDGET, its ports read), and hoisted into one clock (select_hoist, its sums folded into the compares that read them, its ports read). K4 has the Keccak core a round a clock and a half round a clock (keccak_core_half). K2 has the residual in registers, sequenced one cell a cycle, and pipelined (fabric_pipe, the RTL the fabric_horner_seq block hardens). K5 has the butterfly in registers and its pipeline registered once a multiply and after every step. K6 has one per lane multiply strategy: the sequential shift-add (the signoff-clean default), the two-stage decomposed FMA, the single-cycle combinational multiply and the streamed shared multiply, and the engine’s step on ports (simt_ports).
manifest_candidate
Read manifest entry name under root and its files, refusing any file whose bytes no longer hash to the recorded SHA3-256.
misr_step
The MISR update: shift left with the parity of the old state fed back, XOR the folded result.
next_state
One step of the stimulus generator: xorshift64 with shifts 13, 7, 17.
parse_run
The verdict a testbench printed.
read_manifest
The manifest under root.
sha3_hex
The lowercase hex SHA3-256 of bytes.
signature
The signature of a result sequence.
stimulus
The operand values of the first ops operations of k in mode.
trace_lines
The golden results of results as emit_trace_testbench prints them: one line per operation, <op> <port hex>..., each port in hex at its contract width.

Type Aliases§

Words
One operation’s values: per port, per 64-bit chunk.