Skip to main content

Module build_and_verification

Module build_and_verification 

Source
Expand description

Source manifests, simulation entry points, synthesis scripts, and evidence rules.

§Building, Testing, And Verifying The SystemVerilog

This chapter explains how source files become a simulator executable, a Vivado out-of-context design, or a packaged Vitis kernel. It also defines what each kind of evidence proves. Read the overview first if the active and predecessor source sets are not yet familiar.

§Active Elaboration Manifest

The current fixed-64 cryptographic top is fast64_cached_sign_core. Its active source closure is:

LayerFiles elaborated
Fieldradix51_field_mul_pipe.sv, radix17_field_addsub_pipe.sv
Fixed basemulticomb_lookup_rom.sv, multicomb_mul_stream.sv
SHA-512sha512_compress_3phase.sv, sha512_compress_pool4.sv
Point codecpoint_compress_pair_stream.sv
Scalarscalar_arithmetic_dsp_pipe.sv
Signing topfast64_cached_sign_core.sv

scalar_arithmetic_2phase.sv is also supplied by the packaging and synthesis scripts for compatibility with older top-level configurations. No module in the current cached signer instantiates it, so Vivado removes it during elaboration. Source presence in a command is not proof that hardware exists; the instantiated hierarchy and post-synthesis utilization report are the authoritative answers.

The optional deployment shell adds bench/rhdl/rtl/fast64_cached_sign_io_kernel.sv. The compute-only benchmark instead adds fast64_cached_sign_benchmark_engine.sv and fast64_benchmark_kernel.sv.

The active initialized memories are:

crates/rhdl_ed25519_fast_fixed_base/assets/multicomb_t8_n4_s8/
  comb_scan_bank00.mem
  comb_scan_bank01.mem
  comb_scan_bank02.mem
  comb_scan_bank03.mem

Vivado must run with that asset directory available because the scan-bank instances pass these names to $readmemh or Xilinx memory initialization. Moving a build without the memory images can produce an elaboration failure or, worse in a permissive flow, an uninitialized table.

§Rust Crates Versus Synthesized RTL

The fast Rust crates serve four purposes:

  1. They expose stable Rust descriptions and black-box boundaries.
  2. They generate deterministic test vectors and Dalek-derived expected values.
  3. They launch Icarus or Verilator testbenches with an explicit SV source list.
  4. They retain scheduler and arithmetic models useful for regression tests.

Rust code in these crates is not automatically translated into the optimized datapath. The files listed above are handwritten SystemVerilog and are passed directly to the HDL tool. The general compatibility backend is the portion implemented as RHDL synchronous devices and lowered through RHDL.

§Focused Simulation Tests

Run one Cargo job on memory-constrained systems. These tests cover the active blocks from leaves upward:

Test sourceWhat it checks
crates/rhdl_ed25519_fast_field/tests/rtl_radix51_pipeline.rsRadix-51 products, canonical reduction, latency, and consecutive valid inputs
crates/rhdl_ed25519_fast_field/tests/rtl_addsub_pipeline.rsModular add/subtract results and pipeline ordering
crates/rhdl_ed25519_fast_sha512/tests/rtl_compress.rsSHA-512 compression states against a software oracle
crates/rhdl_ed25519_fast_scalar/tests/rtl_scalar_dsp_pipeline.rsWide reduction and multiply-add against integer reference arithmetic
crates/rhdl_ed25519_fast_fixed_base/tests/rtl_multicomb_lookup.rsTable image contents, signed selection, and scan behavior
crates/rhdl_ed25519_fast_fixed_base/tests/rtl_multicomb_mul.rsProjective fixed-base products against Dalek points
crates/rhdl_ed25519_fast_point_codec/tests/rtl_pair_throughput.rsPaired inversion/compression correctness for an explicit six-lane experiment; it does not measure the active four-lane wrapper
crates/rhdl_ed25519_fast_sign/tests/rtl_fast64_cached_sign.rsKey expansion and complete signatures against Dalek
crates/rhdl_ed25519_fast_sign/tests/rtl_fast64_cached_benchmark.rsSaturated 512-message service interval and aggregate checksum
bench/rhdl/tb/fast64_cached_sign_io_kernel_tb.svAXI control, exact memory beats, odd batches, and signature retirement

