SAME-CONDITION COMPARISON

One narrow problem. Every open design we could rerun. The same flow.

Batch-1 matrix-vector products for one LLM decode projection with 4-bit grouped weights and 8-bit activations, re-implemented with the same open tools, processes, clock targets and real model data.

What this page claims, and what it does not

Under the conditions below, CV-GEMV r14 (PAIR_REG = 0 on Nangate45, PAIR_REG = 1 on ASAP7, by the timing rule) has the highest throughput per cell area, the lowest energy per useful multiply-accumulate and the fewest bits read per useful multiply-accumulate of the open designs in the table, VTA's tuned and carry-save rows included, in Nangate45 and ASAP7, with bit-exact results.

The verdict for the three manufacturable open PDKs is separate (see below). The CV-GEMV number format loses less model accuracy than INT4 with 128-column groups and than MXFP4, measured the same way.

Rule change, 2026-11-07: this verdict now takes the latest CV-GEMV revision instead of r7. (a) When the rule was written, the r8 and r9 results in these two processes were already published; (b) in return the comparator bar was raised with two tuned VTA rows; (c) the r7 verdict and its two review rounds stay on this page as history.

History: the earlier verdict (CV-GEMV r7, r7c on Nangate45 and r7r on ASAP7, against the comparators as published then) was reached and confirmed in round 2 after round 1's findings were fixed. Against the best VTA row now in the table, tuned and carry-save rows included, r7 is at Nangate45 M1 -3.3%, M2 -9.5%; ASAP7 M1 -6.9%, M2 -5.2%.

It does not claim anything about other problems (batched matrix multiplication, convolution, training), commercial IP we cannot rerun, GPUs, or fabricated silicon. Where CV-GEMV loses or wins only narrowly, the section Where the margin is small says so.

Status: reached (all gates and all metrics pass). An independent reviewer from a different model family has confirmed it.

The problem and the conditions

  • Workload: Qwen2.5-0.5B layer 12 mlp.down_proj (896 × 4864) on WikiText-2 test tokens. 4,358,144 useful multiply-accumulates per token.
  • Arithmetic: signed INT4 weights with a signed INT4 zero point and an unsigned 8-bit integer scale per 32 columns, signed INT8 activations, exact integer result per row. Every W4A8 engine computes the same integers (the W8A8 baseline uses its own per-row INT8 weights and is labelled as a baseline); where an engine cannot apply the group scale or row sum itself, the host does it and that work is not charged to the engine.
  • Every engine is sized to the same peak, 64 multiply-accumulates per cycle.
  • Flow: OpenROAD-flow-scripts in one pinned container image, the same constraint shape and utilisation target for every engine. ASAP7 (typical corner, RVT) at 1000 ps and Nangate45 (typical) at 4.0 ns.
  • Power: every routed netlist replays real tokens of the same layer at gate level (every output checked), and OpenSTA applies that switching activity with extracted parasitics at the target clock. Most engines replay the first two tokens; the TPU and Gemmini, whose batch-1 replays are about eight times longer, replay the first token only; replaying the second token instead changes their energy by at most 0.04% (check). Energy is divided by the useful work in each engine's own window.
  • Excluded for every engine: storage (SRAM), I/O pads, multi-corner sign-off and host work. These exclusions favour the comparators, several of which keep large accumulators or partial sums outside the engine.
  • A design that misses the target clock is scored at its own minimum period for throughput.

The engines

  • Apache TVM VTA matrix-vector core (Apache-2.0, d4a15f6). Its official module generated from the Chisel source, and a register-for-register hand port that matched it on 200,000 random cycles. Since 2026-11-07 both also appear tuned, with the three changes from r9 and r10 that VTA's structure has (accumulator pipe registers without load enables, exact widths at VTA's interface, Booth-recoded 5-bit MACs; pipeline stages, valid-result latency and results unchanged, checks and diffs), and, after review round 3 noted that CV-GEMV r10 and r11 had carry-save trees while VTA did not, tuned with carry-save trees as well (each MAC's Booth partial products, and each row's eight products plus its accumulator value, summed in carry-save with one add each; same checks, checks and diffs). VTA is scored with the best of the six rows for every metric. Not applied to VTA (rules, 2026-11-08 06:57): CV-GEMV r13 and r14 recode their scale into Booth digits before the register that feeds the multiplier, and VTA's weights also pass an input register before its MACs, but the worst setup path of every tuned and carry-save VTA row, in all five processes, starts after the MACs and ends at the accumulator output, so the same move cannot shorten VTA's clock and would add register bits to all 64 MACs. CV-GEMV's revisions r8 to r14 were chosen from its own GF180MCU timing.
  • OpenGeMM BlockGemm (KU Leuven MICAS, Apache-2.0), 1 × 8 × 8, generated from the unchanged Chisel source.
  • Gemmini spatial array (UC Berkeley, BSD-3-Clause), 8 × 8, weight-stationary, generated from the unchanged Chisel source outside the Chipyard SoC.
  • LogikBench TPU matrix unit (Zero ASIC, MIT), 8 × 8, as shipped in OpenROAD-flow-scripts.
  • Plain W8A8 GEMV, a textbook engine we wrote with the same peak and memory style, as a labelled baseline.
  • CV-GEMV, this IP. Its RTL is supplied under an evaluation agreement; the routed reports, logs and power files are published here.

The two systolic arrays (TPU, Gemmini) are built for matrix-matrix work. At batch 1 they keep 1 of 8 columns busy, which is why their numbers are far apart from the others; they are included because they are the open references most often cited.

Results

★ marks the CV-GEMV setting that the rules fix for each process. Every number links back to the raw files in its row folder.

Nangate45, 4.0 ns

EngineM1 GMAC/s per mm² ↑M2 pJ per useful MAC ↓M3 bits read per MAC ↓Target clockCell area (µm²)Cycles per tokenMinimum period (ns)Routing DRCReplay
CV-GEMV r14, PAIR_REG = 0 ★627.70.6955.38met25,117.869,1041.9800PASS
CV-GEMV r14, PAIR_REG = 1554.30.8125.38met28,397.669,2161.2500PASS
CV-GEMV r13, PAIR_REG = 0627.50.6965.38met25,124.569,1041.9600PASS
CV-GEMV r13, PAIR_REG = 1553.20.8125.38met28,454.669,2161.3400PASS
CV-GEMV r12, PAIR_REG = 0630.60.6835.38met25,004.569,1041.9700PASS
CV-GEMV r12, PAIR_REG = 1553.50.8075.38met28,43769,2161.4000PASS
CV-GEMV r11, PAIR_REG = 0617.50.6975.38met25,533.169,1041.8700PASS
CV-GEMV r11, PAIR_REG = 1547.70.8185.38met28,739.469,2161.2200PASS
CV-GEMV r10, PAIR_REG = 0618.50.7085.38met25,49169,1041.9800PASS
CV-GEMV r10, PAIR_REG = 1543.00.8435.38met28,991.669,2161.2700PASS
CV-GEMV r9, PAIR_REG = 0546.80.7165.38met28,833.369,1041.7900PASS
CV-GEMV r9, PAIR_REG = 1487.50.8545.38met32,291.669,2161.2400PASS
CV-GEMV r8, PAIR_REG = 0525.90.7315.38met29,981.169,1041.7800PASS
CV-GEMV r8, PAIR_REG = 1454.90.9025.38met34,606.369,2161.5100PASS
CV-GEMV r7, PAIR_REG = 0459.30.8335.38met34,38168,9922.0500PASS
CV-GEMV r7, PAIR_REG = 1421.10.9555.38met37,445.969,1041.7500PASS
CV-GEMV r1 (first version measured)262.61.2835.38met60,234.968,8802.4000PASS
VTA matrix-vector core, official module, tuned + carry-save468.20.9236.00met34,175.768,0971.6700PASS
VTA matrix-vector core, hand port, tuned + carry-save475.20.9216.00met33,668.468,0971.6900PASS
VTA matrix-vector core, official module, tuned455.90.9616.00met35,098.468,0971.7700PASS
VTA matrix-vector core, hand port, tuned472.90.9656.00met33,833.968,0972.1100PASS
VTA matrix-vector core, official generated module447.00.9566.00met35,793.268,0972.0800PASS
VTA matrix-vector core, hand port443.40.9866.00met36,086.168,0972.3200PASS
OpenGeMM BlockGemm 1 × 8 × 8313.41.1496.00met51,057.468,0983.4000PASS
Plain W8A8 GEMV (baseline)316.31.2659.00met50,170.568,6561.3000PASS
LogikBench TPU MXU 8 × 826.98.2898.07met72,571.7558,7521.7800PASS
Gemmini mesh 8 × 8, weight-stationary27.67.9698.07met72,550.4544,7931.4700PASS

ASAP7, 1000 ps

EngineM1 GMAC/s per mm² ↑M2 pJ per useful MAC ↓M3 bits read per MAC ↓Target clockCell area (µm²)Cycles per tokenMinimum period (ns)Routing DRCReplay
CV-GEMV r14, PAIR_REG = 026,870.60.1385.38missed, scored at 950 MHz2,228.869,1041.0530PASS
CV-GEMV r14, PAIR_REG = 1 ★27,686.40.1505.38met2,274.269,2160.8060PASS
CV-GEMV r13, PAIR_REG = 026,280.30.1385.38missed, scored at 923 MHz2,214.269,1041.0840PASS
CV-GEMV r13, PAIR_REG = 127,973.50.1515.38met2,250.969,2160.8470PASS
CV-GEMV r12, PAIR_REG = 026,573.90.1385.38missed, scored at 934 MHz2,217.469,1041.0700PASS
CV-GEMV r12, PAIR_REG = 128,261.60.1485.38met2,227.969,2160.8320PASS
CV-GEMV r11, PAIR_REG = 027,089.30.1375.38missed, scored at 959 MHz2,232.369,1041.0430PASS
CV-GEMV r11, PAIR_REG = 127,801.30.1505.38met2,264.869,2160.8240PASS
CV-GEMV r10, PAIR_REG = 025,320.40.1405.38missed, scored at 899 MHz2,239.569,1041.1120PASS
CV-GEMV r10, PAIR_REG = 127,528.60.1525.38met2,287.269,2160.8380PASS
CV-GEMV r9, PAIR_REG = 028,398.50.1315.38met2,220.869,1040.9630PASS
CV-GEMV r9, PAIR_REG = 125,790.10.1545.38met2,441.469,2160.8250PASS
CV-GEMV r8, PAIR_REG = 026,945.00.1355.38met2,340.669,1040.9810PASS
CV-GEMV r8, PAIR_REG = 123,886.80.1625.38met2,635.969,2160.9220PASS
CV-GEMV r7, PAIR_REG = 020,304.70.1565.38missed, scored at 909 MHz2,828.668,9921.1000PASS
CV-GEMV r7, PAIR_REG = 121,849.10.1705.38met2,886.569,1040.9770PASS
CV-GEMV r1 (first version measured)11,259.40.2385.38missed, scored at 840 MHz4,719.868,8801.1910PASS
VTA matrix-vector core, official module, tuned + carry-save23,123.60.1806.00met2,767.768,0970.9930PASS
VTA matrix-vector core, hand port, tuned + carry-save23,478.50.1796.00met2,725.968,0970.9830PASS
VTA matrix-vector core, official module, tuned22,153.90.1906.00met2,888.868,0970.9840PASS
VTA matrix-vector core, hand port, tuned19,314.60.1936.00missed, scored at 857 MHz2,838.168,0971.1670PASS
VTA matrix-vector core, official generated module20,193.70.1926.00missed, scored at 917 MHz2,906.268,0971.0910PASS
VTA matrix-vector core, hand port17,243.70.1976.00missed, scored at 800 MHz2,970.268,0971.2500PASS
OpenGeMM BlockGemm 1 × 8 × 87,544.90.2406.00missed, scored at 534 MHz4,532.568,0981.8710PASS
Plain W8A8 GEMV (baseline)16,489.80.2329.00met3,849.568,6560.8030PASS
LogikBench TPU MXU 8 × 81,395.61.6168.07missed, scored at 996 MHz5,567.5558,7521.0040PASS
Gemmini mesh 8 × 8, weight-stationary1,431.31.5708.07met5,589.1544,7930.9800PASS

M1 = useful multiply-accumulates per second per mm² of standard-cell area. M2 = workload power × replay window ÷ useful multiply-accumulates. M3 = bits the engine must read (weights, group data, activations) per useful multiply-accumulate; each row states its basis in the JSON.

Before and after design work

The first CV-GEMV version (r1) lost to VTA. It was then improved with ordinary engineering in steps r2 to r14 (retiming, one group-scale multiplier shared between rows, narrower counters, the zero point folded out of the lanes, registers without load enables, exact widths, Booth recoding, carry-save registers), each checked block by block to give results identical to r1. On Nangate45, throughput per area went from 262.6 to 627.7 GMAC/s per mm² and energy from 1.283 to 0.695 pJ. On ASAP7, r1 missed 1000 ps (scored at 840 MHz); r14 meets it. The comparators keep their published default structure; VTA, the strongest, also appears with the same kinds of ordinary change.

