Expand description
fabric_pipe — the compiled residual circuit cut into register stages: a new input every clock, a short period.
fabric_rtl lowers a dispatch-free residual to a dataflow circuit that resolves in one clock,
so its period is the propagation delay of the whole residual (for the Horner polynomial, two chained 64-bit
multiplies and three carry chains). This module keeps the same op vocabulary and pipelines that circuit:
- Carry-save lowering (
carry_save_lower). Every additive tree (theAdd/Sub/Mulops a value is built from, through intermediates read exactly once) becomes one set of rows. A variable multiply contributes one masked, shifted copy of its multiplicand per multiplier bit; a constant multiply one shifted row per canonical signed digit; a subtraction the inverted rows plus their +1s; constants fold into a single row. A tree of 3:2 compressors reduces the rows to two, and one Kogge-Stone carry-propagate add resolves them. The lowered circuit holds only bitwise ops and constant shifts, so no op is more than one gate deep and a register can sit between any two of them. - Scheduling (
schedule_pipeline). Ops take the earliest stage whose accumulated depth stays within a per-stage budget, in the units ofop_delay. Wiring (is_wiring: a constant shift, or a bitwise op with a constant) has no depth and no stage of its own: each reader rebuilds it from its operand’s register, so only computed values cross registers. - Emission (
emit_fabric_pipelined_verilog). Inputs register into stage 0 (Inputs::Registered), or stage 0 reads the ports the registers upstream hold (Inputs::Ports); each value is delayed through as many registers as stages separate it from its last reader, and the result registers after its stage. The result of the input presented before clocktis onresultafter clockt + latency - 1.
simulate_pipeline is the cycle model of exactly those registers, so a schedule is checked without a simulator,
and the lowering takes a width so our SAT can check it exhaustively at a narrow one.
Structs§
- Pipeline
Schedule - Where every op of a residual computes, and which op leaves the pipeline.
Enums§
- Final
Add - How the two words a sum’s compressor tree leaves are added.
- Inputs
- Where a pipeline’s first stage reads its inputs.
- SumSharing
- How a sum that other sums read is lowered.
Constants§
- DECISION_
CELLS_ BUDGET - The stage budget a decision is cut to on standard cells, in the units of
op_delay: three carry chains and their selects. A register is ~20 µm² of flip-flop a bit there, where on a fabric it rides in a LUT’s slice, so a decision takes few stages and reads its ports (Inputs::Ports); each compare takes the sums it reads into its own rows (SumSharing::Fold), resolved by one add synthesis picks (FinalAdd::Native). MEASURED (2026-10-18, K1’sdecideso lowered, its ports read, Sky130 HD: yosys 0.33 with OpenLane v1’sDELAY 0ABC script at a 2 ns target, OpenSTA at the typical corner, no wires): 18 = 5 stages, 44,306 µm² at 4.65 ns; 30 = 3 stages, 34,005 µm² at 3.57 ns; 36 = 2 stages, 30,843 µm² at 5.03 ns; one stage, 32,013 µm² at 7.71 ns. Without the folds, 27 and 30 were 32,750 µm² at 4.10 ns and 31,559 µm² at 4.34 ns. - DECISION_
CHAIN_ BUDGET - The stage budget a decision is cut to on a fabric with carry chains, in the units of
op_delay: one unlowered add or subtract (a carry chain, 9) and an AND. The XORs that finish a compare’s sign start the next stage, so the mask a select fans out to its 64 bits leaves a register, never the end of a carry chain. MEASURED (2026-10-17, K1’sdecide, Artix-7 fabric map, yosys 0.33 synth_xilinx + nextpnr-xilinx, seeds 1-3, median): 12 (the compare and its select in one stage) = 852 LUTs at 119.2 MHz, 10 = 848 at 147.3, 9.6 = 784 at 145.4, 6 = 848 at 147.8; at 8 and 9 one seed in three does not finish routing within 300 s. - FOLD_
ROW_ LIMIT - The words a folded sum may bring into each reader’s rows; a larger sum resolves once and is read as one word.
- GEMM_
MUL_ BITS - The int8 width of the GEMM array’s multiply tiles.
- GEMM_
TERM_ BUDGET - The term stage budget of the GEMM array, in the units of
loop_cell_delay: the operand arithmetic in one stage, the int8 multiplies in the next. - HORNER_
SEQ_ BUDGET - The stage budget
fabric_horner_seqis cut to, in the units ofop_delay. MEASURED (2026-10-17, the synthesis sequence of OpenLane’s synth.tcl under host yosys 0.33, AREA 0, abc target 1 ns, sky130_fd_sc_hd tt_025C_1v80, worst stage by abcstime): budget 4 is 1.36 ns over 311,772 µm² of cells, 5 is 1.43 ns over 258,289 µm², 6 is 1.99 ns, 7 is 2.65 ns; the single-stage residual is 13.85 ns. Five is the knee: the next tighter budget buys 5% of period for 21% more area.
Functions§
- carry_
save_ lower - Carry-save lowering of a residual at datapath width
width(64 on silicon; narrower so our SAT can check the lowering exhaustively), each shared sum resolved once (SumSharing::Resolve). Only the values the result depends on are lowered. Returns the new op list, which holds noAdd,SuborMul, and the index of its result. - carry_
save_ lower_ with carry_save_lowerwith the shared sums lowered assharingsays and each compressor tree’s last two words added asfinal_addsays. UnderSumSharing::Foldan add or subtract read only by adds and subtracts never resolves, however many read it, and one its rows fold into resolves only for its other readers; a multiply read more than once still resolves once. UnderFinalAdd::Nativethe lowering holds oneAddper resolved sum and nothing else additive.- csd_
digits - The canonical signed digits of
cmod 2^width:(shift, ±1)pairs whose signed sum of powers of two isc, no two adjacent. The top digit is taken positive, since ±2^(width-1) agree mod 2^width. - decision_
ops - A decision fabric (
decision_fabric_from_source: arithmetic cells and compare-selects) as a residual in the pipeline’s op vocabulary, and the index of its result. A compare becomes the mask of its outcome, all ones or zero (compare_mask); a select ise ^ ((t ^ e) & mask). Every op is emitted once, so a predicate many selects test has one mask. A fabric with any other cell (a functional unit, a memory or heap tile) has no combinational form and is refused. - dot_
unrolled_ source - The
u-wide unrolled int8 dot product in LOGOS: each iteration accumulatesuindependent products, so the compiler placesumultiply tiles that fire together,uMACs per clock. - earliest_
schedule - Every computed value in its earliest stage: the shortest pipeline whose stages each stay within
budget. - emit_
csa_ multiplier_ verilog - A parameterized Verilog module
{module}: an unsigned AW×BW multiplier as a tree of 3:2 compressors over its partial-product rows, registered after CUT tree levels and (with FINAL) once more before a Kogge-Stone final add. One generator for every consumer, so the BigInt limb multiplier and the FPU carry the same tree under their own names. - emit_
fabric_ pipelined_ verilog - Emit the scheduled residual as a pipeline: module
fabric_{name}with portsclk,in0.., and the registeredresult. Every assignment is its own net, so no operator’s signedness leaks into another’s. - emit_
horner_ seq_ verilog benchmarks/silicon/fabric_horner_seq.v: the RTL the flow hardens asfabric_horner_seq.- gemm_
mac_ array_ verilog benchmarks/silicon/gemm_mac_array.v: the eight-wide int8 MAC arraycgra_arr8as the pipelined loop CGRA (operands, then products, ahead of a carry-save accumulator), with its pin-light top.- horner_
seq_ pipeline - The residual
fabric_horner_seqhardens: the REAL compiler’s residual of the Horner polynomial (POLY_BODY), carry-save lowered at 64 bits and cut toHORNER_SEQ_BUDGET. - is_
wiring - Wiring costs no logic depth: a shift by a constant moves bits, and a bitwise op with a constant operand is constant bits or inverters. It takes its operands’ stage, and each reader rebuilds it from their registers.
- known_
bits - The bits of each value its construction fixes, as (mask of known bits, their values): shifts bring in zeros, masks and constants pin bits, a carry row’s bit 0 is zero. A register on a known bit holds a constant, which synthesis removes, so a schedule is charged only for the live bits it holds.
- latest_
schedule - Every computed value in its latest stage of that same shortest pipeline.
- matmul_
array_ top - A pin-light top for a MAC array’s CGRA
cgra_{name}, so placement and routing measure the array’s paths rather than its I/O: a serial input shifts into the loop bound, the finished result latches, its parity drives one pin. - op_
delay - The logic depth of one op, in units of a two-input XOR at the synthesis corner. Wiring is zero. A carry chain or a multiplier left unlowered is one indivisible op, so it occupies a stage of its own whatever the budget.
- schedule_
pipeline - Cut a residual into the shortest pipeline whose stages each stay within
budget(in the units ofop_delay), placing every computed value so the pipeline holds the fewest live register bits. An op deeper than the budget on its own still gets a stage, alone. - simulate_
pipeline - The cycle model of the emitted pipeline. Before each clock
tthe input vectorstream[t]is presented; the returned vector holds the result register after each clock. Registers start at zero.