For example:

cargo test -p rhdl_ed25519_fast_field --test rtl_radix51_pipeline -j 1
cargo test -p rhdl_ed25519_fast_scalar --test rtl_scalar_dsp_pipeline -j 1
cargo test -p rhdl_ed25519_fast_fixed_base --test rtl_multicomb_mul -j 1
cargo test -p rhdl_ed25519_fast_point_codec --test rtl_pair_throughput -j 1
cargo test -p rhdl_ed25519_fast_sign --test rtl_fast64_cached_sign -j 1
cargo test -p rhdl_ed25519_fast_sign \
  --test rtl_fast64_cached_benchmark -j 1 -- --nocapture

The Rust tests construct temporary testbenches and compiler outputs outside the tracked source tree. Inspect the test source when debugging because it is the exact compile manifest: SystemVerilog has no hidden Cargo linker that discovers modules automatically.

§Documentation Coverage Test

This documentation crate contains a structural guard:

cargo test -p ed25519_fast_sv_docs -j 1

It recursively finds every .sv file in the six fast RTL directories and every fast64_*.sv file in bench/rhdl/rtl. It then checks that:

  • every source filename is named in this manual;
  • every declared module is named;
  • every module parameter is named; and
  • every function automatic helper is named.

The test cannot judge explanation quality, prove that grouped AXI port tables are complete, or infer which modules elaborate. A reviewer must still compare the active hierarchy, parameter overrides, ports, state machines, and memory assets with the source.

§Vivado Out-Of-Context Synthesis

tools/vivado/synth_fast64_cached_sign_ooc.tcl reads the active core source, changes into the memory-asset directory, elaborates fast64_cached_sign_core, creates the requested clock, and writes:

ArtifactMeaning
post_synth.dcpSynthesized design checkpoint
utilization.rptFlat resource totals
utilization_hierarchical.rptResource attribution by instance
ram_utilization.rptInferred and primitive memory details
timing_summary.rptConstraint and setup/hold summary
critical_paths.rptTwenty worst maximum-delay paths
summary.txtPart, target frequency/period, and worst setup slack

The script sets general.maxThreads to two to reduce peak memory use. It runs synth_design -mode out_of_context and opt_design; it does not place or route the design. A positive OOC WNS says that the estimated synthesized path meets the requested period at this stage. It is not a routed kernel timing result and is not an FPGA throughput measurement.

tools/vivado/synth_fast64_io_kernel_ooc.tcl performs the corresponding check with fast64_cached_sign_io_kernel as top. Use the shell report for a claim about the deployable AXI kernel; a core-only clock does not include shell control, data movers, or result buffering.

The current matching-source evidence is kept under:

reports/generated/
  u280_fast64_cached_singlepoint_dspacc_norm2_ooc200_20260714/

For xcu280-fsvh2892-2L-e at a 200 MHz, 5.000 ns request, the optimized OOC report has WNS +0.520 ns. The worst path is 4.462 ns from muladd/reducer/biased_reg[25] to muladd/reducer/reduced1_reg[247], with 14 reported logic levels and only 10.959% estimated routing delay. Resource totals are 202,344 LUTs, 219,803 FFs, 356 RAMB36s, 6,745 DSP48E2s, and no URAM.

This run does not establish 250 MHz: 250 MHz allows 4.000 ns, shorter than the reported 4.462 ns data path. It also has no placement, no routing, and no matching-source AXI shell result. The maximum-delay report warns that 788 inputs and 786 outputs have no I/O delays and does not analyze hold timing. Timing claims must always include the top module, part, requested clock, implementation stage, report path, and source revision.

§Physical Implementation Evidence

Placement and routing have occurred, but only for the preceding builder-pipeline source. FAST64_PACKAGE_SHA256SUMS fails against the current working tree for seven active RTL files and the host source, so these reports must retain the predecessor label.