Where the margin is small, and what CV-GEMV loses

  • Throughput per area against VTA's best row on Nangate45 (VTA hand port, tuned + carry-save): +32.1%; on ASAP7 (VTA hand port, tuned + carry-save): +17.9%. The pass line counts anything within ±1% as a tie.
  • VTA needs fewer cycles per token (68,097 versus 69,104).
  • Nangate45: CV-GEMV r14 does not have the shortest minimum period (1.980 ns); Plain W8A8 GEMV (baseline) closes at 1.300 ns.
  • ASAP7: CV-GEMV r14 does not have the shortest minimum period (0.806 ns); Plain W8A8 GEMV (baseline) closes at 0.803 ns.
  • The PAIR_REG setting is chosen by the timing rule (0 if it meets the target clock, otherwise 1), written before the r14 results; the other setting is in the table.
  • Energy per useful multiply-accumulate against VTA's best row: -24.5% on Nangate45, -16.2% on ASAP7.
  • Accuracy: the CV-GEMV format is about equal to the same format with floating-point scales (+14.1% versus +14.0%), not better.
  • Under four shared flow-setting variants the smallest margins against VTA's best row are Nangate45 M1 +32.1%, M2 -24.2%; ASAP7 M1 +17.6%, M2 -15.4% (Flow settings).
  • On 11 more projections (other layers and models) the smallest margins against the best comparator row are Nangate45 M1 +27.4%, M2 -22.9%; ASAP7 M1 +13.4%, M2 -14.3%; SKY130HD M1 +14.6%, M2 -20.5% (nine projections: its 2,432 × 896 CV-GEMV build did not route, so gate_proj and up_proj have no CV-GEMV row); GF180MCU M1 +46.4%, M2 -2.6%; IHP SG13G2 M1 +14.5%, M2 -26.2% (Other layers and models).
  • At 256 MACs per cycle, against the best 256-MAC comparator row: Nangate45 M1 +12.3%, M2 +4.1%; ASAP7 M1 -7.9%, M2 +26.0%; SKY130HD M1 +0.9%, M2 +12.9%; GF180MCU M1 +32.2%, M2 +25.7%; IHP SG13G2 M1 +5.6%, M2 -1.8% (Four times the size).
  • A later revision, r15, built as 16 rows of 16 columns at 256 MACs per cycle (not the verdict subject), against the same 256-MAC comparator rows: Nangate45 M1 +26.9%, M2 -4.2%; ASAP7 M1 +9.4%, M2 +4.3%; SKY130HD M1 +18.1%, M2 -2.6%; GF180MCU M1 +36.1%, M2 +21.3%; IHP SG13G2 M1 +15.4%, M2 -13.0% (Another shape at 256 MACs).

Manufacturable open PDKs: not reached

The same comparison, with its conditions fixed before the first open-PDK result and later changes dated in the rules, in three processes that can be fabricated through open shuttles: SKY130HD, GF180MCU and IHP SG13G2, one 8.0 ns target for all (the clock OpenROAD-flow-scripts ships for its ibex reference design on each). CV-GEMV's setting per process was fixed in advance (PAIR_REG = 0 if it meets 8.0 ns). Result by the same code: not reached.

  • GF180MCU: no engine, CV-GEMV included, meets 8.0 ns (CV-GEMV misses by 0.016 ns), so the timing gate fails.
  • IHP SG13G2: the pinned flow's IHP platform file removes every standard cell from the netlists it writes for its equivalence check, so that check compared empty netlists for every IHP row whose flow ran it (the TPU's flow left no final check log). By the rule of 2026-11-07 09:13, G2 here comes from the same checker run the flow's way on netlists written from the same databases with only the bond-pad pattern removed: identical (lec.txt; the flow's own record is lec-flow.txt).
  • Second machine (G4): 33 of 33 rows reproduced, 0 differences (table).
  • Bits read per useful MAC (M3), bit-exact results and model accuracy do not depend on the process and still pass.

History: with r7 these processes lost throughput per area to VTA by 5.6 % (SKY130HD) and 17.5 % (IHP). r8 folds the zero point out of the 64 lanes (the standard identity sum (w - zp) x = sum w x - zp sum x) and drops the performance counters; it is identical to r1 block for block and bit-exact on the real layer, and the rules made it the subject here before any r8 result. With r8, SKY130HD and IHP passed every metric; on GF180MCU r8 missed 8.0 ns (9.37 ns) and tied VTA on energy. r9 takes the load-enable multiplexers out of registers that are read only under a valid flag (the GF180MCU library has no enable flip-flop, so each enable is a multiplexer), shifts the waiting group results one row per phase instead of selecting them, and gives every register its exact width; results and cycle counts are r8's, and the rules made r9 the subject before any r9 result. With r9 every metric passed in all three processes and GF180MCU closed at 8.05 ns. r10 recoded the lane weights in radix-4 Booth digits, registered each pair sum in two parts with the carry between them kept as one bit, and held the activation sum in carry-save form; it shrank the PAIR_REG = 0 layouts (SKY130HD -7 %, IHP -11 %) but slowed the stage after the pair registers, and GF180MCU closed at 9.15 ns. r11 rebuilt that stage as one carry-save tree and took the plain scale product back; GF180MCU closed at 8.48 ns. r12 split the four pair sums at different bits so their carries enter the group tree without a counting adder, summed the scale product in an explicit carry-save tree and cleared the row accumulators from a register: 8.08 ns. r13 took the scale as radix-4 Booth digits recoded when it is copied (three carry-save levels instead of four) and moved the pair splits so that no upper add is wider than r11's: 8.01 ns. r14 holds those digits one-hot, so each partial-product bit is one AND-OR: 8.02 ns. By the rule the subject is the latest revision (r14), not the one that closed fastest. On 2026-11-07 VTA also got two tuned rows, which raised the bar in every process. The claim above stays limited to Nangate45 and ASAP7 until this verdict is reached.

Attempts: r2 to r14 were all made for this comparison (r1 is the first version measured); 8 of them were measured in GF180MCU (r7 to r14). Each revision's rule was committed before its result, but every extra attempt adds a chance of keeping one that met the target by luck, so all of them stay in summary.json (the tables on this page show r1 and r7 to r14). GF180MCU minimum period per revision (the shorter of its two settings; target 8.0 ns): r7 10.90 ns, r8 9.37 ns, r9 8.05 ns, r10 9.15 ns, r11 8.48 ns, r12 8.08 ns, r13 8.01 ns, r14 8.02 ns.

SKY130HD, 8.0 ns

EngineM1 GMAC/s per mm² ↑M2 pJ per useful MAC ↓M3 bits read per MAC ↓Target clockCell area (µm²)Cycles per tokenMinimum period (ns)Routing DRCReplay
CV-GEMV r14, PAIR_REG = 0 ★57.33.7335.38met137,69669,1047.5200PASS
CV-GEMV r14, PAIR_REG = 153.24.5615.38met147,81169,2165.1600PASS
CV-GEMV r13, PAIR_REG = 056.83.7495.38met138,67969,1047.5600PASS
CV-GEMV r13, PAIR_REG = 153.34.5245.38met147,54469,2165.4800PASS
CV-GEMV r12, PAIR_REG = 056.13.7975.38met140,42869,1047.8000PASS
CV-GEMV r12, PAIR_REG = 154.04.4405.38met145,70669,2165.2800PASS
CV-GEMV r11, PAIR_REG = 056.43.7565.38met139,75069,1047.4900PASS
CV-GEMV r11, PAIR_REG = 153.64.4305.38met146,89369,2165.2700PASS
CV-GEMV r10, PAIR_REG = 056.23.8425.38met140,15669,1047.4900PASS
CV-GEMV r10, PAIR_REG = 153.14.4905.38met148,21769,2165.6500PASS
CV-GEMV r9, PAIR_REG = 052.33.7915.38met150,77069,1047.1000PASS
CV-GEMV r9, PAIR_REG = 147.04.5475.38met167,35169,2165.3000PASS
CV-GEMV r8, PAIR_REG = 050.23.9105.38met156,95169,1047.1800PASS
CV-GEMV r8, PAIR_REG = 144.94.6475.38met175,29869,2166.9600PASS
CV-GEMV r7, PAIR_REG = 041.04.4755.38missed, scored at 124 MHz191,39768,9928.0500PASS
CV-GEMV r7, PAIR_REG = 140.95.0395.38met192,85669,1047.2500PASS
VTA matrix-vector core, official module, tuned + carry-save47.34.8776.00met169,30468,0977.5600PASS
VTA matrix-vector core, hand port, tuned + carry-save45.65.0786.00met175,59568,0977.7200PASS
VTA matrix-vector core, official module, tuned44.85.2426.00met178,60468,0977.1500PASS
VTA matrix-vector core, hand port, tuned45.85.1856.00missed, scored at 123 MHz171,52368,0978.1500PASS
VTA matrix-vector core, official generated module43.35.1996.00met184,68768,0977.9600PASS
VTA matrix-vector core, hand port36.95.8406.00missed, scored at 117 MHz202,29768,0978.5700PASS
OpenGeMM BlockGemm 1 × 8 × 816.66.8976.00missed, scored at 80 MHz307,70068,09812.5600PASS
Plain W8A8 GEMV (baseline)30.86.5379.00met257,76168,6565.8700PASS
LogikBench TPU MXU 8 × 82.652.2078.07met372,577558,7527.6700PASS
Gemmini mesh 8 × 8, weight-stationary2.752.7558.07met367,336544,7936.9600PASS

GF180MCU (9-track, 5 V), 8.0 ns

EngineM1 GMAC/s per mm² ↑M2 pJ per useful MAC ↓M3 bits read per MAC ↓Target clockCell area (µm²)Cycles per tokenMinimum period (ns)Routing DRCReplay
CV-GEMV r14, PAIR_REG = 07.1104.6295.38missed, scored at 81 MHz718,84869,10412.3600PASS
CV-GEMV r14, PAIR_REG = 1 ★10.9111.2685.38missed, scored at 125 MHz720,06869,2168.0200PASS
CV-GEMV r13, PAIR_REG = 06.7104.1155.38missed, scored at 77 MHz724,56169,10412.9700PASS
CV-GEMV r13, PAIR_REG = 111.0109.9295.38missed, scored at 125 MHz717,29969,2168.0100PASS
CV-GEMV r12, PAIR_REG = 06.9101.0165.38missed, scored at 78 MHz710,82469,10412.8100PASS
CV-GEMV r12, PAIR_REG = 110.8110.8035.38missed, scored at 124 MHz719,09169,2168.0800PASS
CV-GEMV r11, PAIR_REG = 07.1101.8245.38missed, scored at 80 MHz709,01569,10412.5500PASS
CV-GEMV r11, PAIR_REG = 110.3110.6595.38missed, scored at 118 MHz724,02769,2168.4800PASS
CV-GEMV r10, PAIR_REG = 06.8105.9655.38missed, scored at 81 MHz752,63069,10412.2700PASS
CV-GEMV r10, PAIR_REG = 18.9118.6995.38missed, scored at 109 MHz772,25769,2169.1500PASS
CV-GEMV r9, PAIR_REG = 07.894.8895.38missed, scored at 87 MHz706,10069,10411.4500PASS
CV-GEMV r9, PAIR_REG = 19.8115.1965.38missed, scored at 124 MHz801,57369,2168.0500PASS
CV-GEMV r8, PAIR_REG = 07.4100.9565.38missed, scored at 90 MHz759,63269,10411.1700PASS
CV-GEMV r8, PAIR_REG = 17.7123.0905.38missed, scored at 107 MHz875,65269,2169.3700PASS
CV-GEMV r7, PAIR_REG = 05.4111.0605.38missed, scored at 76 MHz898,78568,99213.0800PASS
CV-GEMV r7, PAIR_REG = 16.0128.6165.38missed, scored at 92 MHz970,42369,10410.9000PASS
VTA matrix-vector core, official module, tuned + carry-save7.2114.7366.00missed, scored at 93 MHz827,14468,09710.7400PASS
VTA matrix-vector core, hand port, tuned + carry-save6.8118.1316.00missed, scored at 91 MHz853,25468,09711.0400PASS
VTA matrix-vector core, official module, tuned6.9121.7016.00missed, scored at 95 MHz880,25968,09710.5700PASS
VTA matrix-vector core, hand port, tuned5.6126.6166.00missed, scored at 75 MHz863,72568,09713.3200PASS
VTA matrix-vector core, official generated module5.8123.9706.00missed, scored at 80 MHz877,77268,09712.5500PASS
VTA matrix-vector core, hand port4.9132.3746.00missed, scored at 71 MHz919,30968,09714.1800PASS
OpenGeMM BlockGemm 1 × 8 × 82.1152.8196.00missed, scored at 43 MHz1,326,380.068,09823.2000PASS
Plain W8A8 GEMV (baseline)6.2164.7399.00missed, scored at 117 MHz1,204,410.068,6568.5300PASS
LogikBench TPU MXU 8 × 80.31080.6958.07missed, scored at 87 MHz1,963,680.0558,75211.5600PASS
Gemmini mesh 8 × 8, weight-stationary0.5936.1038.07missed, scored at 109 MHz1,754,110.0544,7939.1800PASS

IHP SG13G2, 8.0 ns

EngineM1 GMAC/s per mm² ↑M2 pJ per useful MAC ↓M3 bits read per MAC ↓Target clockCell area (µm²)Cycles per tokenMinimum period (ns)Routing DRCReplay
CV-GEMV r14, PAIR_REG = 0 ★27.73.5125.38met284,66869,1046.6500PASS
CV-GEMV r14, PAIR_REG = 126.64.2805.38met295,38169,2164.5700PASS
CV-GEMV r13, PAIR_REG = 028.33.4705.38met278,15869,1046.6200PASS
CV-GEMV r13, PAIR_REG = 126.44.3055.38met297,97969,2164.5800PASS
CV-GEMV r12, PAIR_REG = 027.63.4875.38met285,59769,1046.8400PASS
CV-GEMV r12, PAIR_REG = 126.74.2645.38met294,49969,2165.0900PASS
CV-GEMV r11, PAIR_REG = 027.53.4875.38met286,56169,1046.6500PASS
CV-GEMV r11, PAIR_REG = 126.44.2905.38met297,75269,2164.9600PASS
CV-GEMV r10, PAIR_REG = 027.23.5505.38met290,19569,1046.5800PASS
CV-GEMV r10, PAIR_REG = 126.54.3335.38met297,16869,2165.1700PASS
CV-GEMV r9, PAIR_REG = 024.23.8525.38met325,68869,1046.5900PASS
CV-GEMV r9, PAIR_REG = 123.04.5825.38met342,19669,2165.1700PASS
CV-GEMV r8, PAIR_REG = 022.94.0315.38met344,30469,1046.7200PASS
CV-GEMV r8, PAIR_REG = 122.04.7235.38met358,16669,2165.6300PASS
CV-GEMV r7, PAIR_REG = 016.75.2445.38met472,97468,9927.5500PASS
CV-GEMV r7, PAIR_REG = 117.55.5615.38met450,14769,1046.2900PASS
VTA matrix-vector core, official module, tuned + carry-save23.04.9786.00met348,43468,0976.0000PASS
VTA matrix-vector core, hand port, tuned + carry-save23.34.9366.00met343,27468,0976.1700PASS
VTA matrix-vector core, official module, tuned20.55.2696.00met391,07468,0976.1100PASS
VTA matrix-vector core, hand port, tuned22.75.0106.00met353,10468,0976.6100PASS
VTA matrix-vector core, official generated module19.95.3646.00met401,91068,0976.9400PASS
VTA matrix-vector core, hand port20.25.3686.00met395,31468,0977.1800PASS
OpenGeMM BlockGemm 1 × 8 × 89.48.4946.00missed, scored at 125 MHz855,45068,0988.0000PASS
Plain W8A8 GEMV (baseline)14.17.4949.00met563,77868,6565.1600PASS
LogikBench TPU MXU 8 × 81.259.4678.07met847,341558,7525.7700PASS
Gemmini mesh 8 × 8, weight-stationary1.160.8888.07met899,095544,7935.2600PASS

