Golf scores on ASAP7, a predictive 7 nm library: never fabricated, and like sky130's score it counts no wires. sky130, a real 130 nm process, is the default. How ASAP7 is scored, and its quirks.

Tasks / add / record

Record d20bd7d9a6e6

on the Pareto frontieron the Pareto frontier scored at N = 16

Area

474.20µm²

474.2048 µm² exactly

vs par
+3.0% largeradd_n · 460.44 µm²
on this page
6th of 10 designs
cells
83
flops
0
repair
0 buffers, 0 tie cells
GE
114.665 extra
A1′
447.93 µm² research

Performance · time

2 479ps

the delay: the latest output arrival, s[15] rising

vs par
−5.1% fasteradd_n · 2 611 ps
on this page
4th of 10 designs
Fmax-eq.
403.4 MHz derived
critical path
30 cells
unit depth
33 extra
A1′
5 525 ps research

Score · area × time

1176µm²·ns

474.2048 µm² × 2 479 ps

vs par
−2.2% betteradd_n · 1202 µm²·ns
on this page
best of 10 designs
board
layer 1, rank 1 of 1 by score
Pareto
on the front

No other player has a ranked record on add yet: the beats and matches lines come with the first one.

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 add's other players at this revision (0 players, 0 records), never the references, the baselines or a rejected design; advisory, recomputed at every build, never stored in a record and never used by the ranking.

“On this page” and “Pareto” compare with the 10 designs of the area-time plot (5 references, 1 submission and 4 baselines): not a ranking.

Area

7.188µm²

7.18794 µm² exactly

vs par
+2.7% largeradd_n · 6.998 µm²
on this page
6th of 10 designs
cells
84
flops
0
repair
0 buffers, 0 tie cells
GE
114.665 extra

Performance · time

561ps

the delay: the latest output arrival

vs par
−0.4% fasteradd_n · 563 ps
on this page
4th of 10 designs
Fmax-eq.
1782.5 MHz derived
unit depth
33 extra

Score · area × time

4.032µm²·ns

7.18794 µm² × 561 ps

vs par
+2.3% worseadd_n · 3.94 µm²·ns
on this page
7th of 10 designs
board
layer 1, rank 1 of 1 by score
Pareto
on the front

No other player has a ranked record on add yet: the beats and matches lines come with the first one.

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 add's other players at this revision (0 players, 0 records), never the references, the baselines or a rejected design; advisory, recomputed at every build, never stored in a record and never used by the ranking.

“On this page” and “Pareto” compare with the 10 designs of the area-time plot (5 references, 1 submission and 4 baselines): not a ranking.

The sources

solution.svdownload
// svGolf task `add`: a carry-select adder with 6-bit blocks, for every N >= 1.
// Q = N / 6 carry-select blocks: block j computes its carries twice, by two ripple chains in
// row j of c0 (block carry-in 0) and c1 (block carry-in 1); row j of cs picks one by the block
// carry cb[j] (the carry into each bit of the block), and the block carries ripple through one multiplexer per block. The R = N % 6 top
// bits ripple from cb[Q] through c (c[i] is the carry INTO bit i; cout = c[N]).
module add_n #(parameter int N = 16) (
  input  logic [N-1:0] a, b,
  input  logic         cin,
  output logic [N-1:0] s,
  output logic         cout
);
  localparam integer Q = N / 6;
  localparam integer R = N % 6;
  logic [N-1:0] p, g;
  logic [Q:0][6:0] c0, c1;
  logic [Q:0][5:0] cs;
  logic [Q:0] cb;
  logic [N:0] c;
  genvar i, j, t;
  // the module-level assigns: block carry 0, the unused row Q of c0, c1, cs (every declared bit
  // is driven), the carry into the tail, the carry out
  assign cb[0] = cin;
  assign c0[Q] = 7'b0;
  assign c1[Q] = 7'b0;
  assign cs[Q] = 6'b0;
  assign c[6*Q] = cb[Q];
  assign cout = c[N];
  generate
    for (i = 0; i < N; i++) begin : g_pg
      assign p[i] = a[i] ^ b[i];
      assign g[i] = a[i] & b[i];
    end
    for (j = 0; j < Q; j++) begin : g_blk
      assign c0[j][0] = 1'b0;
      assign c1[j][0] = 1'b1;
      for (t = 0; t < 6; t++) begin : g_rip
        assign c0[j][t+1] = g[6*j+t] | (p[6*j+t] & c0[j][t]);
        assign c1[j][t+1] = g[6*j+t] | (p[6*j+t] & c1[j][t]);
        assign cs[j][t] = cb[j] ? c1[j][t] : c0[j][t];
      end
      assign cb[j+1] = cb[j] ? c1[j][6] : c0[j][6];
    end
    for (t = 0; t < R; t++) begin : g_tail
      assign c[6*Q+t+1] = g[6*Q+t] | (p[6*Q+t] & c[6*Q+t]);
    end
    for (j = 0; j < Q; j++) begin : g_sblk
      for (t = 0; t < 6; t++) begin : g_s
        assign s[6*j+t] = p[6*j+t] ^ cs[j][t];
      end
    end
    for (t = 0; t < R; t++) begin : g_stail
      assign s[6*Q+t] = p[6*Q+t] ^ c[6*Q+t];
    end
  endgenerate
endmodule
Solution.lean (332 code lines)
import Submission.Design
import SvGolf.Comb
import LeanModels.Sv.CombEqTactic
import LeanModels.Sv.CombLib

/-!
# Carry-select arithmetic, for every block size `K` and every width `N`

Plain Lean over `Nat`-indexed Boolean functions; nothing here mentions the design. A carry-select
adder with `K`-bit blocks is `Q = N / K` blocks, each with two ripple chains (`c0` from carry-in 0,
`c1` from 1, chain `j` stored at `W * j + t`, `W = K + 1`), a multiplexer row `c (K*j+t)` choosing
by the block carry `cb j`, block carries `cb (j+1)` chosen the same way, and a ripple tail of
`N % K` bits from `cb Q`. `csel_carry` says the selected carries are THE ripple carries
(`rip g p 0 ci`), so the adder is `CombLib.AddView` (`csel_view`).
-/

namespace CselMath

open LeanModels.Sv.CombLib

/-- The ripple carry into position `b + t` when the carry into position `b` is `x0`. -/
def rip (g p : Nat → Bool) (b : Nat) (x0 : Bool) : Nat → Bool
  | 0 => x0
  | t + 1 => g (b + t) || (p (b + t) && rip g p b x0 t)