The predecessor standalone core is fully routed. At 200 MHz it misses setup by 0.007 ns; rechecking the same checkpoint at 199 MHz gives WNS +0.018 ns, TNS zero, and no setup failures. All 569,193 routable nets are routed with no route errors. The routed core uses 248,852 LUTs, 237,472 FFs, 356 RAMB36s, 3,376 DSPs, and no URAM. Its reports are:

reports/generated/u280_fast64_cached_quadmul_ctx16_codec4x4_addsub2_mul2z_builderpipe_route200_20260713/
reports/generated/u280_fast64_builderpipe_route199_timing_20260713/

The predecessor was also linked inside the full U280 Vitis platform. Synthesis, placement, and routing completed, but the 199 MHz kernel clock finished with WNS -1.836 ns, TNS -91,954.969 ns, and 137,269 failing setup endpoints. The worst 6.404 ns path runs from point context state to a field-multiplier DSP input and is 89% routing delay. Hold timing passes with WHS +0.006 ns. Vitis stops before bitstream and xclbin generation because setup timing fails:

reports/generated/u280_fast64_io_reference_link199_timing_failed_20260714/

The full routed device uses 381,802 LUTs, 419,571 FFs, 558 RAMB36s, six RAMB18s, 3,380 DSPs, and no URAM, including the fixed U280 platform. Subtracting the report’s fixed column leaves 274,173 LUTs, 283,485 FFs, 365 RAMB36 plus one RAMB18, and 3,376 DSPs in the dynamic region; that difference includes AXI and interconnect and is not kernel-only utilization. The only valid conclusion is that this predecessor was physically routable but did not close full-platform timing. Current-source placement remains open.

§Vitis RTL Kernel Packaging

bench/rhdl/package_fast64_io_kernel.tcl packages the SV closure as an RTL kernel named fast64_cached_sign_io_kernel. It:

  1. Creates a temporary Vivado project for xcu280-fsvh2892-2L-e.
  2. Adds the active RTL and four scan-bank memory images.
  3. marks the AXI-Lite control and four AXI memory buses as clocked by ap_clk.
  4. Creates the control-register metadata used by XRT.
  5. Declares the XPM libraries used for memories and FIFOs.
  6. Checks IP integrity and emits an .xo kernel object.

The lowercase m_axi_gmem* names in IP metadata correspond to the uppercase SystemVerilog signal prefixes documented in shells and benchmarks. The link configuration then assigns those logical ports to U280 memory banks. Packaging proves that the source is structurally acceptable as a Vitis RTL kernel; only linking, routing, programming the board, and validating every returned signature prove the deployed design.

§Reading Cycle Evidence Correctly

The current matching cached benchmark reports:

PASS cached_benchmark=512 cycles=119459 key_load=8517 first=18020 span=101438

There are 511 completion intervals between 512 outputs, so the sustained interval is:

101,438 / 511 = 198.508806 cycles/signature

The complete finite batch, including key load and fill/drain, averages:

119,459 / 512 = 233.318359 cycles/signature

Cycles become signatures per second only after selecting a justified clock. For example, the current core’s met 200 MHz OOC target projects 200,000,000 / 198.508806 = 1,007,512 sustained signatures/s. The finite batch projects to 857,198 signatures/s. These remain core simulation plus OOC projections until a matching shell is routed, an xclbin is generated, and the U280 validates every result.

§Safe Change Workflow

When modifying an SV module:

  1. Identify whether it is active, predecessor, shell, benchmark, or resource probe code in the overview.
  2. Update every caller’s parameter and port connection explicitly.
  3. Preserve ready/valid semantics and opaque tags through added pipeline stages.
  4. For lookup changes, inspect addresses and enables as well as values; secret digits must not alter memory access patterns.
  5. Run the leaf arithmetic test, then its parent engine test, then cached-sign and saturated benchmark tests.
  6. Run the real-core AXI test if ports, backpressure, ordering, or completion behavior changed.
  7. Regenerate matching-source Vivado reports before updating timing or area numbers.
  8. Update this manual and run its coverage test before publishing rustdoc.

Do not infer correctness from synthesis success, timing from RTL simulation, throughput from latency alone, or current performance from a predecessor xclbin. Each claim needs the evidence type that directly measures it.