code wiki / _hdl_build / nx_latency_metric.nx
nx_latency_metric.nx
buildroot/runtime/_hdl_build/nx_latency_metric.nx
about
nx_latency_metric.nx -- the racing-crew's HONEST latency-metric organ.
Given a built NxGsim word-level netlist (topologically ordered cells, each a
kind with up to 3 fanin nets), compute the CRITICAL PATH = the longest
dependency chain of cells from a primary input to an output. Two metrics:
(1) UNIT depth -- every non-CONST cell costs 1. This is the cell-DEPTH the
functional sim (nx_nxgate_sim) implicitly uses: it assigns depth-1 to
every word-level cell, so a 64x64 MUL looks exactly as cheap as a 1-bit
AND. That is the HONEST-METRIC TRAP, and the unit metric is the trap.
(2) HONEST depth -- every cell costs its per-kind logic depth, weighted by
the operand width W (data-driven, NOT hardcoded per call site):
CONST / wire = 0 (no logic)
AND/OR/XOR/NOT/NAND/... = 1 (one gate level)
MUX = 1 (one 2:1 select level)
ADD/SUB = ceil(log2 W) (carry-propagate / prefix adder)
SHL/SHR/SAR = ceil(log2 W) (barrel shifter, log stages)
EQ/NEQ/LT/LTU/GE/GEU = ceil(log2 W) (tree comparator)
MUL = 2*ceil(log2 W) (Wallace/Dadda PP-reduction
tree + final CPA -- the
DEEPEST operator)
So the honest metric does NOT treat a multiplier as depth-1: a MUL costs
2*log(W) gate levels, an ADD costs log(W), a boolean costs 1. This is the
metric on which any LATENCY claim about a Newton (log(W) multiplies)
vs a radix-2 (W subtracts) divider must be stated -- because a multiply
being "one cell" in the sim is exactly the self-deception we must avoid.
METRIC HONESTY (stated, per the racing doctrine): these weights are a STRUCTURAL
gate-LEVEL model (counts of logic levels), not measured silicon nanoseconds and
not a placed-and-routed delay. They are a faithful relative ordering of operator
depth, sized by W, and they are DATA-DRIVEN here so a future PDK-calibrated table
drops in without touching the traversal. The traversal itself is exact: it is the
true longest weighted path through the DAG.
Reuses nx_nxgate_sim's NxGsim/NxGsimCell structs + the NX_GATE_KIND_* enum
(single source of truth -- DRY). Pure read-only analysis: it never mutates the
netlist, only walks it. license_tier: ORIGINAL
dependencies 1 imports · 3 importers
imports: nx_nxgate_sim.nx
imported by: nx_div_pick.nxnx_latency_metric_test.nxnx_superopt.nx
structs
| none |
consts
| 42 | const NX_LAT_OK: i64 = 0 |
| 43 | const NX_LAT_BAD_KIND: i64 = 1 |
functions
| 48 | func nx_lat_log2_ceil(w: i64) -> i64 |
| 60 | func nx_lat_kind_weight(kind: i64, w: i64) -> i64 |
| 102 | func nx_lat_critical_path(g: *NxGsim, depth: *i64, mode: i64, w: i64) -> i64 |
| 143 | func nx_lat_unit(g: *NxGsim, depth: *i64) -> i64 |
| 146 | func nx_lat_honest(g: *NxGsim, depth: *i64, w: i64) -> i64 |