LogikBench is a large hybrid benchmark suite of human authored and AI generated Verilog RTL circuits. Use cases includes objective evaluation of EDA algorithms/tools, PDKs, architectures, model/LLMs, compute infrastructure, (and more...).
"Sunlight is said to be the best of disinfectants." --Supreme Court Justice Louis Brandeis
| Challenge | LogikBench Solution |
|---|---|
| "No Spec CPU for RTL" | 250 robust Verilog RTL benchmark circuits (>1M LOC) |
| Circuit diversity | Broad mix of circuit types, sizes, and source origins |
| Size diversity | Per-circuit parameterization across multiple scales |
| Trust | Documented source code provenance and curation criteria |
| Reproducibility | Fully automated, push-button benchmark flows |
| Portability | Technology-agnostic RTL and lambdalib-based benchmarks |
| Licensing | Clear, permissive licensing for all included sources |
| Quality | Self-checking testbenches and conservative curation |
LogikBench includes the following benchmark types:
| Benchmark type | Groups (-g) |
|---|---|
| Micro-benchmarks | basic, arithmetic, memory |
| Legacy synthetic benchmarks | epfl, isca85, isca89, koios |
| Divers catalog of real circuits | blocks |
| Very large benchmarks | large |
logikbench/
|-- logikbench/ # Python package (the installable module)
| |-- apps/lb.py # the `lb` CLI: lint | sim | syn | pnr | sta
| |-- runner.py # dispatch a benchmark to the right flow
| |-- asic.py / fpga.py # ASIC and FPGA flow drivers
| |-- common.py # shared plumbing (metrics, netlist cache)
| |-- flows/ # SiliconCompiler flow definitions (syn/sta/pnr)
| |-- tools/ # tool drivers + scripts (yosys, tardigrade)
| |-- targets/ # default.sdc + per-PDK tech knobs
| `-- benchmarks/ # the benchmark circuits, grouped by kind
| |-- basic/ memory / ... # micro-benchmarks
| |-- epfl/ iscas85/ ... # legacy synthetic suites
| |-- blocks/ # diverse catalog of real circuits
| `-- large/ # very large designs (CPU cores, accelerators)
|-- tests/ # pytest suite (test_lint, ...)
|-- examples/ # standalone usage examples
|-- docs/ dashboard/ site/ # documentation and the results dashboard
`-- results/ # published metric baselines
Every benchmark is a self-contained directory under its group:
benchmarks/<group>/<name>/
|-- <name>.py # SiliconCompiler Design object (files, params, topmodule)
|-- rtl/ # technology-agnostic Verilog
|-- testbench/ # self-checking smoke test for `lb sim` (optional)
|-- README.md # what it is, source/provenance, license
|-- LICENSE # included when the RTL is vendored
`-- ai.json # AI-provenance record (AI-generated blocks only)
LogikBench is under active development. We recommend the developer install (from source, editable) so you track the latest benchmarks and fixes and can contribute changes back. The PyPI package is fine for a quick, read-only try.
Developer install (recommended):
git clone https://github.com/zeroasiccorp/logikbench.git
cd logikbench
python3 -m venv venv && source venv/bin/activate # recommended
pip install -e '.[test]' # editable + test/dev depsPip install (from PyPI):
pip install logikbenchThe steps below are the same for either install path:
# Install the EDA tools it drives (Yosys + FPGA synthesis plugins)
sc-install -group fpga
# Synthesize your first benchmark on an FPGA target
lb syn -n mux --target virtex7
# Run a whole group; metrics go to build/results/<target>.json
lb syn -g basic --target virtex7
lb syn -g basic --target asap7 # ASIC synthesis (yosys mapper)
# Simulate the self-checking testbenches, or lint the RTL
lb sim -g basic
lb lint -g basic
# Full set of help options
lb syn -hLogikBench includes the lb command-line tool for batch processing benchmarks. It drives SiliconCompiler flows through SiliconCompiler:
each benchmark is a SiliconCompiler Design, and lb has one subcommand per task:
lb synsynthesizes the selected benchmarks for one or more--targets (an ASIC PDK stem such asfreepdk45, or an FPGA part such asvirtex7) with--tool(yosys or, for ASIC, tardigrade). It writes a per-target metrics filebuild/results/<target>.json, incrementally (read-modify-write), so running a subset updates only those benchmarks and preserves the rest.lb pnrruns place-and-route (the SC asicflow throughroute) on an ASIC--targetPDK;--from/--torestrict the flow (e.g.--to synthesis.timingfor synth-stage metrics only).lb simcompiles and runs each benchmark's self-checking testbench;lb lintstatically analyzes the RTL. Both are RTL-only (no--target).
Benchmark selection (-g/--group or -n/--name; default: all groups) and the
run controls (-j, --timeout, --resume, --keep, --publish) are common to
every command; --publish copies results into the committed ./results tree
(git clone only). Run lb <command> -h for the full option list.
lb syn is the only synthesizer. It caches its mapped netlist under
build/netlists/<token>/<name>.vg (with a .key that hashes the RTL, so an
edit invalidates it), and the back-end verbs -- pnr, sta, lec -- start
from that cached netlist instead of re-synthesizing. A cache miss (or stale
netlist) errors with a "run lb syn first" hint. sim and lint work
straight off the RTL and need no netlist.
-t/--target selects what runs and is required; pass several to sweep them in
turn. FPGA targets are named <vendor>_<partname> and map to a Yosys synth
command:
| Target | Synth command |
|---|---|
virtex7 |
synth_xilinx -family xc7 |
polarpro |
synth_quicklogic -family pp3 |
polarfire |
synth_microchip -family polarfire |
ice40 |
synth_ice40 |
ecp5 |
synth_lattice -family ecp5 |
gw5a |
synth_gowin -family gw5a |
speedster |
synth_achronix |
flex16ffc |
synth_analogdevices -tech t16ffc |
trion |
synth_efinix |
fabulous |
synth_fabulous |
cologne |
synth_gatemate |
z1015 |
synth_fpga -config <arch> (wildebeest) |
z1060 |
synth_fpga -config <arch> (wildebeest) |
The zeroasic_* targets load the Wildebeest
plugin and run synth_fpga -config <arch>, where <arch> is the per-part
architecture config vendored under logikbench/targets/zeroasic/.
ASIC runs take an ASIC PDK stem as --target. lb syn --tool yosys|tardigrade
runs the lightweight lbflow (synthesis + OpenSTA timing, no place-and-route)
used for the QoR metrics above; lb pnr runs the full SiliconCompiler asicflow
(synth -> floorplan -> place -> cts -> route), trimmed to a single library and a
single setup corner so each benchmark stays fast. lb pnr --to synthesis.timing
stops the asicflow at synthesis for synth-stage metrics only.
--target PDK |
Library |
|---|---|
freepdk45 |
FreePDK45 / Nangate45 (lambdapdk) |
asap7 |
ASAP7 7nm |
sky130 |
SkyWater 130 |
gf180 |
GlobalFoundries 180 |
ihp130 |
IHP SG13G2 130 |
So lb syn --target freepdk45 --tool tardigrade runs the tardigrade lbflow, and
lb pnr --target asap7 runs the asicflow through route on ASAP7. All of these
are lambdapdk std-cell PDKs.
Common to every command (syn, pnr, sim, lint):
| Flag | Description |
|---|---|
-g, --group |
Benchmark group(s): basic, memory, arithmetic, epfl, blocks, iscas85, iscas89 (default: all groups; mutually exclusive with -n) |
-n, --name |
Act only on benchmark(s) with these name(s), searched across all groups (names are globally unique; mutually exclusive with -g) |
-b |
Build directory root; per-benchmark work goes in <builddir>/<name> (default: build) |
-j |
Number of benchmarks to run in parallel (default: 1) |
--timeout |
Per-step wall-clock cap in seconds; a step that exceeds it is killed and marked failed (default: 3600; 0 disables) |
--resume |
Skip benchmarks whose build already completed successfully |
--keep |
Keep the full per-benchmark artifacts (default: reclaim as each finishes) |
--publish |
Copy this run's results into the committed ./results tree, merging incrementally. Requires a git clone (errors otherwise) |
-v, --verbose |
Show full SiliconCompiler tool/scheduler logs (quieted by default) |
Per-command flags:
| Command | Flags |
|---|---|
syn |
-t/--target (PDK stem or FPGA part, required), --tool {yosys,tardigrade}, --clk (ns), --options, --lintonly |
pnr |
-t/--target (ASIC PDK stem, required), --clk (ns), --options, --lintonly, --from/--to (flow step: synthesis, floorplan, place, cts, route) |
sim |
--tool {icarus,verilator} |
lint |
--tool {slang,verilator} |
Each command wipes a benchmark's build directory before running, so runs are
always fresh (no SiliconCompiler build reuse); use --resume to skip completed
benchmarks. syn/pnr write build/results/<target>.json incrementally
(read-modify-write), so a subset run updates only those benchmarks
and preserves the rest. Use --publish to promote them into the committed
./results tree (git clone only).
Every ASIC run is timing-constrained automatically. You do not need to write an
SDC per benchmark: the flow generates a small wrapper that injects --clk and
the per-PDK knobs, then sources the shared default constraints in
logikbench/targets/default.sdc. Applied to every benchmark, it:
- creates one clock per port whose name matches
*clk*/*clock*(so multi-clock designs such asethmac, withrx_clk/tx_clk, are fully constrained), all at the--clkperiod; - creates a single virtual clock for purely combinational benchmarks (no clock port), so their input-to-output paths are still timed;
- constrains all data inputs and outputs with input/output delays at 50% of the
clock period, and applies per-PDK input transition (slew), load capacitance,
and setup/hold clock uncertainty read from
logikbench/targets/<pdk>/tech.tcl.
The only number you normally set is --clk (the clock period in nanoseconds,
the same value for every PDK; it is scaled into each PDK's native time unit):
lb syn -g basic --target freepdk45 --clk 2 # constrain every basic benchmark at 2 nsCustomizing a single benchmark. When a benchmark needs constraints the
defaults cannot express (e.g. a specific clock name, a subset of ports, a false
path), ship an SDC in the block directory and register it in the benchmark's
.py. Because default.sdc guardbands its defaults, a custom SDC only sets
what it wants to override, then sources the shared file:
# logikbench/<group>/<name>/sdc/<name>.sdc
set LB_CLK [get_ports my_clock] ;# override clock detection
set LB_INPUTS [all_inputs] ;# or a hand-picked subset
set LB_OUTPUTS [all_outputs]
source $LB_DEFAULT_SDC ;# tech.tcl + generic constraintsRegister it in the benchmark class (alongside the rtl fileset):
self.add_file(f'sdc/{name}.sdc', 'sdc', dataroot=root)The wrapper then sources your SDC instead of default.sdc directly. Any of
LB_CLK, LB_INPUTS, LB_OUTPUTS you leave unset fall back to the guardbanded
defaults; LB_CLK_NS (from --clk) and LB_TECH_FILE/LB_DEFAULT_SDC (paths)
are always injected for you.
Synthesize a group on an FPGA target (metrics -> build/results/<target>.json):
lb syn -g arithmetic --target virtex7Synthesize a single benchmark for a Zero ASIC part (needs the wildebeest plugin):
lb syn -n mux --target z1015Sweep several FPGA targets at once, 8 benchmarks in parallel:
lb syn -g basic --target virtex7 ice40 gw5a -j 8Run ASIC synthesis + timing (lbflow) on freepdk45 with the tardigrade mapper:
lb syn -g basic --target freepdk45 --tool tardigradeRun the asap7 SC asicflow through full place-and-route (stop earlier with e.g.
--to synthesis.timing):
lb pnr -g basic --target asap7Simulate the self-checking testbenches, or lint the RTL:
lb sim -g basic
lb lint -g basicEach LogikBench benchmark circuit consists of:
- Tech-agnostic RTL Verilog files for broad tool compatibility
- SiliconCompiler Design object with metadata and configuration
The SiliconCompiler Design object captures benchmark data as files, parameters, topmodule name, and other settings grouped as a fileset. Every circuit in the LogikBench suite has a Python class that inherits from SiliconCompiler's Design class, as shown in this mux example:
from os.path import dirname, abspath
from siliconcompiler import Design
class Mux(Design):
def __init__(self):
name = 'mux'
fileset = 'rtl'
rootname = f'{name}_root'
super().__init__(name)
self.set_dataroot(rootname, dirname(abspath(__file__)))
self.add_file(f'rtl/{name}.v', fileset, dataroot=rootname)
self.set_topmodule(name, fileset)To use a benchmark circuit, simply instantiate its class. You then have access to all methods inherited from SiliconCompiler. The example below shows how to instantiate the Mux circuit and write out its RTL settings in a standard filelist format that can be read directly by tools like Icarus Verilog, Verilator, and slang.
import logikbench as lb
d = lb.basic.Mux()
d.write_fileset('mux.f', fileset='rtl')Some LogikBench blocks are AI-generated (RTL authored with the help of a large
language model under human direction). Any such block carries an ai.json file
in its directory (e.g. ai.json)
that records its provenance so the origin of the design is transparent and
auditable. Blocks that are hand-written or vendored/imported from an external
source do not carry an ai.json.
The file captures who authored the block, which model generated it and when, that a human reviewed it, and whether the RTL is an original implementation or derived from an external source:
{
"schema_version": "1.0",
"name": "lz77",
"spec_ref": "README.md",
"authorship": "Zero ASIC Corporation; author Andreas Olofsson",
"generated_by": {
"model": "claude-opus-4-8",
"provider": "Anthropic",
"interface": "Claude Code",
"date": "2026-06-25"
},
"human_review": {
"reviewed": true,
"reviewer": "Andreas Olofsson",
"date": "2026-06-25",
"notes": "Architecture, scope, and verification were directed and reviewed by the author."
},
"origin": {
"type": "original",
"notes": "Original implementation written for LogikBench; follows the cited algorithm/standard and hardware architectures, not copied from any specific HDL source."
}
}| Field | Meaning |
|---|---|
spec_ref |
The block's specification (its README.md) |
authorship |
The party accountable for the block |
generated_by |
The model / provider / interface and date of generation |
human_review |
Whether a human reviewed it, by whom, and their notes |
origin |
original (written for LogikBench) or a derived/vendored source |
FPGA runs report per-benchmark resource counts extracted from the Yosys synthesis run (no place-and-route) — cells (the total, defined below), LUTs, muxes, LUT RAM, DSPs, block RAMs, registers, latches, and carry cells — plus logic depth and runtime.
ASIC runs report three metrics, Cell Area, FMAX, and runtime. Cell Area comes from the Yosys synthesis run; FMAX is computed by an OpenSTA timing run on the synthesized netlist. Neither involves place-and-route.
NOTE that it is impossible to do a truly fair synthesis comparison between different FPGA architectures because it's an apples to oranges comparison. The approach below is our attempt at normalization. File an issue if you disagree with it.
Each cell type in Yosys' stat per-cell-type report (num_cells_by_type) is binned by an explicit per-target cell table (_CELLMAP in logikbench/tools/yosys/yosys.py) that lists, for each vendor, the exact cell names it emits — explicit names rather than substring heuristics. The names are ground-truthed from the Yosys techlib sources (the *_map.v / *.txt / cells_sim.v files that define what each synth_* emits); the two out-of-tree plugins (analogdevices/flex16ffc and the Zero ASIC z10xx parts) are ground-truthed from stat.json instead. A cell type not listed for its vendor is written to reports/fpga_unclassified.json instead of being silently miscounted, so classification gaps stay visible and get filled as new designs/fabrics are run. The buckets:
-
LUTs — logic lookup tables (
LUT1..LUT6,$lut,SB_LUT4,EFX_LUT4,CC_LUT*,CFG1..CFG4) plus standalone inverters (INV). A pure logic-LUT count: muxes, LUT RAM, and flip-flops are not included. -
Muxes — dedicated mux-fabric primitives, counted separately from LUTs: "combining" muxes that merge outputs of LUTs already counted (
MUXF7/MUXF8,PFUMX/L6MUX21— counting them as LUTs would double-count) and "replacing" muxes that do select logic in place of LUTs (mux4x0/mux8x0,MUX2_LUT5..8,LUTMUX7/8,CC_MX4/CC_MX8,MX4). -
LUT RAM — distributed (LUT-based) RAM primitives that live in the logic fabric rather than a hard block (
RAM64X1S/RAM32M/SRL16E/… on xilinx,TRELLIS_DPR16X4, gowinRAM16SDP*, adiRAMS64X1). Counted separately from both LUTs and block RAM (the Yosys techlibs carry no LUT-site weights to fold them into LUTs, and the count is the honest, source-grounded number). -
DSPs — hard multiplier / MAC blocks:
DSP48E1,SB_MAC16,MULT18X18D,CC_MULT,MACC_PA,RBBDSP,efpga_mult*. (efinix and gowin gw5a emit none — their multipliers stay soft logic.) -
Block RAMs — hardened memory blocks:
RAMB18E1/RAMB36E1,RAM1K20/RAM64x12,SB_RAM40_4K*/SB_SPRAM256KA,EFX_RAM_5K,CC_BRAM_20K/40K,DP16KD/PDPW16KD, gowinSP/DPB/SDPB*,sdpram/spram, and the fabulousRegFile_32x4hard RegFile BEL. -
Registers — flip-flops / sequential elements:
FDRE/FDSE/FDCE/FDPE*,SLE,EFX_FF,CC_DFF,DFF*,TRELLIS_FF,FFRE,SB_DFF*,dffe*,dffepc,LUTFF*. -
Latches — level-sensitive latch primitives (
LDCE/LDPE/LDCPE,CC_DLT). -
Carry cells — dedicated carry-chain / arithmetic cells:
CARRY4,SB_CARRY,ARI1,EFX_ADD,CC_ADDF,ALU,CCU2C,CRY4*.
I/O and clock buffers and constants count toward nothing. Breaking out muxes, LUT RAM, registers, latches, and carry as their own metrics leaves LUTs a pure logic-LUT count, so a fabric that offloads logic to muxes (QuickLogic, GateMate) or absorbs it into carry/DSP/BRAM is not confused with one that spends LUTs.
Cells is the derived total — the unweighted sum of every reported bucket above:
cells = luts + muxes + lutram + dsps + brams + registers + latches + carrycells
It excludes the I/O/clock buffers and constants (and any unclassified cells), so it is the count of fabric cells the design maps to, not Yosys' raw num_cells (which also counts pads/buffers).
Every fabric cell counts as one, regardless of its capacity: a 6-input LUT packs more logic than a 4-input LUT, and a hard mux does an 8:1 select that a LUT-only fabric would spend several LUTs on — but each is one cell. This makes each count a clean cell-utilization metric, most directly comparable within an architecture family (e.g. the Zero ASIC z10xx parts, or two synthesis options on one target). Across vendors the cells differ in size, so cross-vendor counts are informative rather than a strict apples-to-apples ranking.
Logic depth is the longest combinational path through the mapped netlist, measured by Yosys' ltp -noff (longest topological path, flip-flops excluded). It is the count of cells on that path, reported uniformly across all targets; the per-vendor ABC mapping reports are inconsistent (some flows print nothing), so ltp gives one comparable number. ltp only spans a single module, but the vendor synth_* flows flatten by default, so it covers the whole design.
Because it counts cells, the path includes carry-chain and mux cells, not just LUT levels — so depth, like LUTs, reflects each architecture's primitives.
Cell Area is the total standard-cell area of the synthesized (mapped) netlist,
read from the same Yosys stat report as the FPGA cell counts. It is the sum of
the areas of every instantiated standard cell, in the area units of the target's
liberty (um^2 for the Nangate45 library used by freepdk45). Yosys also reports
the raw cell count alongside the area.
This is a pre-layout synthesis-area figure: it reflects the logic mapped to the standard-cell library but not place-and-route effects (buffering, sizing, or filler), so it tracks logic complexity rather than final silicon area. As with the FPGA LUT count, it is most directly comparable within one PDK/library.
Memory-macro area (sky130 caveat). RAM-bearing designs map their storage to
the PDK's SRAM macros via the lambdalib la_spram/la_dpram aliases. The
synthetic-RAM PDKs (asap7, freepdk45, via fakeram) generate an exact-fit
macro, and ihp130/gf180 ship several real SRAM sizes, so their memory-group
cell area is meaningful. sky130 is the exception: lambdapdk provides a
single sky130 SRAM macro (sky130_sram_1rw1r_64x256_8), so a RAM whose shape
does not match it -- the memory group and the line-buffered
conv2d/median3x3/sobel3x3 blocks -- is built by tiling many copies plus
address/mux glue (or, under some tools, falling back to flip-flops). This
inflates the reported cell area far above the other nodes (sky130 can exceed
even 180nm gf180). sky130 memory-group cell area is therefore not
node-comparable and reflects macro-tiling overhead, not logic. This is an
upstream PDK-library limitation (one available macro), not a synthesis bug; the
other PDKs' memory results are unaffected.
FMAX is the maximum operating frequency, computed by an OpenSTA timing run on the
synthesized netlist (logikbench/tools/opensta/scripts/timing.tcl). For each
clock STA finds the minimum achievable period (find_clk_min_period), and FMAX
is 1 / min_period, reported in MHz.
The benchmarks ship no constraints, so a generic SDC (generated by
logikbench/sdc.py) attaches a clock to a port named clk when present, or a
virtual clock for purely combinational designs (so input-to-output paths are
still constrained). The period defaults to 1 ns and is set with the --clk <ns> option (on lb syn/lb pnr); it is given in nanoseconds and scaled into each PDK's SDC time
unit (create_clock -period is read in the unit OpenROAD derives from the
liberty -- 1 ns for most PDKs, 1 ps for ASAP7 -- so the same --clk is the same
real frequency on every target). For the lb syn lbflow path (yosys/tardigrade)
the period is only a starting reference (FMAX is the minimum achievable period);
for the lb pnr asicflow path it is the real optimization target that
place-and-route works to.
Interpreting FMAX (sequential vs combinational). Because the generic SDC
applies zero input/output delay, min_period is the design's critical-path
delay under the clock and FMAX is 1 / (critical path). For a design with
registers this is the register-to-register path -- a genuine maximum clock
frequency. For a purely combinational design (no registers -- e.g. the basic
gate blocks, the ISCAS85 circuits, and the combinational EPFL/arithmetic
designs) the only timed path is input-to-output, so FMAX is
1 / (combinational path delay): the rate at which the block could run if its
I/O were registered, not a realizable silicon clock frequency. Shallow
combinational blocks therefore report very high FMAX -- a one- or two-gate
design can exceed 10 GHz -- which is the correct reciprocal of a small gate
delay (dominated by logic depth), not an error. Two consequences: (1)
combinational and sequential FMAX are different quantities and should not be
pooled into a single distribution or "fastest" ranking -- filter by whether a
design has registers before aggregating across the suite; and (2) the
zero-I/O-delay assumption gives the internal logic the whole period, so
combinational FMAX reflects raw logic speed with no I/O budget.
Runtime is the wall-clock time of the synthesis step, reported to 0.01 s.
Published baselines live in results/syn/{asic,fpga}/. The lists below are the
supported (complete, trustworthy) surface; anything under Experimental is
present but not release-quality. A full audit -- coverage matrix, data-integrity
findings, and RTL/doc gaps -- is in audit.md.
Each cell is succeeded / attempted -- benchmarks with a result over
benchmarks run on that target -- and - means the group was not run there.
Per-benchmark detail is in audit.md.
yosys synthesis + OpenSTA timing (tardigrade = second mapper, comparison only).
| Target | basic | arith | memory | blocks | epfl | iscas85 | iscas89 | large | koios |
|---|---|---|---|---|---|---|---|---|---|
| yosys asap7 | 26/26 | 71/71 | 17/17 | 42/44 | 19/19 | 11/11 | 28/28 | 3/5 | - |
| yosys freepdk45 | 26/26 | 71/71 | 16/17 | 42/43 | 16/16 | 11/11 | 28/28 | - | - |
| yosys gf180 | 26/26 | 71/71 | 16/17 | 42/43 | 16/16 | 11/11 | 28/28 | - | - |
| yosys ihp130 | 26/26 | 71/71 | 16/17 | 41/43 | 16/16 | 11/11 | 28/28 | - | - |
| yosys sky130 | 26/26 | 71/71 | 16/17* | 41/43 | 16/16 | 11/11 | 28/28 | - | - |
| tardigrade asap7 | 26/26 | 71/71 | 16/17 | 41/43 | 19/19 | 11/11 | 28/28 | 7/16 | - |
| tardigrade sky130 | 26/26 | 71/71 | 16/17 | 40/43 | 19/19 | 11/11 | 24/28 | - | - |
Notes: only 16 of the 19 epfl designs are run off asap7 (the hyp/log2/
multiplier giants time out). 16/17* sky130 memory: the 16 results have
inflated, non-node-comparable area (single SRAM macro; see caveats).
memory/ramtdpdc produces no area on any PDK. koios is not run on ASIC.
yosys resource counts, no timing. z1015/z1060 also have _optdelay
(delay-recipe) variants with near-identical coverage. large/koios run on
virtex7 only.
| Target | basic | arith | memory | blocks | epfl | iscas85 | iscas89 | large | koios |
|---|---|---|---|---|---|---|---|---|---|
| cologne | 26/26 | 71/71 | 17/17 | 43/43 | 19/19 | 11/11 | 28/28 | - | - |
| ecp5 | 26/26 | 71/71 | 17/17 | 43/43 | 19/19 | 11/11 | 28/28 | - | - |
| flex16ffc | 24/26 | 71/71 | 17/17 | 43/43 | 19/19 | 11/11 | 28/28 | - | - |
| gw5a | 26/26 | 71/71 | 17/17 | 43/43 | 18/19 | 11/11 | 28/28 | - | - |
| ice40 | 26/26 | 71/71 | 16/17 | 43/43 | 19/19 | 11/11 | 28/28 | - | - |
| polarfire | 26/26 | 71/71 | 16/17 | 41/43 | 19/19 | 11/11 | 28/28 | - | - |
| polarpro | 26/26 | 71/71 | 17/17 | 43/43 | 19/19 | 11/11 | 28/28 | - | - |
| trion | 26/26 | 71/71 | 16/17 | 43/43 | 19/19 | 11/11 | 28/28 | - | - |
| virtex7 | 26/26 | 71/71 | 17/17 | 54/55 | 19/19 | 11/11 | 28/28 | 12/17 | 17/19 |
| z1015 | 24/26 | 70/71 | 17/17 | 42/43 | 19/19 | 11/11 | 28/28 | - | - |
| z1060 | 24/26 | 71/71 | 17/17 | 42/43 | 19/19 | 11/11 | 28/28 | - | - |
| fabulous | 22/26 | 64/71 | 16/17 | 24/43 | 19/19 | 11/11 | 28/28 | - | - |
| speedster | 20/26 | 64/71 | 15/17 | 21/43 | 19/19 | 11/11 | 28/28 | - | - |
fabulous/speedster map only ~half of blocks (and some basic/arithmetic)
-- treat as experimental. results/sim/sim.json is a 10-benchmark simulation
stub, not a release artifact.
- FPGA metrics are resource-only -- no FMAX (no place-and-route).
- sky130
memorycell area is inflated and not node-comparable -- lambdapdk ships a single sky130 SRAM macro, so RAM shapes are tiled with glue (see ASIC Cell Area). Other PDKs' memory results are unaffected. - FMAX for combinational designs is
1 / (combinational path delay), not a clock rate; do not pool it with sequential FMAX (see ASIC FMAX). memory/ramtdpdchas no ASIC cell area (the RAM is dropped and timing fails).
| Benchmark | Description | Source | AI |
|---|---|---|---|
| arbiter | Fixed-priority arbiter | arbiter.v | |
| band | AND reduction | band.v | |
| bin2gray | Binary to Gray code converter | bin2gray.v | |
| bin2prio | Binary to priority encoder | bin2prio.v | |
| binv | Bitwise inverter | binv.v | |
| bnand | NAND reduction | bnand.v | |
| bnor | NOR reduction | bnor.v | |
| bor | OR reduction | bor.v | |
| bxnor | XNOR reduction | bxnor.v | |
| bxor | XOR reduction (parity) | bxor.v | |
| crossbar | Crossbar switch | crossbar.v | |
| dffasync | Asynchronous reset flip-flop | dffasync.v | |
| dffsync | Synchronous reset flip-flop | dffsync.v | |
| fsm | Parametrized FSM with pseudo-random transitions | readme | Y |
| gray2bin | Gray to binary code converter | gray2bin.v | |
| icg | Gated-clock register | icg.v | |
| latch | Transparent D latch | latch.v | |
| mux | Multiplexer | mux.v | |
| muxcase | Case-based multiplexer | muxcase.v | |
| muxhot | One-hot multiplexer | readme | |
| muxpri | Priority multiplexer | muxpri.v | |
| onehot | One-hot encoder | onehot.v | |
| pipeline | Pipeline register | pipeline.v | |
| shiftreg | Shift register | shiftreg.v | |
| tff | Toggle flip-flop | tff.v | |
| tmr | Triple-modular-redundancy voter | tmr.v |
| Benchmark | Description | Source | AI |
|---|---|---|---|
| abs | Absolute value | abs.v | |
| absdiff | Absolute difference | absdiff.v | |
| absdiffs | Signed absolute difference | absdiffs.v | |
| add | Adder | readme | |
| addmod | Wide modular adder (a+b) mod m | readme | |
| addsub | Adder-subtractor | addsub.v | |
| addtree | Balanced adder-reduction tree | readme | |
| argmax | Index of max over N | argmax.v | |
| argmin | Index of min over N | argmin.v | |
| atan | Arctangent (CORDIC vectoring) | readme | Y |
| avgn | Average over N (avg pool) | avgn.v | |
| clamp | Saturate/clip to [lo,hi] | clamp.v | |
| clz | Count leading zeros | clz.v | |
| cmp | Comparator | cmp.v | |
| cos | Cosine (CORDIC rotation) | readme | Y |
| counter | Counter | counter.v | |
| csa32 | 3:2 carry-save adder | csa32.v | |
| csa42 | 4:2 carry-save adder | csa42.v | |
| ctz | Count trailing zeros | ctz.v | |
| dec | Decrementer | dec.v | |
| div | Unsigned integer divide (sequential) | readme | Y |
| divs | Signed integer divide (sequential) | readme | Y |
| dotprod | Dot product | readme | |
| exp | Exponential (range-reduce + poly) | readme | Y |
| fmadd8 | Fused multiply-add, E4M3 fp8 | readme | |
| fmadd16 | Fused multiply-add, bf16 | readme | |
| fmadd32 | Fused multiply-add, fp32 | readme | |
| gelu | GELU activation (sigmoid approx) | readme | Y |
| hswish | Hard-swish activation | readme | Y |
| inc | Incrementer | inc.v | |
| ln | Natural logarithm (normalize + poly) | readme | Y |
| log2 | Log base 2 | log2.v | |
| lrelu | Leaky ReLU activation | readme | Y |
| mac | Multiply-accumulate | mac.v | |
| macc | Complex multiply-accumulate | macc.v | |
| macs | Signed multiply-accumulate | macs.v | |
| max | Maximum | max.v | |
| maxn | Max over N (max pool) | maxn.v | |
| min | Minimum | min.v | |
| mod | Unsigned modulo (sequential) | readme | Y |
| msub | Multiply-subtract | msub.v | |
| mul | Multiplier | readme | |
| muladd | Multiply-add | readme | |
| muladdc | Complex multiply-add | muladdc.v | |
| muladds | Signed multiply-add | muladds.v | |
| mulc | Complex multiply | mulc.v | |
| mulreg | Registered multiplier | readme | |
| muls | Signed multiplier | readme | |
| mulsu | Signed x unsigned multiplier | mulsu.v | |
| multconst | Constant-coefficient multiplier | multconst.v | |
| popcount | Population count (set bits) | popcount.v | |
| premul | Pre-adder multiply (a+d)*b | premul.v | |
| recip | Fixed-point reciprocal 1/x (sequential) | readme | Y |
| relu | ReLU activation function | relu.v | |
| requant | Requantize (mul-shift-round-saturate) | readme | Y |
| rotl | Rotate left (barrel) | rotl.v | |
| rotr | Rotate right (barrel) | rotr.v | |
| round | Rounder | round.v | |
| rsqrt | Fixed-point inverse sqrt (sequential) | readme | Y |
| shiftar | Arithmetic right shift | shiftar.v | |
| shiftb | Barrel shifter | shiftb.v | |
| shiftl | Left shift | shiftl.v | |
| shiftr | Right shift | shiftr.v | |
| sigmoid | Sigmoid activation (PLAN PWL) | readme | Y |
| simdmul | Packed SIMD multiply | simdmul.v | |
| sine | Sine function | sine.v | |
| sqdiff | Squared difference | sqdiff.v | |
| sqrt | Square root | readme | Y |
| sub | Subtractor | sub.v | |
| sum | Summation tree | sum.v | |
| tanh | Tanh activation (PLAN PWL) | readme | Y |
| Benchmark | Description | Source | AI |
|---|---|---|---|
| cache | Cache memory | cache.v | |
| cam | Content-addressable memory | readme | Y |
| fifoasync | Asynchronous FIFO | fifoasync.v | |
| fifosync | Synchronous FIFO | fifosync.v | |
| ramasync | Asynchronous RAM | ramasync.v | |
| rambit | Bit-wide RAM | rambit.v | |
| rambyte | Byte-wide RAM | rambyte.v | |
| raminit | Initialized RAM | raminit.v | |
| ramtdp | True dual-port RAM (single clock) | ramtdp.v | |
| ramtdpdc | True dual-port RAM (dual clock) | ramtdpdc.v | |
| ramsdp | Simple dual-port RAM | ramsdp.v | |
| ramsp | Single-port RAM | ramsp.v | |
| ramspnc | Single-port RAM (no change) | ramspnc.v | |
| ramsprf | Single-port RAM (read-first) | ramsprf.v | |
| ramspwf | Single-port RAM (write-first) | ramspwf.v | |
| regfile | Register file | readme | |
| rom | Read-only memory | rom.v |
| Benchmark | Description | Source | AI |
|---|---|---|---|
| apbregs | APB register file | apbregs.v | |
| axiram | AXI RAM interface | readme | |
| beamformer | N-channel delay-and-sum beamformer (RAM-based delay) | readme | Y |
| conv2d | Streaming 3x3 2D convolution | readme | Y |
| crc32 | CRC-32 generator | readme | Y |
| chiplink | Chiplet die-to-die link, AIB/BoW-style (per-lane deskew) | readme | Y |
| codec8b10b | 8b/10b line encoder/decoder | readme | Y |
| colorconv | Color-space conversion (RGB<->YCbCr, BT.601) | readme | Y |
| ddc | Digital down-converter (NCO/mixer/CIC/FIR) | readme | Y |
| dds | Direct digital synthesizer / NCO (sine/cosine) | readme | Y |
| dma | AXI4 scatter-gather DMA (single channel) | readme | Y |
| ethmac | Ethernet MAC | readme | |
| fft | Fast Fourier Transform | readme | Y |
| firfix | Fixed-coefficient FIR filter | firfix.v | |
| firprog | Programmable FIR filter | firprog.v | |
| fpu64 | 64-bit floating-point unit | fpu64/ | |
| gearbox66 | 64b/66b scrambler + gearbox | readme | Y |
| hamming | Hamming ECC encoder/decoder | readme | Y |
| hft | Tick-to-trade HFT pipeline | readme | Y |
| hmac | HMAC-SHA hashing | readme | |
| huffman | Canonical Huffman encoder/decoder | readme | Y |
| i2c | I2C controller | readme | |
| ialu | Integer ALU | readme | |
| jesd204b | JESD204B full-duplex link interface | readme | Y |
| lfsr | Linear feedback shift register | readme | |
| linkmap | JESD204-style transport framer/deframer | readme | Y |
| lpddr5 | LPDDR5 memory controller (UMI + DFI, ECC) | readme | Y |
| median3x3 | Streaming 3x3 median filter | readme | Y |
| openpiton | OpenPiton manycore tile | readme | |
| picorv32 | PicoRV32 RISC-V core | readme | |
| reedsolomon | Reed-Solomon RS(544,514) codec | readme | Y |
| sad8x8 | 8x8 sum of absolute differences | readme | Y |
| serv | SERV bit-serial RISC-V core | readme | |
| sha256 | SHA-256/224 secure hash core | readme | |
| sobel3x3 | Streaming 3x3 Sobel edge detector | readme | Y |
| spi | SPI controller | readme | |
| uart | UART | readme | |
| umicross | UMI crossbar | readme | |
| umidev | UMI device endpoint | readme | |
| umiregs | UMI register file | umiregs.v | |
| viterbi | Viterbi decoder | readme | Y |
| wordalign | Comma detect + bitslip aligner | readme | Y |
| Benchmark | Description | Source | AI |
|---|---|---|---|
| aes | AES encryption core | readme | |
| axicrossbar | AXI crossbar | readme | |
| bitcoin | SHA256d proof-of-work miner (parametrized, uses sha256) | readme | Y |
| blackparrot | BlackParrot RISC-V core | readme | |
| coralnpu | CoralNPU neural accelerator | readme | |
| cva6 | CVA6 (Ariane) RISC-V core | readme | |
| lz77 | LZ77 compressor/decompressor | readme | Y |
| nvdlafull | NVDLA deep-learning accelerator (nv_full config, 2048 MACs) | readme | |
| nvdlasmall | NVDLA deep-learning accelerator (nv_small config) | readme | |
| ofdm | OFDM modem (QAM + IFFT/FFT) | readme | Y |
| qr | QR decomposition solver (CORDIC/Givens systolic) | readme | Y |
| rocket | Rocket RISC-V core | readme | |
| sonicboom | SonicBOOM (v3) out-of-order RISC-V core | readme | |
| tpu | Weight-stationary systolic matrix multiply (TPU MXU, 128x128) | readme | Y |
| vortex | Vortex GPU core | readme | |
| wally | CVW-Wally RISC-V core | readme |
| Benchmark | Description | Source |
|---|---|---|
| adder | EPFL adder benchmark | adder.v |
| arbiter | EPFL arbiter benchmark | arbiter.v |
| bar | Barrel shifter | bar.v |
| cavlc | CAVLC encoder | cavlc.v |
| dec | Decoder | dec.v |
| div | Divider | div.v |
| hyp | Hypotenuse calculator | hyp.v |
| i2c | I2C controller | i2c.v |
| int2float | Integer to float converter | int2float.v |
| log2 | Log base 2 | log2.v |
| max | Maximum | max.v |
| memctrl | Memory controller | memctrl.v |
| multiplier | Multiplier | multiplier.v |
| priority | Priority encoder | priority.v |
| router | Router | router.v |
| sin | Sine function | sin.v |
| sqrt | Square root | sqrt.v |
| square | Square function | square.v |
| voter | Voter circuit | voter.v |
Combinational gate-level circuits. See iscas85/README.md.
| Benchmark | Description | Source |
|---|---|---|
| c17 | Trivial 6-gate circuit | c17.v |
| c432 | 27-channel interrupt controller | c432.v |
| c499 | 32-bit single-error-correcting circuit | c499.v |
| c880 | 8-bit ALU | c880.v |
| c1355 | 32-bit single-error-correcting circuit | c1355.v |
| c1908 | 16-bit SEC/DED circuit | c1908.v |
| c2670 | 12-bit ALU and controller | c2670.v |
| c3540 | 8-bit ALU | c3540.v |
| c5315 | ALU with parity | c5315.v |
| c6288 | 16x16 combinational multiplier | c6288.v |
| c7552 | 32-bit adder/comparator | c7552.v |
Sequential gate-level circuits (clock port CK). See iscas89/README.md.
| Benchmark | Description | Source |
|---|---|---|
| s27 | Sequential benchmark circuit | s27.v |
| s298 | Sequential benchmark circuit | s298.v |
| s344 | Sequential benchmark circuit | s344.v |
| s349 | Sequential benchmark circuit | s349.v |
| s382 | Sequential benchmark circuit | s382.v |
| s386 | Sequential benchmark circuit | s386.v |
| s400 | Sequential benchmark circuit | s400.v |
| s420 | Sequential benchmark circuit | s420.v |
| s444 | Sequential benchmark circuit | s444.v |
| s510 | Sequential benchmark circuit | s510.v |
| s526 | Sequential benchmark circuit | s526.v |
| s641 | Sequential benchmark circuit | s641.v |
| s713 | Sequential benchmark circuit | s713.v |
| s820 | Sequential benchmark circuit | s820.v |
| s832 | Sequential benchmark circuit | s832.v |
| s838 | Sequential benchmark circuit | s838.v |
| s953 | Sequential benchmark circuit | s953.v |
| s1196 | Sequential benchmark circuit | s1196.v |
| s1238 | Sequential benchmark circuit | s1238.v |
| s1423 | Sequential benchmark circuit | s1423.v |
| s1488 | Sequential benchmark circuit | s1488.v |
| s5378 | Sequential benchmark circuit | s5378.v |
| s9234 | Sequential benchmark circuit | s9234.v |
| s13207 | Sequential benchmark circuit | s13207.v |
| s15850 | Sequential benchmark circuit | s15850.v |
| s35932 | Sequential benchmark circuit | s35932.v |
| s38417 | Sequential benchmark circuit | s38417.v |
| s38584 | Sequential benchmark circuit | s38584.v |
Deep-learning accelerator and layer designs (pure RTL, hard blocks disabled). See koios/README.md.
| Benchmark | Description | Source |
|---|---|---|
| attention_layer | Transformer self-attention layer | attention_layer.v |
| conv_layer | GEMM-based convolution layer | conv_layer.v |
| conv_layer_hls | Sliding-window convolution (HLS style) | conv_layer_hls.v |
| eltwise_layer | Matrix elementwise add / sub / mult | eltwise_layer.v |
| reduction_layer | Add / max / min reduction tree | reduction_layer.v |
| gemm_layer | 20x20 matrix-multiplication engine | gemm_layer.v |
| softmax | Softmax classification layer | softmax.v |
| spmv | Sparse matrix-vector multiplication | spmv.v |
| lstm | LSTM engine | lstm.v |
| robot_rl | Reinforcement-learning | robot_rl.v |
| dnnweaver | DNNWeaver-like accelerator | dnnweaver.v |
| tpu_like_small_os | Google-TPU-v1 (output-stationary) | tpu_like_small_os.v |
| tpu_like_small_ws | Google-TPU-v1 (weight-stationary) | tpu_like_small_ws.v |
| clstm_like_small | CLSTM-like accelerator (small) | clstm_like_small.v |
| clstm_like_medium | CLSTM-like accelerator (medium) | clstm_like_medium.v |
| dla_like_small | Intel-DLA-like accelerator (small) | dla_like_small.v |
| dla_like_medium | Intel-DLA-like accelerator (medium) | dla_like_medium.v |
| bwave_like_fixed_small | Microsoft-Brainwave-like NPU | bwave_like_fixed_small.v |
| bwave_like_float_small | Microsoft-Brainwave-like NPU | bwave_like_float_small.v |
LogikBench itself is pure Python. Because the project is under active development, the developer install (from source, editable) is recommended; the released PyPI package is available for a quick, read-only try:
# Developer install (recommended): editable, with test/dev deps
git clone https://github.com/zeroasiccorp/logikbench.git
cd logikbench
pip install -e '.[test]'
# Or install the released package from PyPI
pip install logikbenchRunning benchmarks additionally needs the EDA tools that SiliconCompiler drives.
The sc-install helper (shipped with SiliconCompiler) builds and installs them.
Install by group, or name individual tools:
sc-install -group fpga # FPGA synthesis (Yosys + vendor plugins)
sc-install -group asic # ASIC synthesis + timing (Yosys, OpenROAD, OpenSTA)Useful flags: -prefix <path> to install somewhere other than the default,
-build_dir <path> to build elsewhere, and -jobs <N> to limit parallel build
jobs on memory-constrained machines.
| Use case | Tools | Group |
|---|---|---|
| FPGA LUT / depth metrics | Yosys (+ vendor synth plugins) | fpga |
| ASIC area / FMAX metrics | Yosys, OpenROAD, OpenSTA | asic |
| RTL simulation (testbenches) | Icarus Verilog, Verilator | digital-simulation |
LogikBench runs on SiliconCompiler's tool set, but the flows are defined
locally (logikbench/flows/<task>/, one per lb command) and you can plug in
tools SC does not ship -- including proprietary/commercial EDA tools (Design
Compiler, Genus, Vivado, Innovus, PrimeTime, VCS, JasperGold, ...). That is what
logikbench/tools/ is for, and it is exactly how the built-in tardigrade
mapper is integrated.
A tool is just a SiliconCompiler Task subclass placed under
logikbench/tools/<tool>/ -- SC's Task API is subclassable, so no SC fork is
needed. The reference implementation is
tools/tardigrade/tardigrade.py: a
base task declares the executable, version switch, and log regexes; a concrete
task per role adds its parameters, required filesets, command line, and metric
scraping.
To make it selectable, add one line to the relevant flow's tool dict:
# logikbench/flows/syn/asic.py
from logikbench.tools.design_compiler.design_compiler import Synthesis as DCSynthesis
class ASICSynthesis(Flowgraph):
_SYNTH = {
"yosys": YosysSynthesis,
"tardigrade": TardigradeSynthesis,
"design_compiler": DCSynthesis, # <-- your tool, one line
}Then lb syn --tool design_compiler ... uses it. SiliconCompiler handles
executable and license detection at run time, so a tool you do not have
installed simply is not selectable -- it never breaks the other flows. The full
guide (including monolithic vendor flows that do several stages at once, and
customized variants of SC's own tools) is in
logikbench/tools/README.md.
The LogikBench project is licensed under the MIT license unless specified otherwise inside the individual benchmark folders.
This work was supported by the U.S. Department of Energy, Office of Science, Advanced Scientific Computing Research program under the project, Democratization of Co-design for Energy-Efficient Heterogeneous Computing (DeCoDe) and the Competitive Portfolio program under the project, End-to-end codesign for performance, energy-efficiency, and security in AI-enabled computational science (ENCODE) at Pacific Northwest National Laboratory (PNNL). The DeCoDe project is part of the Microelectronics Energy Efficiency Research Center for Advanced Technologies (MEERCAT), a DOE Office of Science Microelectronics Science Research Center (MSRC). PNNL is a multi-program national laboratory operated for the U.S. Department of Energy (DOE) by Battelle Memorial Institute under Contract No. DE-AC05-76RL01830.