/-- A chain stored at offset `o` that starts at `x0` and takes the ripple steps of positions
`b, b+1, …` is the ripple carry from `b`. -/
theorem chain_eq (g p d : Nat → Bool) (b o K : Nat) (x0 : Bool) (h0 : d o = x0)
    (hs : ∀ t < K, d (o + t + 1) = (g (b + t) || (p (b + t) && d (o + t)))) :
    ∀ t ≤ K, d (o + t) = rip g p b x0 t := by
  intro t
  induction t with
  | zero => intro _; simpa [rip] using h0
  | succ t ih =>
    intro ht
    show d (o + t + 1) = _
    rw [hs t (by omega), ih (by omega)]
    try rfl

/-- Restarting the ripple at `b` from its own carry changes nothing. -/
theorem rip_add (g p : Nat → Bool) (ci : Bool) (b : Nat) :
    ∀ t, rip g p 0 ci (b + t) = rip g p b (rip g p 0 ci b) t := by
  intro t
  induction t with
  | zero => rfl
  | succ t ih =>
    show rip g p 0 ci (b + t + 1) = _
    simp only [rip, Nat.zero_add, ih]

/-- A multiplexer between the two chains is the chain from the select value. -/
theorem mux_rip (g p : Nat → Bool) (b : Nat) (x : Bool) (t : Nat) :
    (if x = true then rip g p b true t else rip g p b false t) = rip g p b x t := by
  cases x <;> rfl

/-- **The selected carries are the ripple carries.** -/
theorem csel_carry (K W N : Nat) (hK : 0 < K) (hW : W = K + 1)
    (g p c0 c1 cb c : Nat → Bool) (ci : Bool)
    (hcb0 : cb 0 = ci)
    (h00 : ∀ j < N / K, c0 (W * j) = false)
    (h10 : ∀ j < N / K, c1 (W * j) = true)
    (h0s : ∀ j < N / K, ∀ t < K,
      c0 (W * j + t + 1) = (g (K * j + t) || (p (K * j + t) && c0 (W * j + t))))
    (h1s : ∀ j < N / K, ∀ t < K,
      c1 (W * j + t + 1) = (g (K * j + t) || (p (K * j + t) && c1 (W * j + t))))
    (hsel : ∀ j < N / K, ∀ t < K,
      c (K * j + t) = (if cb j = true then c1 (W * j + t) else c0 (W * j + t)))
    (hcbs : ∀ j < N / K,
      cb (j + 1) = (if cb j = true then c1 (W * j + K) else c0 (W * j + K)))
    (hcQ : c (K * (N / K)) = cb (N / K))
    (htail : ∀ t < N % K, c (K * (N / K) + t + 1) =
      (g (K * (N / K) + t) || (p (K * (N / K) + t) && c (K * (N / K) + t)))) :
    ∀ i ≤ N, c i = rip g p 0 ci i := by
  -- the two chains of block j
  have hc0 : ∀ j < N / K, ∀ t ≤ K, c0 (W * j + t) = rip g p (K * j) false t := fun j hj =>
    chain_eq g p c0 (K * j) (W * j) K false (h00 j hj) (h0s j hj)
  have hc1 : ∀ j < N / K, ∀ t ≤ K, c1 (W * j + t) = rip g p (K * j) true t := fun j hj =>
    chain_eq g p c1 (K * j) (W * j) K true (h10 j hj) (h1s j hj)
  -- the multiplexer between them
  have hmux : ∀ j < N / K, ∀ t ≤ K,
      (if cb j = true then c1 (W * j + t) else c0 (W * j + t)) = rip g p (K * j) (cb j) t := by
    intro j hj t ht
    rw [hc1 j hj t ht, hc0 j hj t ht, mux_rip]
  -- the block carries are the ripple carries at the block boundaries
  have hcb : ∀ j ≤ N / K, cb j = rip g p 0 ci (K * j) := by
    intro j
    induction j with
    | zero => intro _; rw [hcb0]; try rfl
    | succ j ih =>
      intro hj
      rw [hcbs j (by omega), hmux j (by omega) K (Nat.le_refl K), ih (by omega),
        ← rip_add, Nat.mul_add, Nat.mul_one]
  intro i hi
  by_cases hlo : i < K * (N / K)
  · -- inside a block
    have hj : i / K < N / K := by
      first
        | exact Nat.div_lt_of_lt_mul hlo
        | exact (Nat.div_lt_iff_lt_mul hK).2 (by rw [Nat.mul_comm]; exact hlo)
    have ht : i % K < K := Nat.mod_lt i hK
    have hi' : K * (i / K) + i % K = i := Nat.div_add_mod i K
    rw [← hi', hsel (i / K) hj (i % K) ht, hmux (i / K) hj (i % K) (by omega),
      hcb (i / K) (by omega), ← rip_add]
  · -- the tail
    have hN : K * (N / K) + N % K = N := Nat.div_add_mod N K
    obtain ⟨t, rfl⟩ : ∃ t, i = K * (N / K) + t := ⟨i - K * (N / K), by omega⟩
    have htl : t ≤ N % K := by omega
    clear hlo hi
    induction t with
    | zero => rw [Nat.add_zero, hcQ, hcb (N / K) (Nat.le_refl _)]
    | succ t ih =>
      rw [← Nat.add_assoc, htail t (by omega), ih (by omega)]
      show _ = rip g p 0 ci (K * (N / K) + t + 1)
      simp only [rip, Nat.zero_add]

/-- Bit `t` of block `j` lies below the tail. -/
theorem blk_lt {K N j t : Nat} (hj : j < N / K) (ht : t < K) : K * j + t < K * (N / K) := by
  have h1 : K * (j + 1) ≤ K * (N / K) := by
    first
      | exact Nat.mul_le_mul_left K (show j + 1 ≤ N / K by omega)
      | exact Nat.mul_le_mul (Nat.le_refl K) (show j + 1 ≤ N / K by omega)
  rw [Nat.mul_add, Nat.mul_one] at h1
  omega

/-- The carry into bit `i` of the carry-select adder: the block multiplexer row `cs` below
`K * (N / K)`, the tail carry `c` from there on. -/
def sel (K N : Nat) (cs c : Nat → Bool) (i : Nat) : Bool := if i < K * (N / K) then cs i else c i

theorem sel_lo {K N i : Nat} {cs c : Nat → Bool} (h : i < K * (N / K)) : sel K N cs c i = cs i :=
  if_pos h

