Skip to main content

Module frontier

Module frontier 

Source
Expand description

Sign / verify throughput frontier on one device.

Signing and verification share the chip: every field machine, ring and block RAM spent on one is unavailable to the other. This module counts both against the same LUT, DSP, BRAM and URAM limits and returns the Pareto frontier of (signatures/s, verifications/s).

Sign vs verify on one U280: 420k LUT, 205 MHz (model from Vivado block costs) 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 signatures per second (millions) verifications per second (millions) 5M sign minimum 5M + 5M target known-key, projected BRAM cuts known-key, as built batch (model), projected strict, projected strict, as built Each step is a buildable split of the chip between signing and verify machines; no point above a curve fits.

Key points at 420k LUT (signatures/s, verifications/s). As built uses the measured block costs; projected applies the BRAM reductions of slimmed_costs. As built, the frontier is BRAM-bound (about 1,965 of 2,016 BRAM36), so 350k and 420k LUT give the same points.

ModeAs built, ≥ 5M signProjected, ≥ 5M signProjected, equal rates
strict5.07M / 0.46M5.07M / 1.04M1.52M / 1.37M
known-key5.07M / 2.27M5.07M / 4.03M4.57M / 4.28M
batch (model)5.07M / 1.07M5.07M / 2.29M2.99M / 2.91M

Every point, budget and mode is in docs/frontier.csv (regenerate with cd tools/hostmodel && cargo test --offline frontier_csv).

§Block costs

vivado_costs are Vivado 2023.2 out-of-context synthesis numbers for the blocks of profile 15/11/3/1 (hierarchical utilization, 205 MHz target). Verify-only blocks that are not built yet are derived from them and marked in their names.

§Verification modes

ModeField multiplies per verificationWhat it checks
VerifyMode::Strict~3,050 bundlesfull strict verification of any key: decode A, [S]B, variable-base [k]A, encode and compare
VerifyMode::KnownKey775 bundles (compiled)the same checks for keys whose tables were loaded in advance: [S]B and [k]A both as fixed-base walks
VerifyMode::Batch~1,300 (model)random-linear-combination batches; may differ from strict on crafted inputs

Every mode also needs two SHA-512 blocks and one scalar job per verification, and the result point is encoded by a batch-compress machine. The bundle counts are program models until the verify programs are compiled; VerifyMode::bundles is the single place to update them.

§Two planners

frontier enumerates every sign build and every verify build that fits the whole Device and keeps the non-dominated pairs. plan_system instead splits a SystemBudget into two fixed Shares and picks the fastest build inside each share independently (plan_sign_with, plan_verify_with); it also considers the projected 150-DSP multiplier and an optional shared SHA-512 pipeline.

Structs§

BramLayout
Field-machine costs in the block-RAM (as-built) layout: the fallback for machines that do not fit the UltraRAM layout’s URAM.
Cost
Resources of one block, or a sum of blocks.
Costs
Per-instance block costs used by the frontier and the system planner. Two tables exist: vivado_costs (as built) and slimmed_costs (projected memory layout).
Device
Device limits of the Alveo U280 (XCU280) that frontier packs builds into. All fields except lut are the physical device totals.
ModulePlan
One planned module.
Point
One point: a sign build, a verify build, their rates and total cost.
Shape
How a module’s blocks are proportioned, set from the TUI.
Share
A module’s share of every resource: the limits one module (sign or verify) must fit inside.
SystemBudget
The controls of the system planner: two budget sliders, two power sliders, plus the verification mode and the clock.
SystemPlan
The planned system.
VerifyProfile
A verify-side build: instance counts of each block. One verify controller (and, in known-key mode, one key loader) is always added on top.

Enums§

Compress
Whether a module uses a batch-compress machine.
Multiplier
Which multiplier a module’s field machines use.
VerifyMode
How signatures are verified. Selects the bundle count per verification and which verify field machine is costed.

Constants§

