Reference mul_n
A proved reference of mul, written or adapted by the maintainers and shipped with the task: its design and its proof mul_n.lean (70 code lines). The N × N array multiplier, partial products summed by rows of full adders, proved with the sv_comb tactics. It is shown with parshown with par, never a player's entry (proved references).
Area
8 290.45µm²
8 290.4512 µm² exactly
Beats 0% · matches 0%
0 of 2 other players beaten, 0 equal.
- vs par
- −3.2% smallermul_tree_h · 8 563.21 µm²
- on this page
- 4th of 10 designs (tied with 1)
- cells
- 1 408
- flops
- 0
- repair
- 0 buffers, 0 tie cells
- GE
- 1 962.576 extra
Performance · time
10 907ps
the delay: the latest output arrival, p[30] rising
Beats 0% · matches 0%
0 of 2 other players beaten, 0 equal.
- vs par
- +82.0% slowermul_tree_h · 5 992 ps
- on this page
- 9th of 10 designs (tied with 1)
- Fmax-eq.
- 91.7 MHz derived
- critical path
- 87 cells
- unit depth
- 88 extra
Score · area × time
90 424µm²·ns
8 290.4512 µm² × 10 907 ps
Beats 0% · matches 0%
0 of 2 other players beaten, 0 equal.
- vs par
- +76.2% worsemul_tree_h · 51 311 µm²·ns
- on this page
- 9th of 10 designs (tied with 1)
- board
- a proved reference, shown with par: never ranked
- Pareto
- dominated on this page by late-carry, plus-minus-two and dadda_rc_16
On the board, of 2 other players: 0 beaten, 0 level, 0 trade off, 2 ahead.
how these numbers are measured and compared
Area: sky130 A0′, the repaired netlist. Time: NLDM, inputs driven by buf_8, 10 fF per output bit, no wires.
Area, time and score are ranked (the leaderboard orders by the score); a number tagged extra, derived or research is shown, never ranked. Fmax-equivalent = 10⁶ / time in ps, for comparison with sites that quote Fmax.
The field is the ranked records of mul's other players at this revision (2 players, 2 records), never the references, the baselines or a rejected design; each player counts once, at their best, and ties are exact at the recorded unit; advisory, recomputed at every build, never stored in a record and never used by the ranking.
On the board, another player is beaten when this design dominates every record of theirs, level when none of theirs is better and one is identical (the rest dominated), ahead when a record of theirs dominates this design, and a trade off otherwise (one of theirs better on one axis, worse on the other).
“On this page” and “Pareto” compare with the 10 designs of the area-time plot (5 references, 2 submissions and 3 baselines): not a ranking.
Area
123.930µm²
123.93000 µm² exactly
Beats 0% · matches 0%
0 of 2 other players beaten, 0 equal.
- vs par
- −3.1% smallermul_tree_h · 127.954 µm²
- on this page
- 4th of 10 designs (tied with 1)
- cells
- 1 411
- flops
- 0
- repair
- 0 buffers, 0 tie cells
- GE
- 1 962.576 extra
Performance · time
1 981ps
the delay: the latest output arrival
Beats 0% · matches 0%
0 of 2 other players beaten, 0 equal.
- vs par
- +70.8% slowermul_tree_h · 1 160 ps
- on this page
- 9th of 10 designs (tied with 1)
- Fmax-eq.
- 504.8 MHz derived
- unit depth
- 88 extra
Score · area × time
245.5µm²·ns
123.93000 µm² × 1 981 ps
Beats 0% · matches 0%
0 of 2 other players beaten, 0 equal.
- vs par
- +65.4% worsemul_tree_h · 148.4 µm²·ns
- on this page
- 9th of 10 designs (tied with 1)
- board
- a proved reference, shown with par: never ranked
- Pareto
- dominated on this page by late-carry, plus-minus-two and dadda_rc_16
On the board, of 2 other players: 0 beaten, 0 level, 0 trade off, 2 ahead.
how these numbers are measured and compared
Area: ASAP7 A0′ (asap7_a0_v1), the same scored netlist, each gate its least-area ASAP7 build, repaired by buffering. Time: NLDM, inputs driven by BUFx8, 2.5 fF per output bit, no wires; a table read below its grid is read at its floor. ASAP7: a predictive 7 nm library, never fabricated; no wires, like sky130's score (how ASAP7 is scored, and its quirks).
Area, time and score order this view's board (by the score); the records' ranked score is sky130's, the default view; a number tagged extra, derived or research is shown, never ranked. Fmax-equivalent = 10⁶ / time in ps, for comparison with sites that quote Fmax.
The field is the ranked records of mul's other players at this revision (2 players, 2 records), never the references, the baselines or a rejected design; each player counts once, at their best, and ties are exact at the recorded unit; advisory, recomputed at every build, never stored in a record and never used by the ranking.
On the board, another player is beaten when this design dominates every record of theirs, level when none of theirs is better and one is identical (the rest dominated), ahead when a record of theirs dominates this design, and a trade off otherwise (one of theirs better on one axis, worse on the other).
“On this page” and “Pareto” compare with the 10 designs of the area-time plot (5 references, 2 submissions and 3 baselines): not a ranking.
The sources
// svGolf task `mul` -- reference solution: an N x N -> 2N array multiplier.
//
// Partial products pp[i][j] = a[j] & b[i]; row 0 is pp[0] itself; row i
// (1 <= i < N) adds the upper N bits of row i-1 to pp[i] with an N-bit
// ripple-carry adder of full adders (carry-in 0). Output bit i < N is bit 0
// of row i; the top N bits are the upper N bits of row N-1.
// Bitwise operators only; genvar loops step with `++` (ls-sv's tier).
module mul_n #(parameter int N = 16) (
input logic [N-1:0] a, b,
output logic [2*N-1:0] p
);
logic [N-1:0][N-1:0] pp; // pp[i][j] = a[j] & b[i]
logic [N-1:0][N:0] s; // row sums (N+1 bits)
logic [N-1:0][N:0] c; // ripple carries
logic [N-1:0][N-1:0] t; // propagate x ^ y
genvar i, j;
generate
for (i = 0; i < N; i++) begin : g_pp
for (j = 0; j < N; j++) begin : g_pp_j
assign pp[i][j] = a[j] & b[i];
end
end
endgenerate
assign s[0] = {1'b0, pp[0]};
assign c[0] = '0;
assign t[0] = '0;
generate
for (i = 1; i < N; i++) begin : g_row
assign c[i][0] = 1'b0;
for (j = 0; j < N; j++) begin : g_bit
assign t[i][j] = s[i-1][j+1] ^ pp[i][j];
assign s[i][j] = t[i][j] ^ c[i][j];
assign c[i][j+1] = (s[i-1][j+1] & pp[i][j]) | (c[i][j] & t[i][j]);
end
assign s[i][N] = c[i][N];
end
endgenerate
generate
for (i = 0; i < N; i++) begin : g_out
assign p[i] = s[i][0];
end
endgenerate
assign p[2*N-1:N] = s[N-1][N:1];
endmodule
mul_n.lean (70 code lines)
import Submission.Design
import SvGolf.Comb
import LeanModels.Sv.CombEqTactic
import LeanModels.Sv.CombLib
/-!
# Reference solution for task `mul`, proved with the `sv_comb` tactics
This is a submission file like any player's `Solution.lean`. The checker generates the module
`Submission.Design` (`Submission.design`, `Submission.Goal`); this file proves
theorem Submission.solution : Submission.Goal
for EVERY `N ≥ 1`. The design is `reference/mul_n.sv`, an `N × N → 2N` array multiplier: 2-D
signals `pp`, `s`, `c`, `t`, nested `generate for` loops, a part-select target and a concatenation.
The same statement is proved with no tactic in `reference/mul_n_byhand.lean` (about six times as
many code lines).
## Route
1. **Structure** (`mul_struct`): `sv_structure` proves `CombDesign ∧ Acyclic` in one theorem;
the goals it leaves compare 2-D windows, which are row-major offsets `r * W + c`, so they are
closed by `intros; sv_rowmajor; omega` (`sv_rowmajor` rewrites those comparisons into
lexicographic ones with the library lemma `rmN_lt_iff`). The rank is a lexicographic key
`(row, column, phase)` of each site identity (`mulKey`). `mul_struct` needs
`maxHeartbeats 400000` (the default 200000 times out in `simp`).
2. **Ports** (`mul_interface`): the statement pins the port names, order and widths; `sv_interface`
proves them from the `CombDesign` profile (see `add_n.lean`).
3. **Equations** (in `solution`): `sv_equations` derives the eleven equations of the 2-D netlist
(`eq_pp_g_pp_j_0`, `eq_t_g_bit_0`, ..., the row stride hidden inside `rmN W i j`), the knownness
of every driven bit and the obligations. The one-dimensional and simple ones close by
`intros; omega`; the six COVERAGE goals of the nested 2-D reads (`cover_2`, `cover_4` to
`cover_8`: "the cell this assign reads is written by some assign") are closed by `sv_cover`, which
solves the writer's loop indices from the read's row and column and walks the disjunction of
writers (`CombCover.lean`).
4. **Arithmetic and bridge** (in `solution`): the equations are the library structure
`CombLib.MulNetlistView` (one field per group of assigns), over the cells `st.cell "s" W i j` of the
2-D signals. Each field is one `sv_bridge eq_x`: the printed equation has the netlist's `Int` index
forms (`rmN W (↑i + -1) (↑j + 1)`), the field has `Nat` indices (`s (i - 1) (j + 1)`), and
`sv_bridge` closes the difference by congruence and `omega`. `ideal_mul_view` (the ripple-row lemma
and the row induction) proves `p = a * b`, and the port bridge turns the Boolean bits into the
port's value.
-/
namespace Submission
open LeanModels.Sv LeanModels.Sv.CombView LeanModels.Sv.CombLib LeanModels.Sv.CombEq SvGolf
/-! ## 1. Structure: `sv_structure` -/
/-- The rank: a lexicographic key `(row, column, phase)` of each site identity. Partial products and
the zero rows come first; within a row, column by column: the propagate `t`, the carry `c`, then the
sum `s`; the row's top bit after its last column; the outputs last. -/
def mulKey (N : Nat) : SiteId → Key
| .plain 0 => (0, 0, 1) -- s[0] = {1'b0, pp[0]}
| .plain 1 => (0, 0, 0) -- c[0] = '0
| .plain 2 => (0, 0, 0) -- t[0] = '0
| .plain _ => (N, 0, 1) -- p[2*N-1:N] = s[N-1][N:1]
| .fam "g_pp_j" _ _ => (0, 0, 0) -- pp[i][j] = a[j] & b[i]
| .fam "g_row" 0 [i] => (i.toNat, 0, 0) -- c[i][0] = 1'b0
| .fam "g_row" _ [i] => (i.toNat, N, 0) -- s[i][N] = c[i][N]
| .fam "g_bit" 0 [i, j] => (i.toNat, j.toNat, 1) -- t[i][j]
| .fam "g_bit" 1 [i, j] => (i.toNat, j.toNat, 3) -- s[i][j]
| .fam "g_bit" _ [i, j] => (i.toNat, j.toNat, 2) -- c[i][j+1]
| .fam _ _ _ => (N, 0, 0) -- p[i] = s[i][0]
set_option maxHeartbeats 400000 in
/-- `CombDesign` and `Acyclic` for every `N ≥ 1`, from the lexicographic key: ONE application of the
soundness theorem and one round of obligations for both. -/
theorem mul_struct (N : Nat) (hN : 1 ≤ N) :
CombDesign (design.sem N) ∧ Acyclic (design.sem N) ∧ SharedObl design.pdesign [N] := by
sv_structure (lexRank := mulKey N)
all_goals (intros; sv_rowmajor; omega)
/-! ## 2. The ports (the task's `Interface`) -/
/-- The task's interface: exactly the ports `a`, `b` (`N` bits) and `p` (`2N` bits). -/
theorem mul_interface (N : Nat) (hN : 1 ≤ N) (hc : CombDesign (design.sem N)) :
SvGolf.Tasks.Mul.task.Interface N (design.sem N) := by
sv_interface
/-! ## 3. The statement: bridge and arithmetic; `sv_cover` closes the coverage -/
set_option maxHeartbeats 400000 in
/-- **The reference solution**: the `mul` statement, for every `N ≥ 1`. -/
theorem solution : Goal := by
intro N hN
have hN' : 1 ≤ N := hN.1
obtain ⟨hc, ha, hso⟩ := mul_struct N hN'
refine CombTask.satisfiedAt_of_comb (mul_interface N hN' hc) hc ha ?_
intro st heqs hs v hv
obtain ⟨x, y, ⟨⟩⟩ := v
simp only [SvGolf.Tasks.Mul.task, HoldAll_cons, HoldAll_nil, and_true] at hv ⊢
obtain ⟨hA, hB⟩ := hv
sv_equations
· obtain ⟨⟨vp, hvp, hvpw⟩, -⟩ := known_p_g_out_0 0 (by omega)
have ba : ∀ i, i < N → st.boolAt "a" i = x.getLsbD i := fun i hi => SvState.boolAt_ofBitVec hA hi
have bb : ∀ i, i < N → st.boolAt "b" i = y.getLsbD i := fun i hi => SvState.boolAt_ofBitVec hB hi
have hkp : ∀ k, k < 2 * N → KnownBit st "p" k := by
intro k hk
by_cases h : k < N
· exact (known_p_g_out_0 k h).2
· obtain ⟨j, rfl⟩ : ∃ j, k = N + j := ⟨k - N, by omega⟩
exact (known_p_plain_3 j (by omega)).2
rw [hvp, SvState.lookup_eq_ofBitVec_bv (W := 2 * N) hvp (by omega) hkp]
congr 2
refine ideal_mul_view hN' (pp := st.cell "pp" N) (t := st.cell "t" N)
(s := st.cell "s" ((N : Int) + 1)) (c := st.cell "c" ((N : Int) + 1))
{ pp_def := ?_, s0 := ?_, s0_top := ?_, c0 := ?_, t0 := ?_, ci0 := ?_, t_def := ?_, s_def := ?_,
c_def := ?_, s_top := ?_, p_low := ?_, p_high := ?_ }
· sv_bridge eq_pp_g_pp_j_0 with ba, bb
· sv_bridge eq_s_plain_0 with if_pos
· sv_bridge (eq_s_plain_0 N (by omega)) with if_neg
· sv_bridge eq_c_plain_1
· sv_bridge eq_t_plain_2
· sv_bridge eq_c_g_row_0
· sv_bridge eq_t_g_bit_0
· sv_bridge eq_s_g_bit_1
· sv_bridge eq_c_g_bit_2
· sv_bridge eq_s_g_row_2
· sv_bridge eq_p_g_out_0 with XF.getLsbD_bv
· sv_bridge eq_p_plain_3 with XF.getLsbD_bv
case inputsKnown_1 => exact inKnown_ofBitVec hA (by omega)
case inputsKnown_2 => exact inKnown_ofBitVec hB (by omega)
all_goals first | (intros; omega) | sv_cover
/--
info: 'Submission.solution' depends on axioms: [propext, Classical.choice, Quot.sound]
-/
#guard_msgs (whitespace := lax) in
#print axioms solution
end Submission
The netlist
The netlist card shows the sky130 weighing (its cells, its critical path): the ASAP7 view changes the overview above, not this card.
Schematic
drawn at N = 4
Drawn at N = 4, a display instance; scored at N = 16. Only this drawing and the notes under it are at the smaller size: the critical path, the cells and every other number on this page are the scored netlist's.
It is the same design through the same pinned flow at a smaller size (ppa.py --param), so that what it does can be seen: 64 cells here, 1 408 at the scoring point. The critical path at N = 4 (15 cells, ending at p[6] rising, 2 478 ps there) is in the accent colour. Drawn by netlistsvg with svGolf's sky130 skin (derived from netlistsvg's default skin, as the drawing is: MIT licence, Copyright (c) 2016 Neil Turley, the notice): one symbol per cell function, the cell above it, the instance on hover; nor2b and nand2b are drawn with the bubble on their inverted input. The cells of the path are listed under Critical path, each a link to the cell here.
The netlist at N = 4: 64 cells, 21 nand2_1, 18 and2_1, 15 xor2_1, 3 xnor2_1, 2 mux2_1, 2 or2_1, 1 inv_1, 1 nor2_1, 1 nor2b_1. There (measured, not ranked): 397.88 µm², 2 478 ps. Open the drawing on its own (SVG, 43.1 KB) to pan and zoom it with the browser's own controls.
Critical path
at N = 16 · scored
The path the ranked delay ends on, at the scoring point N = 16: 88 nets, 87 cells, to p[30] rising at 10 907 ps. Each row is a net of the repaired netlist with the arrival and the transition the STA computed there (NLDM tables, the larger transition carried; no wires). The first row is an input: its arrival is the input driver's own delay (buf_8 fed by a 50 ps ramp). From ppa.py --path (critical_path_timing); the instance names are the scored netlist's, not the schematic's (drawn at a smaller size).
In the schematic, drawn at N = 4, the critical path is 15 cells to p[6] rising (2 478 ps there); each cell is a link to it in the drawing:
b[1]_139_and2_1_145_xnor2_1_146_and2_1_152_or2_1_156_nand2_1_168_and2_1_170_mux2_1_172_xor2_1_173_nand2_1_181_and2_1_186_xor2_1_188_xor2_1_189_nand2_1_191_nand2_1_197_xor2_1p[6]
every stage (88 rows)
| # | net | edge | driven by | cell | arrival (ps) | transition (ps) | stage (ps) |
|---|---|---|---|---|---|---|---|
| 0 | b[1] | fall | input port | – | 128.7 | 34.0 | |
| 1 | _2491_ | fall | _2839_ | and2_1 | 297.9 | 57.8 | 169.2 |
| 2 | _2566_ | rise | _2846_ | xor2_1 | 501.1 | 190.5 | 203.2 |
| 3 | _2577_ | fall | _2847_ | nand2_1 | 572.9 | 45.9 | 71.8 |
| 4 | _2642_ | rise | _2853_ | nand2_1 | 660.1 | 80.1 | 87.2 |
| 5 | _2696_ | fall | _2858_ | nand2_1 | 709.6 | 45.9 | 49.5 |
| 6 | _2826_ | rise | _2870_ | nand2_1 | 796.8 | 80.1 | 87.2 |
| 7 | _1504_ | fall | _2875_ | nand2_1 | 846.4 | 45.9 | 49.6 |
| 8 | _1698_ | rise | _2893_ | nand2_1 | 933.6 | 80.1 | 87.2 |
| 9 | _1752_ | fall | _2898_ | nand2_1 | 983.2 | 45.9 | 49.6 |
| 10 | _1969_ | rise | _2922_ | nand2_1 | 1 070.4 | 80.1 | 87.2 |
| 11 | _1974_ | fall | _2927_ | nand2_1 | 1 120.0 | 45.9 | 49.6 |
| 12 | _2003_ | rise | _2957_ | nand2_1 | 1 207.2 | 80.1 | 87.2 |
| 13 | _2008_ | fall | _2962_ | nand2_1 | 1 256.8 | 45.9 | 49.6 |
| 14 | _2043_ | rise | _2998_ | nand2_1 | 1 343.9 | 80.1 | 87.1 |
| 15 | _2048_ | fall | _3003_ | nand2_1 | 1 393.5 | 45.9 | 49.6 |
| 16 | _2089_ | rise | _3045_ | nand2_1 | 1 480.7 | 80.1 | 87.2 |
| 17 | _2094_ | fall | _3050_ | nand2_1 | 1 530.3 | 45.9 | 49.6 |
| 18 | _2141_ | rise | _3098_ | nand2_1 | 1 617.5 | 80.1 | 87.2 |
| 19 | _2146_ | fall | _3103_ | nand2_1 | 1 667.1 | 45.9 | 49.6 |
| 20 | _2199_ | rise | _3157_ | nand2_1 | 1 754.3 | 80.1 | 87.2 |
| 21 | _2204_ | fall | _3162_ | nand2_1 | 1 803.9 | 45.9 | 49.6 |
| 22 | _2263_ | rise | _3222_ | nand2_1 | 1 891.1 | 80.1 | 87.2 |
| 23 | _2268_ | fall | _3227_ | nand2_1 | 1 940.6 | 45.9 | 49.5 |
| 24 | _2333_ | rise | _3293_ | nand2_1 | 2 027.8 | 80.1 | 87.2 |
| 25 | _2338_ | fall | _3298_ | nand2_1 | 2 077.4 | 45.9 | 49.6 |
| 26 | _2409_ | rise | _3370_ | nand2_1 | 2 164.6 | 80.1 | 87.2 |
| 27 | _2414_ | fall | _3375_ | nand2_1 | 2 214.2 | 47.5 | 49.6 |
| 28 | _2494_ | rise | _3453_ | nand2_1 | 2 302.1 | 80.1 | 87.9 |
| 29 | _2498_ | fall | _3457_ | nand2_1 | 2 361.1 | 56.6 | 59.0 |
| 30 | _2589_ | fall | _3541_ | and2_1 | 2 522.9 | 41.7 | 161.8 |
| 31 | _2591_ | fall | _3543_ | mux2_1 | 2 835.4 | 75.1 | 312.5 |
| 32 | _2593_ | rise | _3545_ | xor2_1 | 3 026.8 | 190.5 | 191.4 |
| 33 | _2594_ | fall | _3546_ | nand2_1 | 3 091.5 | 40.9 | 64.7 |
| 34 | _2680_ | fall | _3626_ | and2_1 | 3 253.4 | 48.1 | 161.9 |
| 35 | _2686_ | rise | _3631_ | xor2_1 | 3 452.5 | 190.5 | 199.1 |
| 36 | _2688_ | rise | _3633_ | xor2_1 | 3 669.2 | 190.5 | 216.7 |
| 37 | _2690_ | rise | _3635_ | xor2_1 | 3 886.0 | 190.5 | 216.8 |
| 38 | _2692_ | rise | _3637_ | xor2_1 | 4 102.8 | 190.5 | 216.8 |
| 39 | _2694_ | rise | _3639_ | xor2_1 | 4 319.6 | 190.5 | 216.8 |
| 40 | _2697_ | rise | _3641_ | xor2_1 | 4 536.3 | 190.5 | 216.7 |
| 41 | _2699_ | rise | _3643_ | xor2_1 | 4 753.1 | 190.5 | 216.8 |
| 42 | _2701_ | rise | _3645_ | xor2_1 | 4 969.9 | 190.5 | 216.8 |
| 43 | _2703_ | rise | _3647_ | xor2_1 | 5 186.7 | 190.5 | 216.8 |
| 44 | _2705_ | rise | _3649_ | xor2_1 | 5 403.4 | 190.5 | 216.7 |
| 45 | _2708_ | rise | _3651_ | xor2_1 | 5 620.2 | 190.5 | 216.8 |
| 46 | _2710_ | rise | _3653_ | xor2_1 | 5 837.0 | 190.5 | 216.8 |
| 47 | _2712_ | rise | _3655_ | xor2_1 | 6 053.8 | 190.5 | 216.8 |
| 48 | _2714_ | rise | _3657_ | xor2_1 | 6 270.5 | 190.5 | 216.7 |
| 49 | _2716_ | rise | _3659_ | xor2_1 | 6 487.3 | 190.5 | 216.8 |
| 50 | _2719_ | rise | _3661_ | xor2_1 | 6 704.1 | 190.5 | 216.8 |
| 51 | _2721_ | rise | _3663_ | xor2_1 | 6 920.8 | 190.5 | 216.7 |
| 52 | _2723_ | rise | _3665_ | xor2_1 | 7 137.6 | 190.5 | 216.8 |
| 53 | _2725_ | rise | _3667_ | xor2_1 | 7 354.4 | 190.5 | 216.8 |
| 54 | _2727_ | rise | _3669_ | xor2_1 | 7 571.2 | 190.5 | 216.8 |
| 55 | _2730_ | rise | _3671_ | xor2_1 | 7 787.9 | 190.5 | 216.7 |
| 56 | _2732_ | rise | _3673_ | xor2_1 | 8 004.7 | 190.5 | 216.8 |
| 57 | _2734_ | rise | _3675_ | xor2_1 | 8 221.5 | 190.5 | 216.8 |
| 58 | _2736_ | rise | _3677_ | xor2_1 | 8 438.3 | 190.5 | 216.8 |
| 59 | _2738_ | rise | _3679_ | xor2_1 | 8 655.0 | 190.5 | 216.7 |
| 60 | _2741_ | rise | _3681_ | xor2_1 | 8 871.8 | 190.5 | 216.8 |
| 61 | _2742_ | fall | _3682_ | nand2_1 | 8 943.6 | 45.9 | 71.8 |
| 62 | _2743_ | rise | _3684_ | nand2_1 | 9 030.8 | 80.1 | 87.2 |
| 63 | _2827_ | fall | _3761_ | nand2_1 | 9 080.4 | 45.9 | 49.6 |
| 64 | _2828_ | rise | _3763_ | nand2_1 | 9 167.5 | 80.1 | 87.1 |
| 65 | _1530_ | fall | _3834_ | nand2_1 | 9 217.1 | 45.9 | 49.6 |
| 66 | _1531_ | rise | _3836_ | nand2_1 | 9 304.3 | 80.1 | 87.2 |
| 67 | _1603_ | fall | _3901_ | nand2_1 | 9 353.9 | 45.9 | 49.6 |
| 68 | _1604_ | rise | _3903_ | nand2_1 | 9 441.1 | 80.1 | 87.2 |
| 69 | _1668_ | fall | _3962_ | nand2_1 | 9 490.7 | 45.9 | 49.6 |
| 70 | _1669_ | rise | _3964_ | nand2_1 | 9 577.9 | 80.1 | 87.2 |
| 71 | _1727_ | fall | _4017_ | nand2_1 | 9 627.5 | 45.9 | 49.6 |
| 72 | _1728_ | rise | _4019_ | nand2_1 | 9 714.6 | 80.1 | 87.1 |
| 73 | _1780_ | fall | _4066_ | nand2_1 | 9 764.2 | 45.9 | 49.6 |
| 74 | _1781_ | rise | _4068_ | nand2_1 | 9 851.4 | 80.1 | 87.2 |
| 75 | _1826_ | fall | _4109_ | nand2_1 | 9 901.0 | 45.9 | 49.6 |
| 76 | _1828_ | rise | _4111_ | nand2_1 | 9 988.2 | 80.1 | 87.2 |
| 77 | _1866_ | fall | _4146_ | nand2_1 | 10 037.8 | 45.9 | 49.6 |
| 78 | _1867_ | rise | _4148_ | nand2_1 | 10 125.0 | 80.1 | 87.2 |
| 79 | _1899_ | fall | _4177_ | nand2_1 | 10 174.6 | 45.9 | 49.6 |
| 80 | _1900_ | rise | _4179_ | nand2_1 | 10 261.8 | 80.1 | 87.2 |
| 81 | _1925_ | fall | _4202_ | nand2_1 | 10 311.3 | 45.9 | 49.5 |
| 82 | _1926_ | rise | _4204_ | nand2_1 | 10 398.5 | 80.1 | 87.2 |
| 83 | _1945_ | fall | _4221_ | nand2_1 | 10 448.1 | 45.9 | 49.6 |
| 84 | _1946_ | rise | _4223_ | nand2_1 | 10 535.3 | 80.1 | 87.2 |
| 85 | _1958_ | fall | _4234_ | nand2_1 | 10 584.9 | 45.9 | 49.6 |
| 86 | _1959_ | rise | _4236_ | nand2_1 | 10 672.1 | 80.1 | 87.2 |
| 87 | _1456_ | rise | _4242_ | xor2_1 | 10 907.3 | 247.2 | 235.2 |
Cells
at N = 16 · scored
| cell | count | µm² each | µm² in all | share |
|---|---|---|---|---|
xor2_1 | 459 | 8.7584 | 4020.1056 | 48.5% |
nand2_1 | 672 | 3.7536 | 2522.4192 | 30.4% |
and2_1 | 269 | 6.2560 | 1682.8640 | 20.3% |
xnor2_1 | 3 | 8.7584 | 26.2752 | 0.3% |
mux2_1 | 2 | 11.2608 | 22.5216 | 0.3% |
nor2b_1 | 1 | 6.2560 | 6.2560 | 0.1% |
or2_1 | 1 | 6.2560 | 6.2560 | 0.1% |
inv_1 | 1 | 3.7536 | 3.7536 | 0.0% |
| total | 1 408 | 8290.4512 |
Repair (buffer_trees_v1): 0 buffers on 0 nets, 0 tie cells, 1 weighing round; nothing is resized.
Legality: worst load 0.144 × max_capacitance, worst transition 0.178 × max_transition; 0 timing-table reads outside the characterized grid.
the gate mix of the extra GE column (the pinned GE table, score/ge.json)
| cell | count | GE each | GE total |
|---|---|---|---|
NAND | 672 | 1.000 | 672.000 |
XOR | 459 | 2.000 | 918.000 |
AND | 269 | 1.333 | 358.577 |
XNOR | 3 | 2.000 | 6.000 |
MUX | 2 | 2.333 | 4.666 |
ANDNOT | 1 | 1.333 | 1.333 |
NOT | 1 | 0.667 | 0.667 |
OR | 1 | 1.333 | 1.333 |
| total | 1408 | 1962.576 |
The reference
- task
mul- design
mul_n.svsha25666686a9d4c60cc9484a7fc673c5a8e2b73f30e25f9f6ddaccccbf3d51bf3bd23- proof
mul_n.lean, 70 code lines- tactics seen
omega,simp,sv_cover,sv_equations,sv_interface,sv_rowmajor,sv_structure- same design as
- –
- recorded
- no: the checker's run details (build time, axioms, the post-synthesis vectors) are kept for recorded designs only
- downloads
mul_n.svmul_n.lean
Area against time
- submission
- proved reference
- baseline (not proved)
- baseline with a banned operator
- the Pareto front of the entries
- this design
- par's score: area × time = 51 311 µm²·ns
the designs as numbers, by score
| design | kind | area (µm²) | time (ps) | score (µm²·ns) |
|---|---|---|---|---|
| late-carry | submission | 7 961.39 | 5 342 | 42 530 |
dadda_rc_16 | baseline, not proved | 8 230.39 | 5 461 | 44 946 |
dadda_ks_16 | baseline, not proved | 8 937.32 | 5 148 | 46 009 |
| plus-minus-two | submission | 7 978.90 | 6 329 | 50 498 |
mul_tree_h | proved reference · par | 8 563.21 | 5 992 | 51 311 |
mul_tree | proved reference | 8 603.25 | 6 129 | 52 729 |
mul_wallace | proved reference | 8 966.10 | 5 982 | 53 635 |
yosys_mul | baseline, not proved · banned operator | 8 825.96 | 6 261 | 55 259 |
mul_n · this design | proved reference | 8 290.45 | 10 907 | 90 424 |
mul_n_byhand | proved reference | 8 290.45 | 10 907 | 90 424 |
- submission
- proved reference
- baseline (not proved)
- baseline with a banned operator
- the Pareto front of the entries
- this design
- par's score: area × time = 148.4 µm²·ns
the designs as numbers, by score
| design | kind | area (µm²) | time (ps) | score (µm²·ns) |
|---|---|---|---|---|
dadda_ks_16 | baseline, not proved | 133.174 | 902 | 120.1 |
| late-carry | submission | 120.854 | 1 088 | 131.5 |
dadda_rc_16 | baseline, not proved | 123.391 | 1 100 | 135.7 |
mul_tree_h | proved reference · par | 127.954 | 1 160 | 148.4 |
yosys_mul | baseline, not proved · banned operator | 131.789 | 1 139 | 150.1 |
mul_tree | proved reference | 128.552 | 1 191 | 153.1 |
| plus-minus-two | submission | 119.746 | 1 307 | 156.5 |
mul_wallace | proved reference | 133.917 | 1 186 | 158.8 |
mul_n · this design | proved reference | 123.930 | 1 981 | 245.5 |
mul_n_byhand | proved reference | 123.930 | 1 981 | 245.5 |
Reproduce
From svgolf/, with the pinned tools (reproduce a score lists them):
# the ranked numbers, at the scoring point (from svgolf/, with the pinned Yosys and liberty)
python3.12 score/ppa.py tasks/mul/reference/mul_n.sv --task tasks/mul --path \
--json out.json --netlist scored.v --repaired-netlist repaired.v
Expect, in out.json:
- ppa.netlist_sha256
57ce50c4b62767ed364613bef11a6e4d8154722d0daeb6975594ece98921aadc- ppa.repair.netlist_sha256
dea76e7e7e8ea1319b86d0885ae7b02c653cec63c1b22dc42d8c7a0cb4f35eee- ppa.area_e4um2_sky130
82904512- ppa.delay_ps_sky130
10907
The schematic and the critical-path data are site/schematics/mul/66686a9d4c60cc94.json and its .svg, written by site/gen_schematics.py (the display instance is ppa.py ... --param N=4 --repaired-netlist, drawn by netlistsvg 1.0.2; repaired netlist sha256 6789c15f0758cdbd…).
From svgolf/, with the pinned tools (reproduce a score lists them):
# the ASAP7 view's numbers, at the scoring point (from svgolf/, with the pinned Yosys; once:
# python3.12 score/ppa.py --pdk asap7 --fetch-liberty, the five pinned ASAP7 files into score/lib/asap7/)
python3.12 score/ppa.py tasks/mul/reference/mul_n.sv --task tasks/mul --pdk asap7 --no-mapped \
--json out.json
Expect, in out.json:
- ppa.netlist_sha256
57ce50c4b62767ed364613bef11a6e4d8154722d0daeb6975594ece98921aadc- ppa.repair.netlist_sha256
dc39f8141d84f2ffd4fa1cc39e2c5b268fa24378c2e9cc23881d28019cffde8d- ppa.area_e5um2_asap7
12393000- ppa.delay_ps_asap7
1981
leaderboard/asap7/mul.json keeps these numbers; python3.12 leaderboard/leaderboard.py asap7 --rescore --task mul weighs every design of the task again and compares, bit for bit.