theorem sel_hi {K N i : Nat} {cs c : Nat → Bool} (h : ¬ i < K * (N / K)) : sel K N cs c i = c i :=
  if_neg h

/-- **The carry-select adder is an adder**: its equations give `CombLib.AddView`, with `sel` (the
multiplexed block carries, then the tail carries) as the carry function. -/
theorem csel_view (K W N : Nat) (hK : 0 < K) (hW : W = K + 1) (x y : BitVec N) (ci : Bool)
    (g p c0 c1 cb cs c s : Nat → Bool) (cout : Bool)
    (hg : ∀ i < N, g i = (x.getLsbD i && y.getLsbD i))
    (hp : ∀ i < N, p i = (x.getLsbD i ^^ y.getLsbD i))
    (hcb0 : cb 0 = ci)
    (h00 : ∀ j < N / K, c0 (W * j) = false)
    (h10 : ∀ j < N / K, c1 (W * j) = true)
    (h0s : ∀ j < N / K, ∀ t < K,
      c0 (W * j + t + 1) = (g (K * j + t) || (p (K * j + t) && c0 (W * j + t))))
    (h1s : ∀ j < N / K, ∀ t < K,
      c1 (W * j + t + 1) = (g (K * j + t) || (p (K * j + t) && c1 (W * j + t))))
    (hsel : ∀ j < N / K, ∀ t < K,
      cs (K * j + t) = (if cb j = true then c1 (W * j + t) else c0 (W * j + t)))
    (hcbs : ∀ j < N / K,
      cb (j + 1) = (if cb j = true then c1 (W * j + K) else c0 (W * j + K)))
    (hcQ : c (K * (N / K)) = cb (N / K))
    (htail : ∀ t < N % K, c (K * (N / K) + t + 1) =
      (g (K * (N / K) + t) || (p (K * (N / K) + t) && c (K * (N / K) + t))))
    (hsb : ∀ j < N / K, ∀ t < K, s (K * j + t) = (p (K * j + t) ^^ cs (K * j + t)))
    (hst : ∀ t < N % K, s (K * (N / K) + t) = (p (K * (N / K) + t) ^^ c (K * (N / K) + t)))
    (hout : cout = c N) :
    AddView N x y ci (sel K N cs c) s cout := by
  have hN : K * (N / K) + N % K = N := Nat.div_add_mod N K
  have hlt : ∀ j < N / K, ∀ t < K, K * j + t < K * (N / K) := fun _ hj _ ht => blk_lt hj ht
  have hc := csel_carry K W N hK hW g p c0 c1 cb (sel K N cs c) ci hcb0 h00 h10 h0s h1s
    (fun j hj t ht => by rw [sel_lo (hlt j hj t ht)]; exact hsel j hj t ht)
    hcbs
    (by rw [sel_hi (Nat.lt_irrefl _)]; exact hcQ)
    (fun t ht => by
      rw [sel_hi (i := K * (N / K) + t + 1) (by omega), sel_hi (i := K * (N / K) + t) (by omega)]
      exact htail t ht)
  refine ⟨?_, fun i hi => ?_, fun i hi => ?_, ?_⟩
  · rw [hc 0 (Nat.zero_le _)]
    try rfl
  · rw [hc (i + 1) (by omega), hc i (by omega)]
    show (g (0 + i) || (p (0 + i) && rip g p 0 ci i)) = _
    rw [Nat.zero_add, hg i hi, hp i hi]
    generalize rip g p 0 ci i = r
    generalize x.getLsbD i = u
    generalize y.getLsbD i = v
    cases r <;> cases u <;> cases v <;> rfl
  · by_cases hlo : i < K * (N / K)
    · have hj : i / K < N / K := by
        first
          | exact Nat.div_lt_of_lt_mul hlo
          | exact (Nat.div_lt_iff_lt_mul hK).2 (by rw [Nat.mul_comm]; exact hlo)
      have hi' : K * (i / K) + i % K = i := Nat.div_add_mod i K
      have h := hsb (i / K) hj (i % K) (Nat.mod_lt i hK)
      rw [hi'] at h
      rw [h, hp i hi, sel_lo hlo]
    · obtain ⟨t, rfl⟩ : ∃ t, i = K * (N / K) + t := ⟨i - K * (N / K), by omega⟩
      rw [hst t (by omega), hp _ hi, sel_hi hlo]
  · rw [hout, sel_hi (i := N) (by omega)]

end CselMath

namespace Submission

open LeanModels.Sv LeanModels.Sv.CombView LeanModels.Sv.CombLib LeanModels.Sv.CombEq SvGolf

/-- The rank: each site's depth (K = 6). Plain sites: cb[0] = cin (0), the unused rows Q of c0,
c1, cs (1, 2, 3), c[6Q] = cb[Q] (4), cout (5). -/
def cselRank (N : Nat) : SiteId → Nat
  | .plain p => if p = 4 then N + 9 else if p = 5 then 3 * N + 30 else 0
  | .fam l p [i] =>
      if l = "g_pg" then 1
      else if l = "g_blk" then (if p ≤ 1 then 1 else 8 + i.toNat)
      else if l = "g_tail" then N + 10 + i.toNat
      else 3 * N + 30
  | .fam l p [j, t] => if l = "g_s" then 3 * N + 30 else if p ≤ 1 then t.toNat + 2 else 9 + j.toNat
  | .fam _ _ _ => 0

set_option maxHeartbeats 1000000 in
theorem csel_struct (N : Nat) (hN : 1 ≤ N) :
    CombDesign (design.sem N) ∧ Acyclic (design.sem N) ∧ SharedObl design.pdesign [N] := by
  sv_structure (rank := cselRank N)
  all_goals first
    | (intros; omega)
    | (intros; sv_rowmajor; omega)
    | fail "unclosed structure obligation"

theorem csel_interface (N : Nat) (hN : 1 ≤ N) (hc : CombDesign (design.sem N)) :
    SvGolf.Tasks.Add.task.Interface N (design.sem N) := by
  sv_interface

theorem bv1_eq_ofBool (v : BitVec 1) : v = BitVec.ofBool (v.getLsbD 0) := by
  apply BitVec.eq_of_getLsbD_eq
  intro i hi
  obtain rfl : i = 0 := by omega
  simp

theorem knownBit_congr {st : SvState} {n : String} {a b : Nat} (h : KnownBit st n a) (e : a = b) :
    KnownBit st n b := e ▸ h

/-- **The player's arithmetic, at the ports.** From the netlist's equations over `Bool` (in `Nat`
index form, block size `K`, chain stride `W = K + 1`) and the knownness of `s` and `cout`: the task's
outputs. -/
theorem csel_final (K W : Nat) (hK : 0 < K) (hW : W = K + 1) {N : Nat} {st : SvState}
    {x y : BitVec N} {c0 : Bool}
    (hA : SvState.lookup st "a" = some (LVec.ofBitVec x))
    (hB : SvState.lookup st "b" = some (LVec.ofBitVec y))
    (hCi : SvState.lookup st "cin" = some (LVec.ofBitVec (BitVec.ofBool c0)))
    (hg : ∀ i < N, st.boolAt "g" i = (st.boolAt "a" i && st.boolAt "b" i))
    (hp : ∀ i < N, st.boolAt "p" i = (st.boolAt "a" i ^^ st.boolAt "b" i))
    (hcb0 : st.boolAt "cb" 0 = st.boolAt "cin" 0)
    (h00 : ∀ j < N / K, st.boolAt "c0" (W * j) = false)
    (h10 : ∀ j < N / K, st.boolAt "c1" (W * j) = true)
    (h0s : ∀ j < N / K, ∀ t < K, st.boolAt "c0" (W * j + t + 1) =
      (st.boolAt "g" (K * j + t) || (st.boolAt "p" (K * j + t) && st.boolAt "c0" (W * j + t))))
    (h1s : ∀ j < N / K, ∀ t < K, st.boolAt "c1" (W * j + t + 1) =
      (st.boolAt "g" (K * j + t) || (st.boolAt "p" (K * j + t) && st.boolAt "c1" (W * j + t))))
    (hsel : ∀ j < N / K, ∀ t < K, st.boolAt "cs" (K * j + t) =
      (if st.boolAt "cb" j = true then st.boolAt "c1" (W * j + t) else st.boolAt "c0" (W * j + t)))
    (hcbs : ∀ j < N / K, st.boolAt "cb" (j + 1) =
      (if st.boolAt "cb" j = true then st.boolAt "c1" (W * j + K) else st.boolAt "c0" (W * j + K)))
    (hcQ : st.boolAt "c" (K * (N / K)) = st.boolAt "cb" (N / K))
    (htail : ∀ t < N % K, st.boolAt "c" (K * (N / K) + t + 1) =
      (st.boolAt "g" (K * (N / K) + t) ||
        (st.boolAt "p" (K * (N / K) + t) && st.boolAt "c" (K * (N / K) + t))))
    (hsb : ∀ j < N / K, ∀ t < K,
      st.boolAt "s" (K * j + t) = (st.boolAt "p" (K * j + t) ^^ st.boolAt "cs" (K * j + t)))
    (hst : ∀ t < N % K, st.boolAt "s" (K * (N / K) + t) =
      (st.boolAt "p" (K * (N / K) + t) ^^ st.boolAt "c" (K * (N / K) + t)))
    (eout : st.boolAt "cout" 0 = st.boolAt "c" N)
    {vs : LVec} (hs : SvState.lookup st "s" = some vs) (hsw : vs.width = N)
    (hks : ∀ k, k < N → KnownBit st "s" k)
    {vc : LVec} (hc : SvState.lookup st "cout" = some vc) (hcw : vc.width = 1)
    (hkc : KnownBit st "cout" 0) :
    SvState.lookup st "s" = some (LVec.ofBitVec
        (BitVec.ofNat N (x.toNat + y.toNat + c0.toNat))) ∧
    SvState.lookup st "cout" = some (LVec.ofBitVec
        (BitVec.ofNat 1 ((x.toNat + y.toNat + c0.toNat) / 2 ^ N))) := by
  have hN : K * (N / K) + N % K = N := Nat.div_add_mod N K
  have hvs := SvState.lookup_eq_ofBitVec_bv hs hsw hks
  have hvc := SvState.lookup_eq_ofBitVec_bv hc hcw (fun k hk => by
    obtain rfl : k = 0 := by omega
    exact hkc)
  rw [hvs] at hs
  rw [hvc] at hc
  have hxb : XF.bv 1 (st.boolAt "cout") = BitVec.ofBool (st.boolAt "cout" 0) := by
    apply BitVec.eq_of_getLsbD_eq
    intro i hi
    obtain rfl : i = 0 := by omega
    rw [XF.getLsbD_bv hi]; simp
  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 bci : st.boolAt "cin" 0 = c0 := by
    rw [SvState.boolAt_ofBitVec hCi (by omega)]; simp
  have hv : AddView N x y c0 (CselMath.sel K N (st.boolAt "cs") (st.boolAt "c"))
      (XF.bv N (st.boolAt "s")).getLsbD (st.boolAt "cout" 0) :=
    CselMath.csel_view K W N hK hW x y c0 (st.boolAt "g") (st.boolAt "p") (st.boolAt "c0")
      (st.boolAt "c1") (st.boolAt "cb") (st.boolAt "cs") (st.boolAt "c")
      (XF.bv N (st.boolAt "s")).getLsbD (st.boolAt "cout" 0)
      (fun i hi => by rw [hg i hi, ba i hi, bb i hi])
      (fun i hi => by rw [hp i hi, ba i hi, bb i hi])
      (by rw [hcb0, bci]) h00 h10 h0s h1s hsel hcbs hcQ htail
      (fun j hj t ht => by
        have hlt := CselMath.blk_lt hj ht
        rw [XF.getLsbD_bv (show K * j + t < N by omega), hsb j hj t ht])
      (fun t ht => by rw [XF.getLsbD_bv (show K * (N / K) + t < N by omega), hst t ht]) eout
  obtain ⟨h1, h2⟩ := add_spec hv
  rw [hs, h1, hc, hxb, h2]
  exact ⟨rfl, rfl⟩

/-- A row-major cell at non-negative coordinates is the flat index `i * W + j` (`sv_bridge … with
rmN_flat` compares a 2-D read with a `Nat`-indexed one). -/
theorem rmN_flat {W i j : Int} (hW : 0 ≤ W) (hi : 0 ≤ i) (hj : 0 ≤ j) :
    rmN W i j = (i * W + j).toNat := by
  obtain ⟨w, rfl⟩ := Int.eq_ofNat_of_zero_le hW
  obtain ⟨a, rfl⟩ := Int.eq_ofNat_of_zero_le hi
  obtain ⟨b, rfl⟩ := Int.eq_ofNat_of_zero_le hj
  unfold rmN
  first
    | rw [← Int.natCast_mul, ← Int.natCast_add, Int.toNat_natCast, Int.toNat_natCast,
        Int.toNat_natCast, Int.toNat_natCast]
    | simp only [Int.toNat_natCast, ← Int.natCast_mul, ← Int.natCast_add]

theorem toNatW : (7 : Int).toNat = 7 := rfl
theorem toNatK : (6 : Int).toNat = 6 := rfl

/-- The one-bit literals as `sv_equations` hands them over. -/
theorem lit0 : ({ bits := #[Logic.l0] } : LVec).boolAt 0 = false := by
  first | rfl | decide | simp [LVec.boolAt]
theorem lit1 : ({ bits := #[Logic.l1] } : LVec).boolAt 0 = true := by
  first | rfl | decide | simp [LVec.boolAt]

set_option maxHeartbeats 1000000 in
theorem solution : Goal := by
  intro N hN
  have hN' : 1 ≤ N := hN.1
  obtain ⟨hc, ha, hso⟩ := csel_struct N hN'
  refine CombTask.satisfiedAt_of_comb (csel_interface N hN' hc) hc ha ?_
  intro st heqs hs v hv
  obtain ⟨x, y, ci, ⟨⟩⟩ := v
  obtain ⟨c0, rfl⟩ : ∃ c0, ci = BitVec.ofBool c0 := ⟨_, bv1_eq_ofBool ci⟩
  simp only [SvGolf.Tasks.Add.task, HoldAll_cons, HoldAll_nil, and_true, BitVec.toNat_ofBool]
    at hv ⊢
  obtain ⟨hA, hB, hCi⟩ := hv
  sv_equations
  · have hknown : ∃ vs, SvState.lookup st "s" = some vs ∧ vs.width = N := by
      by_cases hQ : 6 ≤ N
      · obtain ⟨⟨vs, hvs, hvsw⟩, -⟩ := known_s_1 0 (by omega) 0 (by omega)
        exact ⟨vs, hvs, by omega⟩
      · obtain ⟨⟨vs, hvs, hvsw⟩, -⟩ := known_s_2 0 (by omega)
        exact ⟨vs, hvs, by omega⟩
    obtain ⟨vs, hvs, hvsw⟩ := hknown
    have hks : ∀ k, k < N → KnownBit st "s" k := by
      intro k hk
      by_cases hkq : k < 6 * (N / 6)
      · exact knownBit_congr (known_s_1 (k / 6) (by omega) (k % 6) (by omega)).2 (by omega)
      · exact knownBit_congr (known_s_2 (k - 6 * (N / 6)) (by omega)).2 (by omega)
    obtain ⟨⟨vc, hvc, hvcw⟩, hkc⟩ := known_cout_1
    refine csel_final 6 7 (by decide) rfl hA hB hCi ?_ ?_ ?_ ?_ ?_ ?_ ?_ ?_ ?_ ?_ ?_ ?_ ?_ ?_ hvs
      hvsw hks hvc hvcw hkc
    · sv_bridge eq_g_1
    · sv_bridge eq_p_1
    · sv_bridge eq_cb_1
    · first
        | sv_bridge eq_c0_2 with rmN, toNatW, toNatK, Int.toNat_natCast
        | sv_bridge eq_c0_2 with rmN_flat
    · first
        | sv_bridge eq_c1_2 with rmN, toNatW, toNatK, Int.toNat_natCast
        | sv_bridge eq_c1_2 with rmN_flat
    · first
        | sv_bridge eq_c0_3 with rmN, toNatW, toNatK, Int.toNat_natCast
        | sv_bridge eq_c0_3 with rmN_flat
    · first
        | sv_bridge eq_c1_3 with rmN, toNatW, toNatK, Int.toNat_natCast
        | sv_bridge eq_c1_3 with rmN_flat
    · first
        | sv_bridge eq_cs_2 with rmN, toNatW, toNatK, Int.toNat_natCast
        | sv_bridge eq_cs_2 with rmN_flat
    · first
        | sv_bridge eq_cb_2 with rmN, toNatW, toNatK, Int.toNat_natCast
        | sv_bridge eq_cb_2 with rmN_flat
    · sv_bridge eq_c_1
    · sv_bridge eq_c_2
    · first
        | sv_bridge eq_s_1 with rmN, toNatW, toNatK, Int.toNat_natCast
        | sv_bridge eq_s_1 with rmN_flat
    · sv_bridge eq_s_2
    · sv_bridge eq_cout_1
  all_goals first
    | (intros; omega)
    | rfl
    | (intros; rfl)
    | decide
    | sv_cover
    | (refine inKnown_ofBitVec hA ?_; omega)
    | (refine inKnown_ofBitVec hB ?_; omega)
    | (refine inKnown_ofBitVec hCi ?_; omega)
    | fail "unclosed obligation"

/--
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.

_42_ · sky130_fd_sc_hd__nand2_1 nand2_1 _43_ · sky130_fd_sc_hd__nand2_1 nand2_1 _44_ · sky130_fd_sc_hd__nand2_1 nand2_1 _45_ · sky130_fd_sc_hd__nand2_1 nand2_1 _46_ · sky130_fd_sc_hd__xor2_1 xor2_1 _47_ · sky130_fd_sc_hd__nand2_1 nand2_1 _48_ · sky130_fd_sc_hd__nand2_1 nand2_1 _49_ · sky130_fd_sc_hd__xor2_1 xor2_1 _50_ · sky130_fd_sc_hd__nand2_1 nand2_1 _51_ · sky130_fd_sc_hd__nand2_1 nand2_1 _52_ · sky130_fd_sc_hd__xor2_1 xor2_1 _53_ · sky130_fd_sc_hd__nand2_1 nand2_1 _54_ · sky130_fd_sc_hd__nand2_1 nand2_1 _55_ · sky130_fd_sc_hd__xor2_1 xor2_1 _56_ · sky130_fd_sc_hd__nand2_1 nand2_1 _57_ · sky130_fd_sc_hd__nand2_1 nand2_1 _58_ · sky130_fd_sc_hd__xor2_1 xor2_1 _59_ · sky130_fd_sc_hd__xor2_1 xor2_1 _60_ · sky130_fd_sc_hd__xor2_1 xor2_1 _61_ · sky130_fd_sc_hd__xor2_1 xor2_1 a b cin cout s 0 1 2 3 3 2 1 0 3 2 1 0

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: 20 cells here, 83 at the scoring point. The critical path at N = 4 (8 cells, ending at s[3] rising, 970 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: 20 cells, 12 nand2_1, 8 xor2_1. There (measured, not ranked): 115.11 µm², 970 ps. Open the drawing on its own (SVG, 15.2 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: 31 nets, 30 cells, to s[15] rising at 2 479 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 8 cells to s[3] rising (970 ps there); each cell is a link to it in the drawing:

  1. b[0]
  2. _46_ xor2_1
  3. _47_ nand2_1
  4. _48_ nand2_1
  5. _50_ nand2_1
  6. _51_ nand2_1
  7. _53_ nand2_1
  8. _54_ nand2_1
  9. _61_ xor2_1
  10. s[3]
#netedgedriven bycellarrival (ps)transition (ps)stage (ps)
0b[1]fallinput port–114.422.5
1_159_rise_208_xor2_1302.2190.2187.8
2_164_fall_213_nand2_1369.253.767.0
3_165_rise_214_nand2_1459.880.290.6
4_167_fall_216_nand2_1509.445.949.6
5_168_rise_217_nand2_1596.680.187.2
6_170_fall_219_nand2_1646.245.949.6
7_171_rise_220_nand2_1733.480.187.2
8_173_fall_222_nand2_1783.045.949.6
9_174_rise_223_nand2_1870.280.187.2
10_176_fall_225_nand2_1919.845.949.6
11_177_rise_226_nand2_11 008.181.888.3
12_178_fall_227_nand2_11 061.831.453.7
13_179_rise_228_nand2_11 142.680.380.8
14_180_fall_229_nand2_11 195.953.753.3
15_181_rise_230_nand2_11 286.680.290.7
16_183_fall_232_nand2_11 336.245.949.6
17_184_rise_233_nand2_11 423.480.187.2
18_186_fall_235_nand2_11 473.045.949.6
19_187_rise_236_nand2_11 560.280.187.2
20_189_fall_238_nand2_11 609.845.949.6
21_190_rise_239_nand2_11 696.980.187.1
22_126_fall_241_nand2_11 746.545.949.6
23_127_rise_242_nand2_11 833.780.187.2
24_129_fall_244_nand2_11 883.345.949.6
25_130_rise_245_nand2_11 970.580.187.2
26_132_fall_247_nand2_12 020.145.949.6
27_133_rise_248_nand2_12 107.380.187.2
28_135_fall_250_nand2_12 156.945.949.6
29_136_rise_251_nand2_12 244.180.187.2
30_124_rise_273_xor2_12 479.3247.2235.2

Cells

at N = 16 · scored

the cells of the repaired netlist, by area6 bars; the table beside the chart lists the same numbers.xor2_1: 245.24 µm² (µm² · 28 cells)xor2_1245.24 µm² · 28 cellsnand2_1: 183.93 µm² (µm² · 49 cells)nand2_1183.93 µm² · 49 cellsor2_1: 18.77 µm² (µm² · 3 cells)or2_118.77 µm² · 3 cellsmux2_1: 11.26 µm² (µm² · 1 cell)mux2_111.26 µm² · 1 cellxnor2_1: 8.76 µm² (µm² · 1 cell)xnor2_18.76 µm² · 1 celland2_1: 6.26 µm² (µm² · 1 cell)and2_16.26 µm² · 1 cell
The area of each cell type in the repaired A0′ netlist, at the scoring point: the count times the cell's area in the pinned liberty. Their sum is the ranked area.
cellcountµm² eachµm² in allshare
xor2_1288.7584245.235251.7%
nand2_1493.7536183.926438.8%
or2_136.256018.76804.0%
mux2_1111.260811.26082.4%
xnor2_118.75848.75841.8%
and2_116.25606.25601.3%
total83474.2048

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)
gate mix: cells of each type in the scored netlist6 bars; the table beside the chart lists the same numbers.NAND: 49 cells (49.000 GE)NAND49 49.000 GEXOR: 28 cells (56.000 GE)XOR28 56.000 GEOR: 3 cells (3.999 GE)OR3 3.999 GEAND: 1 cell (1.333 GE)AND1 1.333 GEMUX: 1 cell (2.333 GE)MUX1 2.333 GEXNOR: 1 cell (2.000 GE)XNOR1 2.000 GE
Cells by type; area is the count weighted by the pinned GE table.
cellcountGE eachGE total
NAND491.00049.000
XOR282.00056.000
OR31.3333.999
AND11.3331.333
MUX12.3332.333
XNOR12.0002.000
total83114.665

The record

task
add
player
select-six
assisted by
Claude Opus 5.5 (Anthropic)
submitted
2026-11-05
notes
Made by an AI agent (Claude Opus, Anthropic) in the maintainers' newcomer study on 2026-11-05, as a new design rather than a variation of a shipped one; the agent chose the player name. The design is a carry-select adder with 6-bit blocks, for every N >= 1: Q = N/6 blocks and an R = N%6 ripple tail, both integer localparams. Block j keeps two ripple chains in row j of the 2-D arrays c0 (block carry-in 0) and c1 (block carry-in 1); a multiplexer row cs picks the carry into each bit by the block carry cb[j], the block carries ripple through one multiplexer per block, and the sum bits are p ^ carry, written in two trailing loops. The block size and the placement of the sum assigns were chosen by sweeps scored with score/ppa.py. The proof takes the sv_structure / sv_interface / sv_equations / sv_bridge / sv_cover route with its own rank function over the site ids; its arithmetic is plain Lean, generic in the block size (a ripple carry restarted at any position, two chain lemmas and a multiplexer lemma), and shows that the selected carries are the ripple carries, so the design meets CombLib.AddView and add_spec finishes the proof. The comments in both files are the agent's. Proof ported by the maintainers for the 2026-11-06 range change; design unchanged.
scoring point
N = 16
design
solution.sv sha256 52e1d40feb1823cf5a143674deb33d6d77ea611f898ee83b81fa3725abbebee9
proof
Solution.lean sha256 ecb1b45b3b17e9fb9a86083f6bc821e6ce8cbae22ae702df25e8b6cecb78765b
canonical text
sha256 86215572ee2ce6b6f4e134debd96e9d4cd4b62cdfa579fcc96cf068ccd661c68
record hash
d20bd7d9a6e6c181bf3ce92b55d7bb610fd7bd7dada03f3bab5ca0bb000dc315
downloads
d20bd7d9a6e6.sv d20bd7d9a6e6.lean d20bd7d9a6e6.json
previous frontier
none: this is the task's first submission

The proof

code lines
332
build time
28.65 s
axioms
Classical.choice, Quot.sound, propext
tactics seen
decide, induction, omega, simp, sv_cover, sv_equations, sv_interface, sv_rowmajor, sv_structure
imports
Submission.Design, SvGolf.Comb, LeanModels.Sv.CombEqTactic, LeanModels.Sv.CombLib

Checker and flow

Checked under the pinned flow of this site's boards.

Yosys
Yosys 0.53 (git sha1 53c22ab7c0ced80861c7536c5dae682c30fb5834, clang++ 17.0.0 -fPIC -O3)
Verilator
Verilator 5.042 2025-11-02 rev UNKNOWN.REV
Lean toolchain
leanprover/lean4:v4.33.0-rc1
svGolf revision
88a13caa17ef6765f2c63bf22455ab39071df750
lean-surfaces revision
88a13caa17ef6765f2c63bf22455ab39071df750
canonicalization script
bbd11227d45dc1365f27597fd45c565fe721ba2648450588fc4fd983d00b367b
scoring script
ea58219d8ef14c3bad265218ee266ccdb709ac9d4dc5258edc34d51ee83a0445
GE table
6a29196a3f4b58241f4c9af650c9141e4632b737214d563a11ba142a725c4bea
extractor
4930696021c588c75dc890034c534c95560ad9a28a4955b87d1f8d68b5edbc0c
canonical RTLIL
8c7d4b7ea7ac23b7d36520b2c742dcd08655d29414d5fdd7440df5b095ab8180
the checker's files (sha256)
filesha256
check.pye708084f72f955b0ae1aaabe469dba3eacc5a91484a1ed81bcc073b60f3c0b6d
check/Comparator.lean3145eb578ca71e452eff05a398e8ad04673e6c72ca5343b234cb22e2cefe65a6
check/SvEval.leanfb51d72510b515460866c2798aad3c6f55295536e627b92854c3580af215bb91
check/clocked_rules.py73856a45905724544247ad29042bdc2f1778271ec07b15cdb3a5f214685165c1
check/envelope.py076db01a9791bcc25ee84e9b0033604a4b675f00b212eab0c864078e6a4748b7
check/postsynth.py4e1ee2110c63f24e033dd689c929ea686ddf10f4db23b9057c6fb711394c7558
lakefile.tomlf35a88404367d22906effc14d644aac9a9cad47dfd3b704ea8fec88acfaf9c4d
lean-toolchain62c2d9c0fc1ec4c67e151c11eff41ca004ef38e179cf9476c230406e6defedef
score/banlist.pyf18c14c23a14d55db63e202f42cc424dc84c1dd1c337f132ad60859dc9d5d33a
score/canon.ysbbd11227d45dc1365f27597fd45c565fe721ba2648450588fc4fd983d00b367b
score/fourstate.py95332451ae3754226fb87b46027385b46a91121e7eb9ae25b302bce756d90475
score/ge.json6a29196a3f4b58241f4c9af650c9141e4632b737214d563a11ba142a725c4bea
score/ge_seq.json54b93ca63888009d0671c8978e8ab7bf4fb8ce303bc78d3b4e1f83d946cc3201
score/ppa.py912031912c3e3f6790725161753e95415df34846bd8c27dde3eb707747ddbcbe
score/ppa_mapped.ys93547b343dbac135737e98516b1004a780e1cf2f579e1bd7fed82c908c6d4125
score/ppa_mapped_pins.json4b8688ba3f4d67681658e5944afe878592adf588cd416a8b47597ebe06deb045
score/ppa_pins.jsond66a6086a37a97f5985266057051979fb6a8a3c557d3ef9c42acc1b5e41502d8
score/score.py71d2e3b82f8813ec64a58f0a46909ca23dfab377db44eda6f294b713f45ae781
score/srcgate.py11952f61058051c9e8de91a801b672d07e66a29308e978156c04ffd9f0dbef45
score/svgolf.ysea58219d8ef14c3bad265218ee266ccdb709ac9d4dc5258edc34d51ee83a0445
score/svgolf_seq.ysc3874dbfc85921a87df6eacdfc6b2c9a0e2b34edd5738951e0d8bdb51f4558b2

Post-synthesis check

ls-sv's reading of the design and the scored netlist, simulated on the same vectors, agreed on every one. The vectors are a sample of the inputs: a guard against the two tools disagreeing, not a proof.

mode
full
vectors
4132
full set
4132
mismatches
0
point
N=16
seed
4348e13c54f2015c5f7ef8bd27a4f22ed7e1bcd4e984869b354d99d2b45f12e7
salted
no

Area against time

µm² × ps · lower left is better · ASAP7
add: this design's sky130 area against time, among the task's designs10 designs by sky130 area (µm²) (x) and time (ps) (y), this one ringed; lower left is better; 3 beyond the view, counted at its edges. The table under the chart lists the same numbers.2200240026002800450500550600sky130 area (µm²)time (ps) · lower is betterpar's score: area × time = 1202 µm²·nsthe Pareto front of the entriesadd_n_sklansky · baseline, not proved · Score: 1328 µm²·ns · Area: 541.8 µm² · Delay: 2451 ps5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_mthis design · select-six · submission · 2026-11-05 · Score: 1176 µm²·ns · Area: 474.2 µm² · Delay: 2479 psparthis design1 design beyond the view (right)1 ▸1 design beyond the view (above)▴ 12 designs beyond the view (below)▾ 2
add: this design's sky130 area against time, among the task's designs10 designs by sky130 area (µm²) (x) and time (ps) (y), this one ringed; lower left is better; 3 beyond the view, counted at its edges. The table under the chart lists the same numbers.2200240026002800500600sky130 area (µm²)time (ps) · lower is betterpar's score: area × time = 1202 µm²·nsthe Pareto front of the entriesadd_n_sklansky · baseline, not proved · Score: 1328 µm²·ns · Area: 541.8 µm² · Delay: 2451 ps5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_mthis design · select-six · submission · 2026-11-05 · Score: 1176 µm²·ns · Area: 474.2 µm² · Delay: 2479 psparthis design1 design beyond the view (right)1 ▸1 design beyond the view (above)▴ 12 designs beyond the view (below)▾ 2
  • submission
  • proved reference
  • baseline (not proved)
  • baseline with a banned operator
  • the Pareto front of the entries
  • this design
  • par's score: area × time = 1202 µm²·ns
sky130 area (x) against the ranked time (y); lower left is better on both. The step line is the Pareto front of the entries (the proved references and the players' ranked records); a design under par's score curve has a better score than par. Baselines are drawn for scale: scored, never proved. Fitted to the cluster: 3 designs beyond the view, counted at its edge (◂ ▸ ▴ ▾); “All designs” shows them.
the designs as numbers, by score
designkindarea (µm²)time (ps)score (µm²·ns)
select-six · this designsubmission474.202 4791176
add_n proved reference · par460.442 6111202
add_n_byhand proved reference460.442 6111202
add_proc proved reference460.442 6111202
add_mux proved reference460.442 6111202
add_proc_m proved reference460.442 6111202
add_n_kogge_stone baseline, not proved641.872 0641325
add_n_sklansky baseline, not proved541.772 4511328
plus baseline, not proved · banned operator497.983 1431565
cmp_carry baseline, not proved · banned operator857.071 9651684
add: this design's ASAP7 area against time, among the task's designs10 designs by ASAP7 area (µm²) (x) and time (ps) (y), this one ringed; lower left is better; 2 beyond the view, counted at its edges. The table under the chart lists the same numbers.45050055077.588.59ASAP7 area (µm²)time (ps) · lower is betterpar's score: area × time = 3.94 µm²·nsthe Pareto front of the entriesadd_n_sklansky · baseline, not proved · Score: 3.919 µm²·ns · Area: 8.048 µm² · Delay: 487 psplus · baseline, not proved · banned operator · Score: 4.224 µm²·ns · Area: 7.436 µm² · Delay: 568 ps5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_mthis design · select-six · submission · 2026-11-05 · Score: 4.032 µm²·ns · Area: 7.188 µm² · Delay: 561 psparthis design2 designs beyond the view (right)2 ▸1 design beyond the view (below)▾ 1
add: this design's ASAP7 area against time, among the task's designs10 designs by ASAP7 area (µm²) (x) and time (ps) (y), this one ringed; lower left is better; 2 beyond the view, counted at its edges. The table under the chart lists the same numbers.450500550789ASAP7 area (µm²)time (ps) · lower is betterpar's score: area × time = 3.94 µm²·nsthe Pareto front of the entriesadd_n_sklansky · baseline, not proved · Score: 3.919 µm²·ns · Area: 8.048 µm² · Delay: 487 psplus · baseline, not proved · banned operator · Score: 4.224 µm²·ns · Area: 7.436 µm² · Delay: 568 ps5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_m5 designs at this point · add_mux · add_n · add_n_byhand · add_proc · add_proc_mthis design · select-six · submission · 2026-11-05 · Score: 4.032 µm²·ns · Area: 7.188 µm² · Delay: 561 psparthis design2 designs beyond the view (right)2 ▸1 design beyond the view (below)▾ 1
  • submission
  • proved reference
  • baseline (not proved)
  • baseline with a banned operator
  • the Pareto front of the entries
  • this design
  • par's score: area × time = 3.94 µm²·ns
ASAP7 area (x) against the ASAP7 time (y); lower left is better on both. The step line is the Pareto front of the entries (the proved references and the players' ranked records); a design under par's score curve has a better score than par. Baselines are drawn for scale: scored, never proved. Fitted to the cluster: 2 designs beyond the view, counted at its edge (◂ ▸ ▴ ▾); “All designs” shows them.
the designs as numbers, by score
designkindarea (µm²)time (ps)score (µm²·ns)
add_n_sklansky baseline, not proved8.0484873.919
add_n proved reference · par6.9985633.94
add_n_byhand proved reference6.9985633.94
add_proc proved reference6.9985633.94
add_mux proved reference6.9985633.94
add_proc_m proved reference6.9985633.94
select-six · this designsubmission7.1885614.032
add_n_kogge_stone baseline, not proved9.4774324.094
cmp_carry baseline, not proved · banned operator12.5533364.218
plus baseline, not proved · banned operator7.4365684.224

Reproduce and verify

From svgolf/, with the pinned tools (reproduce a score lists them):

shell
# the ranked numbers, at the scoring point (from svgolf/, with the pinned Yosys and liberty)
python3.12 score/ppa.py d20bd7d9a6e6c181bf3ce92b55d7bb610fd7bd7dada03f3bab5ca0bb000dc315.sv --task tasks/add --path \
    --json out.json --netlist scored.v --repaired-netlist repaired.v

Expect, in out.json:

score.rtlil_sha256
8c7d4b7ea7ac23b7d36520b2c742dcd08655d29414d5fdd7440df5b095ab8180
ppa.netlist_sha256
8336e9565c6f0afb8d7124305394f022f1878b9b9c33f5fee277995dda94041c
ppa.repair.netlist_sha256
202476f3c9450be314ecab23dfe870ff3ad300ea4671a0e0647e20981380f779
ppa.area_e4um2_sky130
4742048
ppa.delay_ps_sky130
2479

The schematic and the critical-path data are site/schematics/add/52e1d40feb1823cf.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 f9c03540b33661ba…).

From svgolf/, with the pinned tools (reproduce a score lists them):

shell
# 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 d20bd7d9a6e6c181bf3ce92b55d7bb610fd7bd7dada03f3bab5ca0bb000dc315.sv --task tasks/add --pdk asap7 --no-mapped \
    --json out.json

Expect, in out.json:

ppa.netlist_sha256
8336e9565c6f0afb8d7124305394f022f1878b9b9c33f5fee277995dda94041c
ppa.repair.netlist_sha256
28254366c960942c7454283d58f262a05a2339152c15aab707fbf403b8981ba0
ppa.area_e5um2_asap7
718794
ppa.delay_ps_asap7
561

leaderboard/asap7/add.json keeps these numbers; python3.12 leaderboard/leaderboard.py asap7 --rescore --task add weighs every design of the task again and compares, bit for bit.

Verify the record

Download the three files, then from svgolf/:

shell
# re-run the whole check on this record's files (the cost of the original check)
H=d20bd7d9a6e6c181bf3ce92b55d7bb610fd7bd7dada03f3bab5ca0bb000dc315
mkdir -p rec/add && cp "$H.json" "$H.sv" "$H.lean" rec/add/
python3.12 leaderboard/leaderboard.py verify --data-dir rec --task add --full

verify --offline checks only the hashes and the arithmetic; plain verify also rescores the design (no Lean; seconds for most designs, a minute or more for the largest), on sky130 and on ASAP7.