BASE_DSP
DSP budget that the 100 % setting means.
BASE_LUT
LUT budget that the 100 % setting means.
CONST_ROM_LUT
LUTs the constant ROM (machine::ConstRom, fix14) adds to each field machine: a literal and a mux per read port instead of LUT RAM. Routed on the 1,1,1,1 verifier (three field machines: verify, compress, key loader): 84,435 LUT against 82,184 on fix12 (007zzr, 007zzi), so 750 each. One core, so provisional; the signers’ machines hold other constants and are not yet routed on fix14.
FB_IN_CORE_LUT
LUT change of a fixed-base machine inside a whole signing core against the machine routed alone (fitted, see slimmed_costs): synthesis shares or trims logic across the machine’s boundary.
LUT_BANKS_LUT
LUTs that banks M and A of one 32-context field machine cost in LUT RAM (MachineMemory::LUT_BANKS): eight 512 x 255-bit copies (four read ports per bank) plus read muxes. Routed (Vivado 2023.2 OOC, 4.878 ns) on the fix9 RTL (2026-10-18): fb machine 37,440 LUT (+22,825, WNS +0.450), verify machine 36,677 (+22,814, WNS +0.366); the larger delta, rounded up, is used. (Before the timing fixes, 2026-10-16: +22,803 and +23,260; projected at 16,500 before routing.)
SHA_CLIENT_LUT
LUTs of the port from a module to the shared SHA-512 pipeline: request mux, tag, and the credit-counted result FIFO (estimate until built).
SIGN_BUNDLES
Bundles of the signing fixed-base program (for reports).
SMALL_SIGNER_CYCLES
Cycles per signature of the fused small signer with 32 requests in flight (native simulation).
U280_BRAM36
Physical BRAM36 blocks of the XCU280.
U280_DSP
Physical DSP48E2 blocks of the XCU280.
U280_LUT
Physical CLB LUTs of the XCU280 (the hard ceiling for any LUT share).
U280_URAM
Physical URAM blocks of the XCU280.
VERIFY_FUSED_EXTRA
Extra field-machine bundles per verification without a compress machine: the per-point inversion and encoding, as in signing (FUSED_BUNDLES - FB_BUNDLES).
VERIFY_PER_MACHINE_LUT
Verify-controller LUTs per verify machine (dispatch, free-slot word, output offer), fitted from the 6- and 24-machine routed fix9 verifiers; costed with each machine so the controller entry stays fixed. (Fitted at 716 on the 6- and 14-machine verifiers before the timing fixes.)
VERIFY_UTIL
Sustainable utilization of a verify field machine on the known-key program. Measured in native simulation of planned builds on a full SHA line (2026-10-16): 2,0,1,1 ran 387.16 cycles/verification and 4,0,1,1 191.76, i.e. 774 and 767 machine cycles per 775-bundle verification (utilization 1.00 and 1.01 within the 50-90 % window’s error).

Functions§

before_const_rom
The cost table for RTL before fix14 (constant banks in LUT RAM), to compare routed cores of that RTL with the table.
best_verify_at
Best verification rate at or above a signing rate: the frontier point with the highest verifications/s among those with at least min_signs signatures/s. None if no point reaches min_signs.
frontier
The frontier for one verification mode: for each signing rate, the best verification rate that still fits, keeping only non-dominated points. Includes sign-only and verify-only points. Sorted by descending signing rate.
plan_sign
Best signing module within a share, with its own SHA rings.
plan_sign_shaped
plan_sign_with restricted to builds of shape (ratio, batch compression). The fused small signer counts as a build without batch compression and is skipped under a manual ratio.
plan_sign_with
Best signing module within a share; with shared_sha the module has no SHA rings and sends its three blocks per signature to the shared SHA-512 pipeline (a client port instead of rings, sha = 0 in the profile).
plan_system
Plan both modules for the budget controls. Each module is planned independently inside its own share (no SHA sharing); a module with zero power is left out.
plan_verify
Best verify module within a share, with its own SHA rings.
plan_verify_shaped
plan_verify_with restricted to builds of shape; without batch compression the profile has cp = 0.
plan_verify_with
Best verify module within a share; shared_sha as in plan_sign_with (two blocks per verification). Same selection rule as plan_sign_with; None if nothing fits.
sign_cost_placed
A signing build’s cost with its fixed-base machines in exactly the layouts machines = [uram, lut, bram] (ED25519_URAM_MACHINES, ED25519_LUT_MACHINES), for comparing a built design with the table.
sign_cost_within
The signing build’s cost with the memory layouts placed to fit limit (see place); extra_lut (the shared-SHA client port) is part of the build and counted in the fit.
sign_placement
Where a signing build’s fixed-base machines go within limit: how many in UltraRAM, LUT-RAM banks and block-RAM banks.
slimmed_costs
Specialized modules: the memory layout of MachineMemory::SPECIALIZED (banks M and A in UltraRAM, constants in a LUT ROM, the compress machine’s input bank in UltraRAM), as built and routed: Vivado 2023.2 out of context at 4.878 ns, every block meeting timing, on the fix9 RTL (the timing fixes through e0c9caa; measure/results.tsv, 2026-10-18):
verify_cost_placed
A verify build’s cost with its verify machines in exactly the layouts machines (as sign_cost_placed).
verify_cost_within
A verify build’s cost with the memory layouts placed to fit limit.
verify_placement
Where a verify build’s verify machines go within limit (as sign_placement).
vivado_costs
Vivado 2023.2 out-of-context synthesis of 15/11/3/1, per instance.
with_mul_pub
The cost table c rebuilt for multiplier m. Returns None for Multiplier::Lean150 when c.lean_mul is None, so callers can skip that option. The cost table for multiplier m, or c itself when m is not offered (for callers outside this module).