Flow settings

The flow gives the same result for the same inputs as far as it was checked: for every row a verdict uses, a second machine (one per row: the Mac or AWS) reproduced every number in the table (gate G4), with the same routed netlist for 22 of 22 main-verdict rows (second-machine.json), and here the 3 ASAP7 rows run again at the published setting on the AWS instance reproduced every number. So instead of a random seed the margins were tested against small changes of two settings every engine shares: core utilization and the placement density add-on. The rows and variants were fixed before any run (rules, 2026-11-07 14:34): in each process the CV-GEMV subject and every VTA row within 5 % of VTA's best M1 or M2 there (21 rows), every variant applied to all of them, flows, replay and power on the AWS instance. Each cell is CV-GEMV's margin over the best of those VTA rows under that setting (the row that is best can change; it is named in the JSON).

Process, metricPublishedCore utilization 40 %50 %Density add-on 0.150.25Smallest (rule's five)
Nangate45 M1+29.9%+30.1%+30.7%+30.0%+29.9%+29.9%
Nangate45 M2-24.3%-24.6%-24.5%-23.9%-24.2%-23.9%
ASAP7 M1+18.4%+19.7%+18.4% (= published)+18.4%+18.5%+18.4%
ASAP7 M2-16.2%-17.1%-16.2% (= published)-16.0%-16.2%-16.0%
SKY130HD M1+19.4%+19.4%+17.3%+18.8%+19.6%+17.3%
SKY130HD M2-23.0%-23.0%-20.2%-22.3%-23.5%-20.2%
GF180MCU M1+42.3%+44.9%+41.2%+45.0%+41.8%+41.2%
GF180MCU M2-3.6%-3.8%-3.2%-2.9%-2.9%-2.9%
IHP SG13G2 M1+18.0%+18.5%+17.6%+17.7%+18.4%+17.6%
IHP SG13G2 M2-29.4%-29.5%-29.4%-29.2%-29.6%-29.2%

No variant reverses a metric: in every process and metric each margin stays outside the ±1 % band. The closest is GF180MCU M2, -2.9% (density add-on 0.15). None of the rule's four variants changed whether a row meets its clock, its routing DRC count or its replay result. On GF180MCU CV-GEMV misses its clock in every variant as in the published table, so its throughput there is scored at its own minimum period and the timing gate stays open. The verdicts are not changed by this study.

Correction (rules, 2026-11-07 18:00, after the results): the rule gave the base utilization as 45 %; in ASAP7 it is 50 %, so there the 50 % column is the published configuration itself (the AWS run reproduced every numeric field of the three published ASAP7 rows) and 40 % is ten points below it. Added after the results and outside the fixed rule, the three ASAP7 rows at 45 and 55 % (below; not part of the smallest value): no metric reverses.

Process, metricASAP7 45 % (added)ASAP7 55 % (added)
ASAP7 M1+18.8%+18.2%
ASAP7 M2-16.4%-15.9%

ASAP7 at 55 %: VTA hand port, tuned + carry-save misses its 1000 ps target by 0.30 ps and is scored at its own minimum period.

All six VTA rows (rules, 2026-11-07 18:48, written after the round-5 cross-review and before these runs): the 14 VTA rows the rule left out were run under the same four settings, and ASAP7's four of them also at 45 and 55 %. Each cell below is CV-GEMV's margin over the best of all six VTA rows under that setting. This is reported apart from the rule's result above, which stays as published.

Process, metricPublishedCore utilization 40 %50 %Density add-on 0.150.25Smallest (five)
Nangate45 M1+29.9%+30.1%+30.7%+30.0%+29.9%+29.9%
Nangate45 M2-24.3%-24.6%-24.5%-23.9%-24.2%-23.9%
ASAP7 M1+18.4%+19.7%+18.4%+18.4%+18.5%+18.4%
ASAP7 M2-16.2%-17.1%-16.2%-16.0%-16.2%-16.0%
SKY130HD M1+19.4%+19.4%+17.3%+18.8%+19.6%+17.3%
SKY130HD M2-23.0%-23.0%-20.2%-22.3%-23.5%-20.2%
GF180MCU M1+42.3%+44.9%+41.2%+45.0%+41.8%+41.2%
GF180MCU M2-3.6%-3.8%-3.2%-2.9%-2.9%-2.9%
IHP SG13G2 M1+18.0%+18.5%+17.6%+17.7%+18.4%+17.6%
IHP SG13G2 M2-29.4%-29.5%-29.4%-29.2%-29.6%-29.2%

Against all six VTA rows no metric reverses or comes within ±1 % either. In no variant is a left-out row VTA's best, so the margins equal the rule's. ASAP7 at 45 and 55 % against all six: M1 +18.8%, +18.2%; M2 -16.4%, -15.9% (none reversed or within ±1 %). Under density add-on 0.25, ASAP7 vta8_official_tuned misses its 1000 ps target by 14.62 ps and is scored at its own minimum period (in the published table it meets it).

The current subject (r14)

The study above was fixed on 2026-11-07 for the subject of that day (r11). When both verdicts moved to r14 (rules of 2026-11-08, each revision's entry written before its results; these runs were fixed at 06:21), its subject row in each process was run under the same four settings, and ASAP7's also at 45 and 55 %, on the AWS instance. Each cell is r14's margin over the best of all six VTA rows under that setting (the VTA rows are the published variant rows above). Reported apart; no verdict depends on it.

Process, metricPublishedCore utilization 40 %50 %Density add-on 0.150.25Smallest (five)
Nangate45 M1+32.1%+32.3%+32.9%+32.1%+32.1%+32.1%
Nangate45 M2-24.5%-24.7%-24.5%-24.2%-24.3%-24.2%
ASAP7 M1+17.9%+19.1%+17.9%+17.6%+17.8%+17.6%
ASAP7 M2-16.2%-17.0%-16.2%-15.4%-15.9%-15.4%
SKY130HD M1+21.2%+21.1%+17.5%+19.2%+21.3%+17.5%
SKY130HD M2-23.5%-23.4%-19.3%-21.2%-24.3%-19.3%
GF180MCU M1+51.3%+55.3%+52.1%+56.3%+52.2%+51.3%
GF180MCU M2-3.0%-3.2%-2.0%-3.3%-2.8%-2.0%
IHP SG13G2 M1+18.8%+19.6%+18.8%+18.9%+19.2%+18.8%
IHP SG13G2 M2-28.9%-29.1%-28.9%-28.8%-29.1%-28.8%

No metric reverses or comes within ±1 %. ASAP7 at 45 and 55 %: M1 +18.2%, +17.7%; M2 -16.1%, -16.0% (none reversed or within ±1 %). Worst setup slack of each subject under each setting (gate G3 is decided by the published flow; this shows how far the other settings move it):

Process, subjectPublishedCore utilization 40 %50 %Density add-on 0.150.25
Nangate45, CV-GEMV r14, PAIR_REG = 0+2.018 ns+2.024 ns+2.036 ns+2.019 ns+2.028 ns
ASAP7, CV-GEMV r14, PAIR_REG = 1+0.194 ns+0.221 ns+0.194 ns+0.214 ns+0.186 ns
SKY130HD, CV-GEMV r14, PAIR_REG = 0+0.478 ns+0.545 ns+0.110 ns+0.435 ns+0.450 ns
GF180MCU, CV-GEMV r14, PAIR_REG = 1-0.016 ns (missed)-0.011 ns (missed)-0.018 ns (missed)-0.039 ns (missed)+0.014 ns
IHP SG13G2, CV-GEMV r14, PAIR_REG = 0+1.348 ns+1.283 ns+1.014 ns+1.360 ns+1.018 ns

GF180MCU: r14 misses 8.0 ns under the published table, utilization 40 %, utilization 50 %, density add-on 0.15. Tables: utilization 40 %, utilization 50 %, density add-on 0.15, density add-on 0.25, ASAP7 at 45 %, ASAP7 at 55 %.

Sensitivity JSON ↓ · Each variant's table, with a raw-file folder per row: utilization 40 %, utilization 50 %, density add-on 0.15, density add-on 0.25, ASAP7 at 45 %, ASAP7 at 55 % · all VTA rows, utilization 40 % · all VTA rows, utilization 50 % · all VTA rows, density add-on 0.15 · all VTA rows, density add-on 0.25 · all VTA rows, ASAP7 at 45 % · all VTA rows, ASAP7 at 55 %

Other layers and models

Both verdicts use one projection. As written on 2026-11-08 08:40, before any of these files existed, the verdict subject (CV-GEMV r14, the setting the subject rule chose in each process) and every comparator row of the tables were measured in all five processes on 11 more projections (except CV-GEMV on SKY130HD gate_proj and up_proj, whose build did not route; see Gates): the other six of the base layer, down_proj of the first and the last layer, and down_proj of the middle layer of three recent models. Each projection's data comes from the base pipeline (the same calibration, the eight preregistered token positions, per-token INT8); the generator first reproduced the base table's 15 input files byte for byte (14 of them have published hashes). VTA, the TPU, OpenGeMM and Gemmini take any shape at run time and were replayed on their published routed netlists. CV-GEMV and the W8A8 baseline fix the shape when they are built, so each new shape is a new build of the same RTL with the same flow settings; CV-GEMV takes at most 4096 rows per command, so gate_proj and up_proj run as two commands on one 2,432 × 896 build; between them the testbench swaps the weight and group memories in zero time, as it swaps the query between tokens (storage is outside every engine), and both commands' cycles and reads are counted. As in the base table, the TPU and Gemmini replay one token and the others two. No verdict changes; this is reported apart.

Smallest margin over the base table and the eleven projections (SKY130HD: the base table and nine projections), and energy per MAC over the seven projections of layer 12 together:

ProcessM1, throughput per area (higher is better)M2, energy per MAC (lower is better)M2, layer 12 together
Nangate45+27.4% (Qwen2.5-0.5B layer 12 gate_proj)-22.9% (Qwen2.5-0.5B layer 12 gate_proj)-24.8% (VTA official generated module)
ASAP7+13.4% (Qwen2.5-0.5B layer 12 o_proj)-14.3% (Qwen2.5-0.5B layer 12 q_proj)-15.1% (VTA hand port, tuned + carry-save)
SKY130HD+14.6% (Qwen2.5-0.5B layer 12 o_proj)-20.5% (Qwen3.5-0.8B layer 12 down_proj)–
GF180MCU+46.4% (Qwen2.5-0.5B layer 12 gate_proj)-2.6% (Qwen2.5-0.5B layer 12 gate_proj)-3.0% (VTA official module, tuned + carry-save)
IHP SG13G2+14.5% (Qwen2.5-0.5B layer 12 o_proj)-26.2% (Qwen2.5-0.5B layer 23 down_proj)-28.4% (VTA hand port, tuned + carry-save)

Throughput per area (M1): CV-GEMV's margin over the best comparator row

ProjectionRows × columnsNangate45ASAP7SKY130HDGF180MCUIHP SG13G2
Qwen2.5-0.5B layer 12 down_proj (base table)896 × 4,864+32.1%+17.9%+21.2%+51.3%+18.8%
Qwen2.5-0.5B layer 12 q_proj896 × 896+28.9%+13.4%+14.6%+46.8%+14.5%
Qwen2.5-0.5B layer 12 k_proj128 × 896+27.8%+14.6%+16.6%+48.4%+18.5%
Qwen2.5-0.5B layer 12 v_proj128 × 896+27.8%+14.6%+16.6%+48.4%+18.5%
Qwen2.5-0.5B layer 12 o_proj896 × 896+28.9%+13.4%+14.6%+46.8%+14.5%
Qwen2.5-0.5B layer 12 gate_proj4,864 × 896+27.4%+14.0%no routed build (G3)+46.4%+16.0%
Qwen2.5-0.5B layer 12 up_proj4,864 × 896+27.4%+14.0%no routed build (G3)+46.4%+16.0%
Qwen2.5-0.5B layer 0 down_proj896 × 4,864+32.1%+17.9%+21.2%+51.3%+18.8%
Qwen2.5-0.5B layer 23 down_proj896 × 4,864+32.1%+17.9%+21.2%+51.3%+18.8%
Qwen3.5-0.8B layer 12 down_proj1,024 × 3,584+33.7%+20.7%+20.7%+54.1%+21.4%
Qwen3.5-2B layer 12 down_proj2,048 × 6,144+32.9%+17.4%+18.3%+51.0%+20.9%
Gemma 4 E2B layer 17 down_proj1,536 × 12,288+32.8%+20.6%+20.4%+53.8%+19.4%

No workload puts this margin inside ±1% or reverses it.

Energy per useful MAC (M2): CV-GEMV's margin over the best comparator row

ProjectionRows × columnsNangate45ASAP7SKY130HDGF180MCUIHP SG13G2
Qwen2.5-0.5B layer 12 down_proj (base table)896 × 4,864-24.5%-16.2%-23.5%-3.0%-28.9%
Qwen2.5-0.5B layer 12 q_proj896 × 896-23.8%-14.3%-23.7%-3.6%-27.7%
Qwen2.5-0.5B layer 12 k_proj128 × 896-23.4%-14.8%-24.1%-3.1%-29.7%
Qwen2.5-0.5B layer 12 v_proj128 × 896-23.4%-14.5%-23.9%-2.9%-29.5%
Qwen2.5-0.5B layer 12 o_proj896 × 896-24.9%-15.3%-21.3%-3.3%-28.9%
Qwen2.5-0.5B layer 12 gate_proj4,864 × 896-22.9%-14.4%no routed build (G3)-2.6%-28.0%
Qwen2.5-0.5B layer 12 up_proj4,864 × 896-23.2%-14.7%no routed build (G3)-3.0%-28.2%
Qwen2.5-0.5B layer 0 down_proj896 × 4,864-23.7%-15.9%-23.4%-4.1%-26.7%
Qwen2.5-0.5B layer 23 down_proj896 × 4,864-23.1%-15.5%-23.2%-3.9%-26.2%
Qwen3.5-0.8B layer 12 down_proj1,024 × 3,584-24.3%-16.8%-20.5%-4.2%-29.3%
Qwen3.5-2B layer 12 down_proj2,048 × 6,144-24.8%-15.8%-22.1%-3.0%-29.8%
Gemma 4 E2B layer 17 down_proj1,536 × 12,288-23.3%-15.2%-21.6%-4.9%-26.4%

No workload puts this margin inside ±1% or reverses it.

Bits read per useful MAC (M3): -10.4% in every process and projection; the count depends on the formats and the tiling, not on the data.

Written before the results: CV-GEMV r14 spends a fixed 9 or 10 cycles per block of eight rows, which VTA's mapping does not, so on the 896-column projections (7 to 8 % of its cycles instead of 1.5 %) its M1 margins were expected several points smaller, and the GF180MCU energy margin, the closest of the base table, might fall inside ±1 % or reverse. Margins in bold are inside ±1 % or reversed. The best comparator row of every cell is in the JSON.

Result: on the 896-column projections the M1 margins are Nangate45 +27.4 to +28.9% (base +32.1%); ASAP7 +13.4 to +14.6% (base +17.9%); SKY130HD +14.6 to +16.6% (base +21.2%); GF180MCU +46.4 to +48.4% (base +51.3%); IHP SG13G2 +14.5 to +18.5% (base +18.8%). GF180MCU M2 ranges from -4.9% to -2.6% over the base table and the eleven projections; it does not fall inside ±1 % or reverse.

Gates

  • Nangate45: 121 replays, every output bit-exact. CV-GEMV: 6 of 6 new builds routed, 0 DRC violations, setup met at the target. W8A8: 6 of 6 new builds routed, 0 DRC violations, setup met at the target.
  • ASAP7: 121 replays, every output bit-exact. CV-GEMV: 6 of 6 new builds routed, 0 DRC violations, setup met at the target. W8A8: 6 of 6 new builds routed, 0 DRC violations, setup met at the target.
  • SKY130HD: 119 replays, every output bit-exact. CV-GEMV: 5 of 6 new builds routed, 0 DRC violations, setup met at the target; the 2432 × 896 build did not route (detailed routing ended with 1 violation and unrouted nets), so gate_proj and up_proj have no CV-GEMV row. W8A8: 6 of 6 new builds routed, 0 DRC violations, setup met at the target.
  • GF180MCU: 121 replays, every output bit-exact. CV-GEMV: 6 of 6 new builds routed, 0 DRC violations, setup missed at the target by 0.008 ns (1536 × 12288), 0.009 ns (2048 × 6144), 0.028 ns (896 × 896), 0.068 ns (1024 × 3584) (scored at their own minimum period). W8A8: 6 of 6 new builds routed, 0 DRC violations, setup missed at the target by 0.188 ns (896 × 896), 0.478 ns (1024 × 3584), 0.501 ns (4864 × 896), 0.541 ns (1536 × 12288), 0.654 ns (2048 × 6144), 1.056 ns (128 × 896) (scored at their own minimum period).
  • IHP SG13G2: 121 replays, every output bit-exact. CV-GEMV: 6 of 6 new builds routed, 0 DRC violations, setup met at the target. W8A8: 6 of 6 new builds routed, 0 DRC violations, setup met at the target.

Each replay row of the eleven projections (603; the 55 base rows are the base table's own) names the machine it ran on (AWS instance: 311, Azure build VM: 292) and the SHA-256 of the routed netlist it read. The replays of each published routed row all read one and the same netlist (55 of 55 rows); for the 22 rows whose netlist hash second-machine.json publishes, it is that netlist. The generator's check on the base projection compared 15 files, 0 different; the 14 whose hashes fixtures.json publishes are listed with those hashes (equal). The route log of the build that did not route: excerpt.

Workload breadth JSON ↓ · raw files per row under /evidence/compare/workloads/.

Four times the size: 256 MACs per cycle

Every engine above has a peak of 64 multiply-accumulates per cycle. As written on 2026-11-08 16:51, before any source, input file, flow or replay at the new size, the verdict subject (CV-GEMV r14 with the setting the subject rule chose in each process, now with 32 rows per cycle) and every comparator row were built at 256 MACs per cycle and measured on the base layer in all five processes: the W8A8 baseline with 32 rows; VTA at 16 × 16 (its default size) in its six rows; the TPU at 16 × 16; Gemmini as a 16 × 16 mesh (its default); OpenGeMM at 1 × 16 × 16. Each process's flow settings are those of the same 64-MAC row; only the size changed. VTA's square shape is its default and needs half the accumulators of a 32 × 8 shape, which favours VTA. No verdict changes; this is reported apart.

Checks before any flow, as the rule fixed them: at size 8 the generalised input generator reproduced the 15 base files byte for byte, and the generalised testbenches gave the published replay lines of 12 of 12 64-MAC rows exactly; at 256 MACs all 12 of 12 rows replay bit-exact at RTL. The VTA hand ports at 16 × 16 follow VTA's own source, which moves the pipeline register of the dot product from the first adder layer (8 × 8) to the third (16 × 16, after two adder layers); each hand port was checked cycle by cycle against the module generated from the unchanged Chisel, and the tuned and carry-save copies against their unchanged modules (25 runs of 200,000 cycles, 0 mismatches; a deliberately broken copy fails). The program that makes the tuned and carry-save copies of the generated module gives the published 8 × 8 copies byte for byte.

CV-GEMV's margin over the best 256-MAC comparator row

ProcessM1, throughput per areaM1 at 64 MACsM2, energy per MACM2 at 64 MACs
Nangate45+12.3% (VTA official generated module, 16 × 16)+32.1%+4.1% (VTA official generated module, 16 × 16)-24.5%
ASAP7-7.9% (VTA official generated module, 16 × 16)+17.9%+26.0% (VTA official generated module, 16 × 16)-16.2%
SKY130HD+0.9% (VTA official module, tuned + carry-save, 16 × 16)+21.2%+12.9% (VTA official module, tuned + carry-save, 16 × 16)-23.5%
GF180MCU+32.2% (VTA official generated module, 16 × 16)+51.3%+25.7% (VTA official generated module, 16 × 16)-3.0%
IHP SG13G2+5.6% (VTA hand port, tuned + carry-save, 16 × 16)+18.8%-1.8% (VTA official module, tuned + carry-save, 16 × 16)-28.9%

The 64-MAC columns are the same comparison on the published rows (higher M1 and lower M2 are better; bold: inside ±1 % or reversed). Bits read per useful MAC (M3): -15.9% in every process.

Written before the results: the cycles per token follow from the mappings (CV-GEMV about 17,275 or 17,303, VTA 17,025), so the cycle ratio to VTA stays the base table's; VTA's and OpenGeMM's accumulators only double while their multipliers quadruple, while CV-GEMV's per-row parts grow four times, so the margins over VTA might be smaller than at 64 MACs or reverse. Result: inside ±1 % or reversed: Nangate45 M2 +4.1% (VTA official generated module, 16 × 16); ASAP7 M1 -7.9% (VTA official generated module, 16 × 16); ASAP7 M2 +26.0% (VTA official generated module, 16 × 16); SKY130HD M1 +0.9% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD M2 +12.9% (VTA official module, tuned + carry-save, 16 × 16); GF180MCU M2 +25.7% (VTA official generated module, 16 × 16)

Reported, not used (written before the results): the flow inserts timing-repair buffers, most of them hold buffers on the registers that take an engine's inputs directly (CV-GEMV / VTA's largest count: Nangate45 5546 / 15382; ASAP7 9600 / 9110; SKY130HD 10351 / 7488; GF180MCU 7618 / 13745; IHP SG13G2 10029 / 15146). With every row's timing-repair buffer area left out, M1 margins are Nangate45 +10.2% (64 MACs: +26.2%); ASAP7 -5.9% (64 MACs: +7.0%); SKY130HD +6.6% (64 MACs: +21.0%); GF180MCU +24.4% (64 MACs: +48.8%); IHP SG13G2 +0.3% (64 MACs: +17.3%).

Built with hold repair off after the flow stopped at the hold-repair buffer limit (second fallback, which favours the row): ASAP7 VTA hand port, 16 × 16, ASAP7 VTA hand port, tuned + carry-save, 16 × 16, ASAP7 VTA official generated module, 16 × 16, ASAP7 VTA official module, tuned + carry-save, 16 × 16, ASAP7 VTA official module, tuned, 16 × 16, ASAP7 VTA hand port, tuned, 16 × 16, Nangate45 VTA official generated module, 16 × 16.

Each engine at 256 MACs over itself at 64 MACs

ProcessCV-GEMV areaCV-GEMV M1CV-GEMV M2best VTA row (M1): areaits M1best VTA row (M2): M2
Nangate453.871.031.013.091.290.71
ASAP73.951.011.032.901.510.64
SKY130HD4.170.961.153.471.150.78
GF180MCU3.900.981.003.231.390.72
IHP SG13G23.791.051.003.371.190.72

Gates

  • Nangate45: 11 rows replayed, every output bit-exact; every row meets the target clock; 0 route DRC violations.
  • ASAP7: 11 rows replayed, every output bit-exact; setup missed at the target by VTA hand port, tuned + carry-save, 16 × 16 11.100 ps, VTA official module, tuned, 16 × 16 17.300 ps, VTA official module, tuned + carry-save, 16 × 16 18.600 ps, LogikBench TPU MXU 16 × 16 58.900 ps, VTA hand port, 16 × 16 111.600 ps, VTA hand port, tuned, 16 × 16 173.600 ps, OpenGeMM BlockGemm 1 × 16 × 16 1128.700 ps (scored at their own minimum period); 0 route DRC violations.
  • SKY130HD: 11 rows replayed, every output bit-exact; setup missed at the target by VTA hand port, tuned + carry-save, 16 × 16 0.003 ns, VTA official generated module, 16 × 16 0.040 ns, VTA hand port, tuned, 16 × 16 0.126 ns, VTA official module, tuned, 16 × 16 0.138 ns, VTA hand port, 16 × 16 0.152 ns, OpenGeMM BlockGemm 1 × 16 × 16 6.538 ns (scored at their own minimum period); 0 route DRC violations.
  • GF180MCU: 11 rows replayed, every output bit-exact; setup missed at the target by CV-GEMV r14, PAIR_REG = 1, P = 32 0.410 ns, Plain W8A8 GEMV (baseline), P = 32 0.943 ns, Gemmini mesh 16 × 16, weight-stationary 1.379 ns, VTA official generated module, 16 × 16 3.221 ns, VTA official module, tuned + carry-save, 16 × 16 3.310 ns, VTA official module, tuned, 16 × 16 3.326 ns, VTA hand port, tuned + carry-save, 16 × 16 3.331 ns, LogikBench TPU MXU 16 × 16 3.382 ns, VTA hand port, tuned, 16 × 16 4.446 ns, VTA hand port, 16 × 16 5.256 ns, OpenGeMM BlockGemm 1 × 16 × 16 17.732 ns (scored at their own minimum period); 0 route DRC violations.
  • IHP SG13G2: 11 rows replayed, every output bit-exact; setup missed at the target by OpenGeMM BlockGemm 1 × 16 × 16 1.476 ns (scored at their own minimum period); 0 route DRC violations.

Machines: AWS instance: 23 rows, Azure build VM: 32 rows; each row names its machine and the SHA-256 of its routed netlist.

Reproduction

As written on 2026-11-08 17:49, every 256-MAC row was built and replayed once more from clean folders on the AWS instances, two of the same image and setup (the Azure rows on a second machine, the AWS rows as a clean rerun). Compared per row: the routed netlist's SHA-256, cell area, setup slack, route DRC, the replay's cycles and result lines, and the power. 55 of 55 rows are identical in every field. The margins above use the first run; each row's second-run values are in size256.json (reproduction, rows).

256-MAC JSON ↓ · raw files per row under /evidence/compare/size256/.

Other layers and models at 256 MACs

As written on 2026-11-08 17:49, the eleven projections of the workload-breadth section, with the same integers, on the 256-MAC subject and every 256-MAC comparator row: VTA, the TPU, OpenGeMM and Gemmini replay their 256-MAC routed netlists; CV-GEMV and the W8A8 baseline are built for each new shape, only the shape changed. Smallest margin over the base layer and the projections (the cell least favourable to CV-GEMV), next to the same at 64 MACs (higher M1 and lower M2 are better):

Processsmallest M1 marginat 64 MACssmallest M2 marginat 64 MACsM2 over layer 12at 64 MACs
Nangate45+8.5% (gate_proj)+27.4% (gate_proj)+11.5% (layer 23 down_proj)-22.9% (gate_proj)+6.5%-24.8%
ASAP7-12.0% (o_proj)+13.4% (o_proj)+33.5% (q_proj)-14.3% (q_proj)+30.4%-15.1%
SKY130HD-1.5% (o_proj)+14.6% (o_proj), 9 of 11+13.1% (layer 23 down_proj)-20.5% (Qwen3.5-0.8B down_proj), 9 of 11+11.1%–
GF180MCU+30.6% (gate_proj)+46.4% (gate_proj)+34.5% (gate_proj)-2.6% (gate_proj)+31.0%-3.0%
IHP SG13G2+1.5% (gate_proj)+14.5% (o_proj)-0.8% (gate_proj)-26.2% (layer 23 down_proj)-1.3%-28.4%

605 replays, every output bit-exact. Inside ±1 % or reversed: Nangate45 down_proj (base) M2 +4.1% (VTA official generated module, 16 × 16); Nangate45 q_proj M2 +7.8% (VTA official generated module, 16 × 16); Nangate45 k_proj M2 +7.9% (VTA official generated module, 16 × 16); Nangate45 v_proj M2 +8.3% (VTA official generated module, 16 × 16); Nangate45 o_proj M2 +1.6% (VTA official generated module, 16 × 16); Nangate45 gate_proj M2 +8.4% (VTA official generated module, 16 × 16); Nangate45 up_proj M2 +8.2% (VTA official generated module, 16 × 16); Nangate45 layer 0 down_proj M2 +10.5% (VTA official generated module, 16 × 16); Nangate45 layer 23 down_proj M2 +11.5% (VTA official generated module, 16 × 16); Nangate45 Qwen3.5-0.8B down_proj M2 +3.8% (VTA official generated module, 16 × 16); Nangate45 Qwen3.5-2B down_proj M2 +3.4% (VTA official generated module, 16 × 16); Nangate45 Gemma 4 E2B down_proj M2 +8.2% (VTA official generated module, 16 × 16); ASAP7 down_proj (base) M1 -7.9% (VTA official generated module, 16 × 16); ASAP7 down_proj (base) M2 +26.0% (VTA official generated module, 16 × 16); ASAP7 q_proj M1 -12.0% (VTA official generated module, 16 × 16); ASAP7 q_proj M2 +33.5% (VTA official generated module, 16 × 16); ASAP7 k_proj M1 -11.3% (VTA official generated module, 16 × 16); ASAP7 k_proj M2 +32.6% (VTA official generated module, 16 × 16); ASAP7 v_proj M1 -11.3% (VTA official generated module, 16 × 16); ASAP7 v_proj M2 +33.2% (VTA hand port, 16 × 16); ASAP7 o_proj M1 -12.0% (VTA official generated module, 16 × 16); ASAP7 o_proj M2 +26.9% (VTA official module, tuned + carry-save, 16 × 16); ASAP7 gate_proj M1 -11.9% (VTA official generated module, 16 × 16); ASAP7 gate_proj M2 +33.1% (VTA official generated module, 16 × 16); ASAP7 up_proj M1 -11.9% (VTA official generated module, 16 × 16); ASAP7 up_proj M2 +32.9% (VTA official generated module, 16 × 16); ASAP7 layer 0 down_proj M1 -7.9% (VTA official generated module, 16 × 16); ASAP7 layer 0 down_proj M2 +29.9% (VTA official generated module, 16 × 16); ASAP7 layer 23 down_proj M1 -7.9% (VTA official generated module, 16 × 16); ASAP7 layer 23 down_proj M2 +30.8% (VTA official generated module, 16 × 16); ASAP7 Qwen3.5-0.8B down_proj M1 -6.9% (VTA official generated module, 16 × 16); ASAP7 Qwen3.5-0.8B down_proj M2 +25.6% (VTA official generated module, 16 × 16); ASAP7 Qwen3.5-2B down_proj M1 -7.4% (VTA official generated module, 16 × 16); ASAP7 Qwen3.5-2B down_proj M2 +26.4% (VTA official generated module, 16 × 16); ASAP7 Gemma 4 E2B down_proj M1 -6.9% (VTA official generated module, 16 × 16); ASAP7 Gemma 4 E2B down_proj M2 +29.7% (VTA official generated module, 16 × 16); SKY130HD down_proj (base) M1 +0.9% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD down_proj (base) M2 +12.9% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD q_proj M1 -1.5% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD q_proj M2 +10.1% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD k_proj M2 +7.0% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD v_proj M2 +7.5% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD o_proj M1 -1.5% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD o_proj M2 +12.5% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD gate_proj M1 -1.1% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD gate_proj M2 +10.2% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD up_proj M1 -1.1% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD up_proj M2 +10.1% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD layer 0 down_proj M1 +0.9% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD layer 0 down_proj M2 +12.7% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD layer 23 down_proj M1 +0.9% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD layer 23 down_proj M2 +13.1% (VTA official generated module, 16 × 16); SKY130HD Qwen3.5-0.8B down_proj M2 +9.7% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD Qwen3.5-2B down_proj M2 +9.0% (VTA official module, tuned + carry-save, 16 × 16); SKY130HD Gemma 4 E2B down_proj M2 +12.7% (VTA official module, tuned + carry-save, 16 × 16); GF180MCU down_proj (base) M2 +25.7% (VTA official generated module, 16 × 16); GF180MCU q_proj M2 +33.9% (VTA official generated module, 16 × 16); GF180MCU k_proj M2 +33.4% (VTA official generated module, 16 × 16); GF180MCU v_proj M2 +34.1% (VTA official generated module, 16 × 16); GF180MCU o_proj M2 +26.1% (VTA official generated module, 16 × 16); GF180MCU gate_proj M2 +34.5% (VTA official generated module, 16 × 16); GF180MCU up_proj M2 +34.3% (VTA official generated module, 16 × 16); GF180MCU layer 0 down_proj M2 +30.5% (VTA official generated module, 16 × 16); GF180MCU layer 23 down_proj M2 +31.3% (VTA official generated module, 16 × 16); GF180MCU Qwen3.5-0.8B down_proj M2 +25.2% (VTA official generated module, 16 × 16); GF180MCU Qwen3.5-2B down_proj M2 +27.0% (VTA official generated module, 16 × 16); GF180MCU Gemma 4 E2B down_proj M2 +31.5% (VTA official generated module, 16 × 16); IHP SG13G2 gate_proj M2 -0.8% (VTA hand port, tuned + carry-save, 16 × 16); IHP SG13G2 up_proj M2 -1.0% (VTA hand port, tuned + carry-save, 16 × 16). New builds that miss the target clock, scored at their own minimum period: GF180MCU CV-GEMV r14, PAIR_REG = 1, P = 32 1,024 × 3,584 by 0.160 ns, GF180MCU CV-GEMV r14, PAIR_REG = 1, P = 32 128 × 896 by 0.166 ns, GF180MCU CV-GEMV r14, PAIR_REG = 1, P = 32 1,536 × 12,288 by 0.152 ns, GF180MCU CV-GEMV r14, PAIR_REG = 1, P = 32 2,048 × 6,144 by 0.339 ns, GF180MCU CV-GEMV r14, PAIR_REG = 1, P = 32 2,432 × 896 by 0.252 ns, GF180MCU CV-GEMV r14, PAIR_REG = 1, P = 32 896 × 896 by 0.115 ns, GF180MCU Plain W8A8 GEMV (baseline), P = 32 1,024 × 3,584 by 0.872 ns, GF180MCU Plain W8A8 GEMV (baseline), P = 32 128 × 896 by 0.966 ns, GF180MCU Plain W8A8 GEMV (baseline), P = 32 1,536 × 12,288 by 0.767 ns, GF180MCU Plain W8A8 GEMV (baseline), P = 32 2,048 × 6,144 by 0.631 ns, GF180MCU Plain W8A8 GEMV (baseline), P = 32 4,864 × 896 by 1.086 ns, GF180MCU Plain W8A8 GEMV (baseline), P = 32 896 × 896 by 0.806 ns, IHP SG13G2 Plain W8A8 GEMV (baseline), P = 32 1,536 × 12,288 by 0.007 ns, SKY130HD CV-GEMV r14, PAIR_REG = 0, P = 32 896 × 896 by 0.030 ns; route DRC 0 on every new build. Written before the results: CV-GEMV's fixed cycles per row block do not depend on P, so its M1 margins on the 896-column projections were expected several points smaller than on the base layer, as at 64 MACs. Result: the smallest M1 margin is 1.6 to 4.1 points below the base layer's in every process.

256-MAC workloads JSON ↓ · raw files under /evidence/compare/workloads256/.

Which size a memory keeps busy

Reported, not used (rule written 2026-11-08 18:18, before any 256-MAC metric). In single-token decoding every weight is read once per token, so a memory of peak bandwidth BW feeds at most 8 × BW / M3 useful MACs per second, M3 being CV-GEMV's measured bits per useful MAC on the base layer at 256 MACs (4.625). Divided by the 256-MAC row's clock and utilization this is the number of MACs per cycle that keeps up; the table gives the smallest power of two from 64 to 4,096 not below it. Peak bandwidths are from the JEDEC standards (transfer rate × bus width / 8); a real controller reaches less, so every size is an upper bound. * not a measured size (computed from the 256-MAC row's clock, utilization and M3, which another size would change).

Memorypeak GB/sNangate45ASAP7SKY130HDGF180MCUIHP SG13G2Qwen2.5-0.5B tokens/s, upper bound
LPDDR4X-4266 x3217.1128*6425625625660
LPDDR5-6400 x3225.625664512*512*512*90
LPDDR5X-8533 x1617.1128*6425625625660
LPDDR5X-8533 x3234.125664512*512*512*120
LPDDR5X-8533 x6468.3512*128*1,024*1,024*1,024*239
LPDDR5X-8533 x128136.51,024*2562,048*2,048*2,048*478
LPDDR5X-8533 x256273.12,048*512*4,096*4,096*4,096*956
HBM3-6400 x1024 (one stack)819.2> 4,0962,048*> 4,096> 4,096> 4,0962,869

The token rate counts the seven projections of each of the 24 layers and the 151,936 × 896 output projection (493,961,216 MACs per token), nothing else. Bandwidth the measured rows themselves read at their clocks (GB/s):

Processclock, MHzCV-GEMV, 64 MACsCV-GEMV, 256 MACsW8A8 baseline, 256 MACs
Nangate4525010.636.565.5
ASAP7100042.3145.6261.8
SKY130HD1255.318.232.7
GF180MCU1195.317.329.3
IHP SG13G21255.318.232.7

Written before the results: on LPDDR5X-8533 x64 the size was expected to be 128 or 256 in every process. Result: Nangate45 512, ASAP7 128, SKY130HD 1024, GF180MCU 1024, IHP SG13G2 1024 MACs, so the expectation did not hold in Nangate45, SKY130HD, GF180MCU, IHP SG13G2.

Sizing JSON ↓

Another shape at 256 MACs: 16 rows of 16 columns

The 256-MAC rows above build CV-GEMV r14 as 32 rows of 8 columns per cycle. As written on 2026-11-10 11:20, before any flow, replay or power of the rows below, a later revision, r15, was built as 16 rows of 16 columns per cycle: the same 256 MACs per cycle, the same integers, the same two tokens and the same outputs. Each process uses the flow settings and target clock of its 256-MAC r14 row; only the source file, its parameters and the names changed. Three builds per process differ in the pipeline registers of the dot product (PAIR_REG = 0, 2 and 1, fewest flip-flops first). The shape and the PAIR_REG = 2 setting were fixed after the 256-MAC results above, from RTL replays and synthesis areas, before any flow of an r15 row; a second shape (8 rows of 32 columns) was looked at by synthesis only and is not measured. The comparator rows are the published 256-MAC rows above, not rebuilt. No verdict changes: the verdicts' subject stays r14, and r15's RTL is not public, as r14's is not.

Checks before any flow: built at r14's shapes, the r15 source gives the published replay lines of 3 of 3 published rows exactly (64 MACs and 256 MACs); at 16 × 16 all 3 of 3 builds replay bit-exact at RTL, and the expected outputs are the published 256-MAC row's file, byte for byte.

The row reported for each process

Chosen by timing only, before any power or metric was read: the first of the three builds, in the order below, that meets the target clock with 0 route DRC violations; if none does, the one with the shortest minimum period. Setup slack at the target clock (bold: chosen):

ProcessPAIR_REG = 0PAIR_REG = 2PAIR_REG = 1Reported row
Nangate45+1.928 ns+2.292 ns+2.358 nsPAIR_REG = 0
ASAP7-108 ps+57 ps+147 psPAIR_REG = 2
SKY130HD-0.231 ns+0.674 ns+1.621 nsPAIR_REG = 2
GF180MCU-5.935 ns-2.746 ns-0.992 nsPAIR_REG = 1 (none meets the target: shortest minimum period)
IHP SG13G2+0.739 ns+1.791 ns+1.949 nsPAIR_REG = 0

Margin over the best 256-MAC comparator row

ProcessM1, throughput per arear14's M1 marginM2, energy per MACr14's M2 margin
Nangate45+26.9% (VTA official generated module, 16 × 16)+12.3%-4.2% (VTA official generated module, 16 × 16)+4.1%
ASAP7+9.4% (VTA official generated module, 16 × 16)-7.9%+4.3% (VTA official generated module, 16 × 16)+26.0%
SKY130HD+18.1% (VTA official module, tuned + carry-save, 16 × 16)+0.9%-2.6% (VTA official module, tuned + carry-save, 16 × 16)+12.9%
GF180MCU+36.1% (VTA official generated module, 16 × 16)+32.2%+21.3% (VTA official generated module, 16 × 16)+25.7%
IHP SG13G2+15.4% (VTA hand port, tuned + carry-save, 16 × 16)+5.6%-13.0% (VTA official module, tuned + carry-save, 16 × 16)-1.8%

The r14 columns are the margins of the 256-MAC table above, against the same comparator rows (higher M1 and lower M2 are better; bold: inside ±1 % or reversed). Bits read per useful MAC (M3): 4.875, -11.4% in every process (r14: 4.625, -15.9%); with 16 rows per cycle in place of 32, each activation is read twice as often.

r15 at 16 × 16 over r14 at 32 × 8, same process

Processr15 buildr14 row's settingcell areacycles per tokenM1M2
Nangate45PAIR_REG = 0PAIR_REG = 00.8781.0081.1300.920
ASAP7PAIR_REG = 2PAIR_REG = 10.8351.0101.1870.828
SKY130HDPAIR_REG = 2PAIR_REG = 00.8451.0111.1700.863
GF180MCUPAIR_REG = 1PAIR_REG = 10.9001.0101.0290.966
IHP SG13G2PAIR_REG = 0PAIR_REG = 00.9081.0081.0930.886

Written before the results: by synthesis areas and cycle counts, M1 was expected to rise by about 10 % where PAIR_REG = 0 is chosen and about 18 % where PAIR_REG = 2 is chosen in place of r14's PAIR_REG = 1, and energy per MAC to fall most where PAIR_REG = 2 is chosen; whether r14's reversed margins would turn was not known. Result: M1 over r14 Nangate45 +13.0%; ASAP7 +18.7%; SKY130HD +17.0%; GF180MCU +2.9%; IHP SG13G2 +9.3%; energy per MAC over r14 Nangate45 -8.0%; ASAP7 -17.2%; SKY130HD -13.7%; GF180MCU -3.4%; IHP SG13G2 -11.4%; inside ±1 % or reversed with r14 and no longer with r15: Nangate45 M2, ASAP7 M1, SKY130HD M1, SKY130HD M2; still inside ±1 % or reversed: ASAP7 M2 +4.3% (VTA official generated module, 16 × 16); GF180MCU M2 +21.3% (VTA official generated module, 16 × 16).

All three builds

ProcessBuildSetup slackMinimum periodRoute DRCCell area (µm²)Cycles per tokenM1 GMAC/s per mm² ↑M2 pJ per useful MAC ↓Replay
Nangate45PAIR_REG = 0+1.928 ns2.070 ns085,312.917,416733.30.648PASS, chosen
Nangate45PAIR_REG = 2+2.292 ns1.710 ns090,002.417,472692.90.688PASS, not chosen
Nangate45PAIR_REG = 1+2.358 ns1.640 ns096,544.417,472645.90.760PASS, not chosen
ASAP7PAIR_REG = 0-108 ps1108 ps07,637.817,41629,567.90.127PASS, not chosen
ASAP7PAIR_REG = 2+57 ps943 ps07,499.417,47233,260.90.128PASS, chosen
ASAP7PAIR_REG = 1+147 ps853 ps07,709.317,47232,355.20.138PASS, not chosen
SKY130HDPAIR_REG = 0-0.231 ns8.230 ns0518,06817,41658.74.002PASS, not chosen
SKY130HDPAIR_REG = 2+0.674 ns7.330 ns0485,21317,47264.33.708PASS, chosen
SKY130HDPAIR_REG = 1+1.621 ns6.380 ns0512,70417,47260.84.255PASS, not chosen
GF180MCUPAIR_REG = 0-5.935 ns13.940 ns02,408,910.017,4167.596.117PASS, not chosen
GF180MCUPAIR_REG = 2-2.746 ns10.750 ns02,515,690.017,4729.2102.033PASS, not chosen
GF180MCUPAIR_REG = 1-0.992 ns8.990 ns02,530,750.017,47211.0107.708PASS, chosen
IHP SG13G2PAIR_REG = 0+0.739 ns7.260 ns0979,99017,41631.93.099PASS, chosen
IHP SG13G2PAIR_REG = 2+1.791 ns6.210 ns01,015,950.017,47230.73.311PASS, not chosen
IHP SG13G2PAIR_REG = 1+1.949 ns6.050 ns01,034,530.017,47230.13.883PASS, not chosen

Gates

  • Nangate45: 3 builds replayed, every output bit-exact; every build meets the target clock; 0 route DRC violations.
  • ASAP7: 3 builds replayed, every output bit-exact; setup missed at the target by PAIR_REG = 0 108 ps (scored at their own minimum period); 0 route DRC violations.
  • SKY130HD: 3 builds replayed, every output bit-exact; setup missed at the target by PAIR_REG = 0 0.231 ns (scored at their own minimum period); 0 route DRC violations.
  • GF180MCU: 3 builds replayed, every output bit-exact; setup missed at the target by PAIR_REG = 0 5.935 ns, PAIR_REG = 2 2.746 ns, PAIR_REG = 1 0.992 ns (scored at their own minimum period); 0 route DRC violations.
  • IHP SG13G2: 3 builds replayed, every output bit-exact; every build meets the target clock; 0 route DRC violations.

Reproduction

Each reported row was built and replayed once more from a clean folder on the other AWS instance (two instances of the same image and setup). Compared per row: the routed netlist's SHA-256, cell area, setup slack, route DRC, the replay's cycles and result lines, and the power. 5 of 5 rows are identical in every field. The margins use the first run; the second run's values are in the JSON (reproduction, rows).

16 × 16 JSON ↓ · raw files per build under /evidence/compare/lanes256/.

r16 at 256 MACs: ASAP7 and GF180MCU

This two-process pilot evaluates CV-GEMV r16 at 16 rows × 16 columns per cycle, using the same integer workload and two tokens as the r15 study above. The target clocks and flow conditions are unchanged. Area, timing and energy are tool estimates from routed layouts and replay activity. The reference rows are the published r15 and 256-MAC comparator rows; they were not rebuilt for this pilot. The margins below use the first run.

The verdict above evaluates r14. The r16 results apply to ASAP7 and GF180MCU. The measurement and reproduction status is complete. Timing and performance criteria are shown separately below.

Measured results

ProcessM1 GMAC/s/mm² ↑M2 pJ/MAC ↓M3 bit/MAC ↓Area (µm²)Cycles/tokenReplay
ASAP733,781.40.1278744.8757,383.817,472PASS
GF180MCU11.080108.5911514.8752,648,450.017,472PASS

Margins against the reference rows

ProcessMetricr16r15Best rowBest valuevs. bestvs. r15
ASAP7M133,781.433,260.9vta16_official30,416.2+11.1%+1.6%
ASAP7M20.1278740.127711vta16_official0.122459+4.4%+0.1%
ASAP7M34.8754.875vta165.500-11.4%+0.0%
GF180MCUM111.08010.964vta16_official8.057+37.5%+1.1%
GF180MCUM2108.591151107.708136vta16_official88.762214+22.3%+0.8%
GF180MCUM34.8754.875vta165.500-11.4%+0.0%

Higher M1 and lower M2/M3 are better. The best comparator is chosen separately for each metric. Bold margins are within ±1% or worse; a margin within ±1% is not a win. ASAP7: M1 better, M2 worse, M3 better; GF180MCU: M1 better, M2 worse, M3 better.

Clocks and routing checks

ProcessTargetSetup slackMin. periodM1 periodM2 periodRoute DRC
ASAP71000 ps+139 ps (met)861 ps1000 ps1000 ps0
GF180MCU8.000 ns-0.503 ns (missed)8.500 ns8.500 ns8.000 ns0

M1 uses the target period when setup is met and otherwise the layout's minimum period. M2 remains the activity-based power estimate at the common target period. When setup is missed, that M2 value is not an energy measurement at a clock that the layout meets. Storage and host work are excluded from both designs, as in the published comparison.

Reproduction

ProcessFirst runSecond runFields comparedResult
ASAP7AWS instance 1AWS instance 29identical (other instance)
GF180MCUAWS instance 1AWS instance 29identical (other instance)

Compared fields: routed-netlist SHA-256, cell area, setup slack, route DRC, cycles per token, replay-result SHA-256, workload power, replay result, flow-setting fingerprint. 2 of 2 reproduced rows are identical in all listed fields; 2 were reproduced on the other instance. The second-run values and differences are in the JSON. Equal replay results do not by themselves establish timing or energy superiority.

r16 JSON ↓ · public report summaries under /evidence/compare/r16/.

Model accuracy by weight format

Same model, same text, same harness; activations are per-token INT8 for every format; only the weight format changes. Perplexity increase over 8 pre-registered windows of 512 tokens. All formats use plain round-to-nearest encoding without calibration (GPTQ, AWQ or rotations could change the order).

Weight formatAll 168 projectionsLayer 12 down_proj only
CV-GEMV format: INT4, 32-column groups, 8-bit integer scale and 4-bit zero point+14.1%+0.05%
INT4, 32-column groups, floating-point scale and zero point+14.0%+0.04%
NVFP4 (E2M1, 16-element blocks, E4M3 scale)+16.3%+0.06%
INT4, 128-column groups, floating-point scale and zero point+22.3%-0.09%
MXFP4, shared exponent rounded up+25.7%+0.09%
MXFP4, shared exponent as in the OCP specification+27.7%+0.10%

The pass line asks that the CV-GEMV format (+14.1%) not be worse than INT4 with 128-column groups (+22.3%) and MXFP4 at its better encoder (+25.7%). NVFP4 (+16.3%) is reported, not part of the pass line.

Recent models

The same check on recent open models (weights rounded the same way, every linear layer of the language decoder quantized, the model's own tokenizer). Pinned revisions are in models.json.

Weight formatQwen2.5-0.5BQwen3.5-0.8BQwen3.5-2Bgemma-4-E2B
CV-GEMV format: INT4, 32-column groups, 8-bit integer scale and 4-bit zero point+14.1%+9.8%+5.9%+17.7%
INT4, 32-column groups, floating-point scale and zero point+14.0%+9.2%+5.9%+17.3%
NVFP4 (E2M1, 16-element blocks, E4M3 scale)+16.3%+10.4%+5.3%+14.1%
INT4, 128-column groups, floating-point scale and zero point+22.3%+16.4%+8.0%+36.5%
MXFP4, shared exponent rounded up+25.7%+17.8%+10.1%+30.9%
MXFP4, shared exponent as in the OCP specification+27.7%+16.2%+11.3%+26.0%

NVFP4 loses less accuracy than the CV-GEMV format on Qwen3.5-2B, gemma-4-E2B. It is reported, not part of the pass line.

Gates

  • G1 (nangate45), gate-level replay of the real tokens, 0 output mismatches: pass
  • G2 (nangate45), final netlist formally equivalent to synthesis: pass
  • G3 (nangate45), 0 routing DRC violations and the target clock met: pass
  • G1 (asap7), gate-level replay of the real tokens, 0 output mismatches: pass
  • G2 (asap7), final netlist formally equivalent to synthesis: pass
  • G3 (asap7), 0 routing DRC violations and the target clock met: pass
  • G4, a second, independent run reproduces the table: pass: on a second machine, 22 of 22 rows reproduced, 0 differences (table); from clean directories on the build machine, 22 of 22 rows reproduced, 0 differences (table)

Independent review

Round 1 (2026-11-06): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/, the comparison pages. Conclusion: disagree. The reviewer recomputed M1–M3 for 10 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1the verdictG4 accepts matching subject rows without requiring all comparator rows or evidence of a clean-machine run. The supplied rerun has only eight rows: it omits official VTA, OpenGeMM and Gemmini in both processes. The separate-machine record covers only Nangate45 CV-GEMV and official VTA, and only layout hashes and selected flow metrics—not the complete workload-power table. Thus RULES.md line 61's complete-table reproduction requirement is not established, despite verdict.json and the page marking G4 pass.re-measuredverdict.py now requires every verdict row, both processes, reproduced with every number equal on a second machine (and in any clean rerun). The six missing comparator rows are being rerun from clean directories, and the full table on a second machine. Done: both second runs reproduce all 14 rows with every number equal.
2a metricInteger division truncates 136195 cycles over two tokens to 68097 rather than 68097.5. Both OpenGeMM M1 values are overstated by approximately 0.000734%. This favours the comparator and does not reverse the metric outcome.fixedExact division in collect.py. The rounding favoured OpenGeMM by 0.0007 %; no metric outcome changes.
3a metricTPU and Gemmini replay only token 0, while CV-GEMV, VTA, OpenGeMM and W8A8 replay tokens 0 and 1. Normalizing useful MACs does not make their switching workloads identical. The direction and size of any energy bias remain unmeasured; the page's claim that every engine replays the same real tokens is inaccurate.disclosed, not re-measuredPage and rules now state that the TPU and Gemmini replay the first token and the others two. Their energy per useful MAC is about ten times CV-GEMV's, so the token set cannot change the outcome.
4page wordingThe assertion that post-result changes can only favour comparators conflicts with the documented r1-to-r7 subject optimization and process-specific subject selection. Both Nangate45 r7 settings meet timing, so 'the setting that meets the target clock' does not uniquely select PAIR_REG=0. That setting wins M1; PAIR_REG=1 loses. The explicit amended subject names are implemented correctly, but their selection is not demonstrated to be independent of results.fixedRules and page now say that two post-result changes concern CV-GEMV (r2 to r7, and PAIR_REG fixed per process after the first results; on Nangate45 both settings meet the clock and the smaller layout was chosen). The claim names the configuration.
5page wordingThe W8A8 baseline uses separately quantized per-row INT8 weights, not the W4A8-G32 integers. Its PASS means agreement with its own reference. The baseline is labelled elsewhere, but this universal arithmetic statement is false.fixedPage: every W4A8 engine computes the same integers; the W8A8 baseline is excepted.
6page wordingThe 4.9× energy ratio described as 'same RTL' uses Nangate45 PAIR_REG=0 and ASAP7 PAIR_REG=1. It therefore combines process changes with a different register configuration and cycle count. The arithmetic is reproducible, but this is not a controlled same-configuration process ratio.fixedThe scaling ratio now uses one configuration (PAIR_REG = 1) in both processes (5.6x).
7page wordingThe parenthetical assigns +14.0% versus +14.1% in the opposite order to the sentence's CV-GEMV-versus-floating-scale comparison. CV-GEMV is +14.131%; floating-scale INT4 g32 is +13.974%. The accuracy table itself has the correct order.fixedOrder corrected.
8noneCV-GEMV RTL, testbench, config.mk and integer fixtures are absent. Its M3 arithmetic reproduces 5.375 from read_count and assumed metadata reads, but the interface widths and metadata-read schedule cannot be independently checked against its implementation here. Likewise, identical utilization settings and cycle_count semantics cannot be fully audited for the subject. This is a disclosed evidence limit, not a demonstrated numerical error.no changeCV-GEMV RTL, testbench and flow configs are supplied under an evaluation agreement; the limit is disclosed in the package README.
9noneM2 can be reproduced from raw workload power and the supplied window_s, but the underlying SAIF DURATION and activity annotations cannot be independently audited because activity.saif is not included. Agreement with result.json does not independently establish that window extraction was correct.fixedEach row folder now has activity-header.txt: the SAIF header (timescale, duration) and the SHA-256 of the full SAIF.

Round 2 (2026-11-06): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/, the comparison pages. Conclusion: confirm. The reviewer recomputed M1–M3 for 10 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1page wordingThe claimed fix is incomplete: activity-header.txt is absent for OpenGeMM and Gemmini in both processes. The other 26 headers have 1 ps timescales and durations matching result.json.window_s. For the four missing headers, M2 reproduces using window_s, but its duration cannot be independently checked against a supplied SAIF header. Headers also do not expose full switching activity.fixedOpenGeMM and Gemmini were first replayed on the build VM, whose SAIF was not kept. Their activity-header.txt now comes from the clean rerun of the same routed netlist (whose numbers equal the first run's), and the file says so.
2noneG4 checks only a whitelist, despite stating that every number must match. Numeric fields including die_area_um2, clock_used_mhz, useful_mac_per_s, utilization and the secondary metrics are omitted. This is a latent validation gap: independently comparing all supplied row fields found no differences, so it does not invalidate this verdict.fixedG4 now compares every scalar field of every needed row, not a list of fields.
3noneThe documented verdict commands omit --second-machine. With the revised code, these commands necessarily fail G4 and cannot reproduce the published reached verdict. The description that verdict.py reads only summary.json and formats.json is insufficient for a passing G4.fixedThe package README gives the verdict command with --second-machine and --rerun.
4a metricThe round-1 workload difference remains: TPU and Gemmini replay token 0 only, whereas the other engines replay two tokens. Their M2 values therefore describe different activity samples. This is now explicitly disclosed and permitted by the dated rules; it is not a newly discovered arithmetic error or a demonstrated reversal.re-measuredThe second token was replayed on the TPU and Gemmini netlists in both processes; energy per useful MAC changes by at most 0.04 % (token-check.json).
5noneThe disclosed round-1 evidence limitation remains: CV-GEMV RTL, testbench and config.mk are absent. Its 5.375-bit M3 reproduces from logged read_count and the stated metadata schedule, but the actual interface, metadata enables, cycle-counter semantics and utilization configuration cannot be independently inspected here. Public comparator interfaces support their stated bases and exclusions.no changeCV-GEMV RTL, testbench and flow configs are supplied under an evaluation agreement; disclosed.

Round 3 (2026-11-07): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/, before-13/summary.json, the comparison pages. Conclusion: confirm (main verdict, r11), confirm (open PDKs). The reviewer recomputed M1–M3 for 11 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1noneThe code accepts vacuous equivalence and cites a G2 exception absent from RULES.md. The IHP subject's lec.txt explicitly reports no valid outputs to compare. G1 replay cannot establish the formal equivalence required by G2. G2 should fail or remain unestablished. This does not change the current open-PDK 'not reached' outcome, already forced by GF180 timing.fixedG2 in the open-PDK verdict now marks a vacuous equivalence check as open (pass: false) and notes on the page that G1 real-token replay passes.
2noneThe named lockstep.sh is absent from this folder. The six summary log lines report zero mismatches, but without the driver its randomization, extreme-value stretches, reset coverage and comparison predicates cannot be independently inspected. The supplied real-layer testbench and four matching replay logs support unchanged results on those inputs, not exhaustive sequential equivalence.fixedmake_package.py now includes vta/tuned/lockstep.sh and the generated w5 official VTA module in reproduce.zip.
3page wordingThe three advertised VTA edits are present and mathematically sound, but they do not establish exhaustive optimization parity. VTA still uses cascaded carry-propagating additions for its multioperand dot-product reduction; CV-GEMV received carry-save arithmetic. A carry-save reduction is also applicable to VTA's combinational reduction without adding pipeline stages. Its benefit or harm has not been measured. Conversely, CV-GEMV's group-scale sharing and waiting-group changes have no direct counterpart in this VTA core.fixedThe page and vta-tuned/summary.json now state that VTA received the three changes from r9 and r10 that VTA's structure has, and that VTA's combinational dot-product adder tree is unchanged.
4page wording'Registers ... unchanged' is imprecise: register positions and pipeline depth remain unchanged, but registered product widths shrink and accumulator registers update during invalid cycles. Valid-result behavior is preserved by the inspected logic; internal state and invalid-cycle data are not identical.fixedChanged to 'pipeline stages, valid-result latency and results unchanged' on the page and in vta-tuned/summary.json.
5noneThe open-PDK verdict says M4b carries over, but its outcome never incorporates the main M4b result. A future format-accuracy failure could therefore leave the open-PDK code verdict reached. All supplied M4b comparisons pass, so this is a latent validation defect, not a current reversal.fixedopdk_verdict now includes M4b in its metric pass check.
6page wording'All of them stay in the table' is true of summary.json, but the rendered tables omit six earlier CV-GEMV configurations per main process: r2, r2d, r3d, r4d, r5d and r6d. No evidence rows were deleted; the page should distinguish its displayed subset from the complete downloadable table.fixedThe page now says that all of them stay in summary.json and that the tables on the page show r1 and r7 to r11.
7page wordingThe earlier r7 verdict is described as 'confirmed by two reviews', but the page's own review record says round 1 disagreed and round 2 confirmed after corrections.fixedChanged to 'confirmed in round 2 after round 1's findings were fixed'.
8noneThe documented command omits --opdk-second-machine, so it cannot reproduce the published open-PDK G4 pass or the complete verdict.json. Several surrounding descriptions also still identify r7 as the current subject.fixedThe package README now includes --opdk-second-machine in the verdict commands and updates the revision descriptions through r11.
9page wordingThe introductory accounting of post-result changes is stale: RULES.md mentions subject development only through r7, while the page's closing explanation stops at r10. The dated additions and open-PDK history correctly describe r11. The supplied dated prose alone does not independently prove the claim that each rule was committed before its result.fixedRULES.md and the page's 'How the verdict is made' section now both state r2 to r11 and the 2026-11-07 subject-rule amendment.
10noneThe disclosed implementation-evidence limit remains: CV-GEMV RTL and its testbench are unavailable. Its M3 reproduces as (68096×320 + 152×112×8×12)/(896×4864) = 5.375, but the actual metadata-read schedule and counter semantics cannot be independently inspected. VTA's public interface and replay support 5 + 8/8 = 6 bits per useful MAC, with host/storage exclusions as written.no changeCV-GEMV RTL, testbench and flow configs are supplied under an evaluation agreement; disclosed.

Round 4 (2026-11-07): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/, before-csa/summary.json, the comparison pages. Conclusion: confirm (main verdict, r11), confirm (open PDKs). The reviewer recomputed M1–M3 for 15 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1noneThe published corrected logs contain only 'SAT solver finished: UNSAT' and 'Circuits are IDENTICAL'. They omit collected-output counts and database/netlist provenance. The scripts correctly invoke the flow's writer and checker on the row's base databases with only bondpad_70* removed, but these excerpts do not independently establish the requested non-vacuous output collection. This is an evidence gap, not evidence that the corrected comparison was vacuous.fixedlec.txt of every IHP SG13G2 row now also lists the databases read, the two netlists compared and the collected input and output counts (2,825 outputs for the r11c subject); all 36 IHP rows were re-run on both machines with that record, all identical.
2noneOpen-PDK G4 checks the second-machine table but never checks the supplied clean rerun. The published clean-rerun table contains only Nangate45/ASAP7, so it does not substantiate the 08:33 addition's statement that the new rows were measured on the clean rerun in all five processes. All 33 required open-PDK rows are present and scalar-identical on the second machine.fixedThe public text of the 08:33 addition now carries the parenthesis of the internal original written at the same time: the clean rerun covers Nangate45 and ASAP7. The open-PDK G4 uses the second machine, as its rule says.
3page wordingThe assertion that the original flow compared empty netlists 'for every engine' exceeds the supplied records: ihp-sg13g2-tpu8/lec-flow.txt says 'no final LEC log'. The other 19 IHP flow excerpts explicitly report vacuous equivalence.fixedThe page and both rule files now say: every IHP row whose flow ran the check compared empty netlists; the TPU's flow left no final check log.
4page wordingThis unqualified statement conflicts with the disclosed later subject, comparator, G2 and second-machine amendments. The initial open-PDK extension preceded results; the complete current rules did not.fixedThe open-PDK section now says its conditions were fixed before the first open-PDK result and that later changes are dated in the rules.
5noneThe lock-step stimulus exercises common valid gaps, not independently varying input-valid signals, and resets rst only initially. Its six passing runs support sampled valid-result equivalence, not exhaustive sequential equivalence. Inspection shows the relevant valid/reset logic is unchanged, so this does not reveal a functional defect.no changeKept as stated: the lock-step checks common valid gaps and the initial reset; the arithmetic identity is argued separately. A stimulus with independent valid inputs and midstream reset is a follow-up.
6noneM3 reproduces as 5.375 from tb_read_count and the stated metadata accounting, but private CV-GEMV RTL/testbench prevents independent inspection of the actual metadata-read schedule. This inherited evidence limit remains unchanged.no changeInherited, disclosed limit: CV-GEMV RTL, testbench and flow configs are under an evaluation agreement.

Round 5 (2026-11-07): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/ (sensitivity.json, sensitivity/), the comparison pages. Scope: the flow-setting study only, not the verdicts. Conclusion: disagree. The reviewer recomputed M1 and M2 for 30 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1page wordingThe claim of the same routed netlist on the build machine, Mac and AWS exceeds the supplied evidence. second-machine.json records each row against either Mac or AWS, not both. For example, ASAP7 vta8_csa and vta8_official_csa have AWS comparisons, while the ASAP7 subject has a Mac comparison. G4 establishes scalar-table equality on the required second machine; it does not establish three-machine netlist identity or universal determinism.fixedThe opening sentence now says what was checked: one second machine per row (the Mac or AWS) reproduced every number in the table (G4), with the same routed netlist for 22 of 22 main-verdict rows, and the three ASAP7 rows run again at the published setting reproduced every number on AWS. The clock, DRC and replay sentence is limited to the rule's four variants, and the added 55 % run's VTA hand-port row that misses 1000 ps by 0.30 ps is stated under the added table.
2noneSelecting competitors using only baseline performance can favour CV-GEMV if an excluded VTA row improves more under a changed setting. For example, SKY130HD vta8_official_tuned is excluded with M1 only 5.2071% below the baseline best and M2 7.4794% above it. Its variant performance is unmeasured. This is a limitation of the selected-row study, not an incorrect application of its rule or a demonstrated reversal.fixedThe 14 VTA rows the 14:34 rule left out were run under the same four variants, and ASAP7's four of them also at 45 and 55 % (rules, 2026-11-07 18:48, committed before the runs). Against the best of all six VTA rows no metric reverses or comes within 1 % in any variant, and no left-out row is VTA's best, so the margins equal the rule's (smallest GF180MCU M2 -2.9 %, density add-on 0.15). Both pages report this apart from the rule's result, and the limit paragraph is gone. Round 7 checked it.

Round 6 (2026-11-07): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/ (sensitivity.json, sensitivity/, review.json round 5), the comparison pages. Scope: the flow-setting study only, not the verdicts. Conclusion: confirm. The reviewer recomputed M1 and M2 for 2 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did

Round 7 (2026-11-08): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/ (sensitivity.json, sensitivity/ incl. all-vta/, review.json rounds 5-6), the comparison pages and the CV-GEMV page. Scope: the flow-setting study only, not the verdicts. Conclusion: confirm. The reviewer recomputed M1 and M2 for 22 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did

Round 8 (2026-11-08): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/, the table before the r12 to r14 rows (before-r12/summary.json), the comparison pages and the CV-GEMV page. Conclusion: confirm (main verdict, r14), confirm (open PDKs). The reviewer recomputed M1–M3 for 17 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1page wordingThe sensitivity summary still gives r11 margins: Nangate45 +29.9%/-23.9% and ASAP7 +18.4%/-16.0%. For r14 the smallest margins across the published setting and four variants are +32.1%/-24.2% and +17.6%/-15.4%, respectively. The later 'current subject (r14)' table is correct.fixedThe last bullet of 'Where the margin is small' now reads the current subject's flow-sensitivity part (r14): Nangate45 +32.1 %/-24.2 %, ASAP7 +17.6 %/-15.4 %.
2page wordingThe introductory disclosure stops implementation changes at r11, although the current subject includes r12–r14. The dated additions and detailed page history correctly disclose those later changes.fixedRULES.md's opening and the page's 'How the verdict is made' now say the design was improved in steps r2 to r14 (the page reads the revision from verdict.json).
3noneThe brief still identifies r12 as the latest revision and says only ten r12 rows were added. There are thirty added rows covering r12–r14. It also says rounds 1 and 2 confirmed r7, whereas round 1 disagreed and round 2 confirmed after corrections.fixedREVIEW.md now names r14 as the subject, the thirty added rows of r12 to r14, the rules of 06:21, 06:41 and 06:57 and the 09:19 note, and says round 2 confirmed r7 after round 1's findings were fixed.
4noneThe timing rationale supports leaving pre-register Booth recoding unapplied for the existing critical path, but does not establish that it cannot improve M1 or M2. All 20 tuned/carry-save VTA worst setup paths start after the MACs. Nevertheless, pre-register recoding and one-hot digits remain applicable, unmeasured changes; extra register bits alone do not determine net area or switching power. No missing change with a demonstrated benefit was found.kept as a limitThe page says why the move is not applied (every tuned and carry-save VTA row's worst path starts after its MACs, so it cannot shorten VTA's clock) and that it would add register bits; its net effect on VTA's area and energy is not measured.
5noneThis manifest names machines and hashes for only the 22 main-verdict rows, not the 33 open-PDK rows. The open-PDK second-machine summary is complete and scalar-identical, but does not itself name a machine for each row. Thus the requested per-row machine attribution is not established for the open PDKs by these files.kept as statedAll 33 open-PDK second-machine rows ran on the Mac (none is linked from another machine); second-machine.json lists routed-netlist hashes for the 22 main rows only.
6noneM3 reproduces as (68096×320 + 152×112×8×12)/(896×4864) = 5.375, but the metadata schedule remains a stated accounting basis because CV-GEMV RTL and testbench are private. The logs establish the read counter value, not an independently inspectable implementation of every metadata read.kept as statedM3 for CV-GEMV is the stated accounting of its private RTL; the read counts in the replay logs match it.
7noneThe dated entries state the intended ordering, but this package does not independently prove commit-before-result chronology. The supplied rules support the revision-selection logic; they are not an immutable timestamp record of preregistration.kept as statedThe order rule-before-result is recorded in the repository's history (each rule commit was pushed before its runs started; the VM ledger records the run times), not in this package.

Round 9 (2026-11-08): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/ (workloads.json, workloads/, the base rows), the comparison pages. Scope: the study of other layers and models only, not the verdicts. Conclusion: confirm. The reviewer recomputed M1 and M2 for 20 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1noneEvidence limitation: the supplied shape and fixture manifests match the specified projections and token positions, but the workload generator and its byte-for-byte base-reproduction log are absent. The package also does not independently establish preregistration chronology or execution-machine attribution.fixed in part; the rest kept as a limitFixed in part: workloads.json now holds the generator's check on the base projection (base_check: 15 files compared byte for byte, 0 different; the 14 whose hashes fixtures.json publishes are listed with those hashes, all equal), and each replay row of the eleven projections names the machine it ran on. Kept as a limit: the generator itself stays out of the package (it writes CV-GEMV's input images, which come with its RTL), and the order of the rule entries and the runs is in the repository's commit times, not in the package.
2noneEvidence limitation: every runtime-shape comparator names the expected published row, and the runner selects its routed 6_final.v. However, workload records contain row names rather than hashes of the actual netlists consumed. No substituted comparator netlist was found, but byte identity is not independently established by these records.fixedEach replay row of the eleven projections (603 rows; the 55 base rows are the base table's own) carries the SHA-256 of the routed netlist it read: on the build VM as it is there (hashed on the VM, vm/netlist_hashes.sh), on the AWS instance the file uploaded or built there. netlists_read shows, for each of the 55 published routed rows, that all its replays read one netlist, and that it is the netlist second-machine.json publishes for the 22 rows listed there.
3noneThe zero-time swap excludes a potentially real loading cost and therefore limits the gate_proj/up_proj results to the prescribed compute-only model. Both commands' cycles and reads are included correctly. Private CV-GEMV RTL, testbench and configs prevent independent inspection of the swap implementation, shape-only rebuilds and metadata-read schedule.kept as statedThe rule (08:40) fixes the zero-time swap, as storage is outside every engine for the query between tokens too; both commands' cycles and reads are counted. The page now states the swap and that both commands are counted.
4noneTPU and Gemmini use one token while other engines use two, as allowed by the rules. Their denominators are correct. The base-workload second-token sensitivity result does not establish token sensitivity for these eleven new projections; no demonstrated advantage to CV-GEMV follows from this limitation.kept as a limitAs in the base table, the TPU and Gemmini replay one token (rules); the page now says so in this section. A second-token replay of both on the eleven projections (110 long replays) is a follow-up, not done here.
5noneThe failed build is correctly classified as G3 failure, with no subject metrics for gate/up and no subject layer-12 aggregate. Its precise reported cause—one routing violation and unrouted nets—is not independently checkable because the failing route log is absent from this package.fixedevidence/compare/workloads/failed-builds/sky130hd-cv_gemv_r14c_p8_s2432x896/route-excerpt.txt: the lines of its detailed-route log that report the violations left after each iteration (6,021 down to 1) and the stop on unrouted nets; the page links it.

Round 10 (2026-11-08): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/ (workloads.json, workloads/, the base rows, review.json rounds 1 to 9), workloads.json as round 9 reviewed it, the comparison pages. Scope: the study of other layers and models only, not the verdicts. Conclusion: disagree. The reviewer checked the changes after the previous round against the files (no metric changed); findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1page wordingThe status 'fixed' overstates closure. The resolution explicitly retains the absent generator and unavailable preregistration chronology evidence. Added base-check results and machine labels address parts of the original finding, but do not resolve all of it. Label this partially addressed with remaining limits, or split its dispositions.fixedRound 9 finding 1 is now marked 'fixed in part; the rest kept as a limit', and its resolution says which part is fixed (the base check, the machines) and which is kept as a limit (the generator, the order of the runs).
2page wordingThe wording says every row carries its replay machine and netlist hash. Only the 603 non-base rows do; all 55 base rows lack these additions. Qualify this as 'every new-workload replay row'. The requested non-base coverage itself passes.fixedBoth pages and round 9's resolution now say that each replay row of the eleven projections (603) names its machine and netlist hash, and that the 55 base rows are the base table's own.

Round 11 (2026-11-08): OpenAI Codex CLI 0.166.0, model gpt-6-astra, reasoning effort low, read-only sandbox; public material only: reproduce.zip, public/evidence/compare/ (workloads.json, review.json rounds 1 to 10), workloads.json and review.json as round 10 reviewed them, the comparison pages. Scope: the study of other layers and models only, not the verdicts. Conclusion: confirm. The reviewer checked the changes after the previous round against the files (no metric changed); findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did

Round 12 (2026-11-10): Antigravity CLI 1.5.3, model Gemini 4 Argon, effort low, terminal sandbox, run in a copy of the public files (OpenAI Codex, used in rounds 4 to 11, was at its usage limit); public material only: reproduce.zip, public/evidence/compare/ (size256.json, size256/, workloads256.json, workloads256/, bandwidth-sizing.json, the base rows), the comparison pages. Scope: the 256-MAC study only, not the verdicts. Conclusion: confirm. The reviewer recomputed M1 and M2 for 36 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1nonemachine(run) in workloads_collect.py checks only whether 'aws' or 'pnr' is in the run folder name, so the 515 non-base replays that reused the 55 base netlists (in run folder ext4b-256-replay) are misclassified as 'Azure build VM', and netlist_sha() then looks in vm_netlists() (64-MAC netlists only) instead of reading netlist-sha256.txt or size256.json. As a result, workloads256.json netlists_read records sha256_by_machine={'Azure build VM': [null]}, one_netlist=false, and equals_size256_json=false for all 55 base builds (and appends null to the 5 w8a8_p32 entries), even though the actual netlist-sha256.txt files in evidence/compare/workloads256/ match size256.json.fixedworkloads_collect.py now records the AWS instances for every 256-MAC projection row (17:49, part 2: all runs on AWS), whatever the run folder's name, and hashes each replayed row's routed netlist as uploaded from the 256-MAC study's own folder. netlists_read now shows, for all 55 rows, that every replay read one netlist and that it equals the one size256.json publishes. No metric changed. The replays ran in the folders ext3wl-replay, ext3wl-replay2 and ext3wl-replay3; the folder named in the finding is not one of them.
2nonemachine(run) in size_collect.py labels any run folder without 'aws' in its name as 'Azure build VM'. Because four of the five reproduction folders (ext3rep-azure, ext3rep-azure-b, ext3rep-hold-asap7, ext3rep-hold-ng45) do not contain 'aws' in their names even though RULES.md 2026-11-10 08:55 and the HTML pages state all 55 reproduction builds ran on AWS instances, size256.json reproduction.machines lists ['AWS instance', 'Azure build VM']. In addition, only the aggregate reproduction summary in size256.json is published, not the second run's per-row raw files.fixedsize_collect.py now names the machine by folder: only the Azure build VM's first-run folder is the Azure VM; the ASAP7 fallback builds and every reproduction folder ran on AWS instances. This also corrected the first-run machine counts on both pages (AWS instance 23 rows, Azure build VM 32; they read 17 and 38 because the ASAP7 fallback folder's name has no 'aws'). size256.json's reproduction now lists, per row, the second run's folder, machine and its values of the nine compared fields, and the pages say where. No metric changed.
3page wordingRULES.md 17:49 part 2 requires the eleven 256-MAC projections to be reported as in the 08:40 entry ('Gate G1 (zero mismatches) is required on every replay; Gate G3 is checked on every new build and reported'). In workloads256.json, 14 of the 60 new shape builds missed the 8.0 ns target clock (sky130hd cv_gemv_r14c_p32_s896x896 at -0.030 ns, all 12 new gf180 builds at -0.115 to -1.086 ns, and ihp-sg13g2 w8a8_p32_s1536x12288 at -0.007 ns) and were scored at their own minimum periods, but the 'Other layers and models at 256 MACs' section on both HTML pages mentions only '605 replays, every output bit-exact' and omits the 14 Gate G3 setup misses on the 60 new builds.fixedBoth pages' section on the eleven projections at 256 MACs now lists the 14 new builds that miss the target clock, each with its setup miss, says they are scored at their own minimum period, and states route DRC 0 on every new build.
4noneBecause M2 margins are stored as (subject - best) / best (positive when CV-GEMV has higher energy per MAC and loses, negative when CV-GEMV has lower energy and wins) and smallest_margin() minimizes -kv[1] for M2, workloads256.json by_process.*.smallest.M2 selects the most positive M2 margin (CV-GEMV's worst M2 loss on Nangate45, ASAP7, SKY130HD, and GF180MCU; smallest M2 win on IHP SG13G2) rather than the cell closest to 0% in magnitude. The HTML pages state the full M2 margin ranges accurately.kept as statedBy the 08:40 entry, as at 64 MACs, the smallest margin is the cell least favourable to CV-GEMV: for M2 (lower is better) the largest (subject - best) / best. The pages now say so next to the table.

Round 13 (2026-11-10): Antigravity CLI 1.5.3, model Gemini 4 Argon, effort low, terminal sandbox, run in a copy of the public files (OpenAI Codex, used in rounds 4 to 11, was at its usage limit); public material only: reproduce.zip, public/evidence/compare/ (size256.json, size256/, workloads256.json, workloads256/, bandwidth-sizing.json, the base rows), the comparison pages. Scope: the 256-MAC study only, not the verdicts. Conclusion: confirm. The reviewer checked the changes after the previous round against the files (no metric changed); findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did

Round 14 (2026-11-10): Antigravity CLI 1.5.4, model Gemini 4 Argon, effort low, terminal sandbox, run in a copy of the public files (OpenAI Codex, used in rounds 4 to 11, was at its usage limit); public material only: reproduce.zip, public/evidence/compare/ (lanes256.json, lanes256/, size256.json, size256/, the base rows), the comparison pages. Scope: the 16 × 16 study at 256 MACs only, not the verdicts. Conclusion: confirm. The reviewer recomputed M1 and M2 for 15 rows from the raw files; findings are quoted as written.

#EffectFinding (reviewer's words)StatusWhat we did
1noneMethodological and evidence limits that could favour CV-GEMV r15 in this study: (1) the 16x16 shape and the PAIR_REG=2 half-way dot-product pipeline option were fixed after inspecting 256-MAC r14 results and synthesis areas (before any r15 place-and-route flow, replay, or power run); (2) three builds per process (PAIR_REG = 0, 2, 1) are built and one is selected by the timing-only rule while the 256-MAC comparator rows from size256.json are reused without rebuilding; and (3) CV-GEMV r15 RTL, testbench, and flow configs remain private, so M3 metadata-read accounting and identical flow settings (beyond constraint.sdc and report headers) cannot be inspected from source. All three points are explicitly disclosed in RULES.md and on both HTML pages, all 15 builds are reported with their full metrics, and the verdicts' subject remains r14.fixedRULES.md states all three points (the 11:20 entry). The pages stated the second and third (three builds with one reported by the timing rule and all fifteen shown; the comparator rows not rebuilt; r15's RTL not public) but not the first. Both pages now say in the section's first paragraph that the shape and the PAIR_REG = 2 setting were fixed after the 256-MAC results, from RTL replays and synthesis areas, before any flow of an r15 row, and that a second shape (8 rows of 32 columns) was looked at by synthesis only and is not measured. No number changed.

Review record JSON ↓

Published designs we cannot rerun (context only)

These numbers come from papers, under the authors' own conditions, and never enter the verdict. To put them next to ours we scaled them to 7 nm in two ways that disagree: the Stillmaker–Baas scaling equations, and the energy ratio our own flow measures for the same RTL and setting (CV-GEMV r7, PAIR_REG = 1) between Nangate45 and ASAP7 (5.6×). For reference, CV-GEMV r7 on ASAP7: 0.170 pJ per useful MAC and 21,849 GMAC/s per mm².

DesignNode, result typePrecisionWhat the area includesReported pJ/MACScaled to 7 nm, pJ/MACScaled to 7 nm at 1 GHz, GMAC/s per mm²
Hybrid systolic array accelerator for edge LLM inference (Chen et al., Cornell), ISLPED 202528 nm, post-layout simulationW4A8 (MXINT4 weights, INT8 activations)0.636 mm² as reported; whether SRAM is included is not stated0.8440.140 to 0.2332,520
OpenGeMM (KU Leuven MICAS), arXiv 2411.0954316 nm, synthesisINT8 x INT8cell area including a 270 KiB scratchpad (63.5 % of it)0.4270.252 to 0.1983,085
Siracusa with N-EUREKA (ETH Zurich / Univ. Bologna), IEEE JSSC 59(7), 202416 nm, measured siliconINT8 activations x 8-bit weights (bit-serial)whole 10.7 mm² cluster including MRAM, SRAM and RISC-V cores0.7460.479 to 0.347290
Precision-scalable microscaling datapath (Cuyckens et al., KU Leuven), MXINT8 mode, ASP-DAC 202622 nm, synthesisMXINT8 x MXINT80.60 mm² including scratchpad3.0440.800 to 1.052449
Precision-scalable microscaling datapath (Cuyckens et al., KU Leuven), MXFP4 mode, ASP-DAC 202622 nm, synthesisMXFP4 x MXFP4 (4-bit activations: a different problem)0.60 mm² including scratchpad0.4920.129 to 0.1703,593
  • The W4A8 decode accelerator from ISLPED 2025 scales to between 0.14 and 0.23 pJ per MAC, which brackets CV-GEMV's figure. Its number is a peak at full array use; ours counts useful work at batch 1. We cannot say which is lower without rerunning it.
  • The MXFP4 mode of the ASP-DAC 2026 datapath scales to 0.13–0.17 pJ per MAC with 4-bit activations, a different problem from W4A8.
  • Throughput per area is not comparable on equal terms: most published areas include scratchpad memory and all figures are peaks.

Sources, quoted inputs and arithmetic ↓

How the verdict is made

The pass line was written before the verdict: every metric must beat every comparator in both processes, ties within ±1% count as not better, and changes made after results are recorded as dated additions. Most of them can only favour the comparators (VTA's tuned and carry-save rows among them); three concern CV-GEMV itself and are disclosed above: its design was improved in steps r2 to r14, its one build option (PAIR_REG) was first fixed per process after the first r7 results, and on 2026-11-07 the verdict moved from r7 to the latest revision with PAIR_REG chosen by a timing rule. A script applies it to the table; a reviewer from a different model family than the author then reads the raw files and either confirms or lists disagreements. Disagreements are settled by measuring again.

Raw files

Comparison table JSON ↓ · Verdict by code JSON ↓ · Number formats JSON ↓ · Workload hashes ↓

Reproduce: the comparison scripts, flow configurations of the public engines and testbenches are in the reproduction package. The flow runs in the pinned image openroad/orfs@sha256:9aeafa602de8317ea294ec24b95755437546111a08e4e1bce452339401da14b2.