LogikBench is a high quality curated open source RTL benchmark suite that enables reproducible evaluation of EDA tools, process technologies, architectures, and LLMs.
"Sunlight is said to be the best of disinfectants." --Supreme Court Justice Louis Brandeis
| Problem Addressed | LogikBench Solution |
|---|---|
| No "Spec CPU for RTL" | 220 standardized benchmark circuits |
| Lack of diversity | Broad range of circuits and code origins |
| Hard coded values | Extensive per circuit parametrization |
| Lack of trust | Documented source code provenance |
| Reproducibility | 100% push button automation |
| Lack of portability | Tech agnostic RTL+lambdalib benchmarks |
| License uncertainty | 100% clear permissive license |
| Lack of quality | Testbenches and conservative curation |
LogikBench includes the following benchmark types:
| Benchmark type | Groups (-g) |
|---|---|
| Micro-benchmarks | basic, arithmetic |
| Legacy synthetic benchmarks | epfl, isca85, isca89 |
| Very large and real circuits | blocks |
# 1. Install LogikBench (pure Python, from PyPI)
pip install logikbench
# 2. Install the EDA tools it drives (Yosys + FPGA synthesis plugins)
sc-install -group fpga
# 3. Synthesize your first benchmark on an FPGA target
lb run -n mux -t xilinx_virtex7
# 4. Run a whole group; metrics go to build/results/<target>.json
lb run -g basic -t xilinx_virtex7
lb run -g basic -t lattice_ice40
# 5. Compare a metric across the two runs (writes a CSV)
lb compare -m luts build/results/xilinx_virtex7.json build/results/lattice_ice40.jsonlb -h, lb run -h, and lb compare -h list every option. Picking a
benchmark is optional: with neither -g nor -n, lb run sweeps all groups.
For ASIC area/FMAX metrics, install sc-install -group asic and use an ASIC
target such as yosys_freepdk45. See Tool Installation
for the full tool prerequisites.
Each 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 three metrics, all extracted from the Yosys synthesis run (no place-and-route): LUTs, 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.
The LUT count is the synthesized logic-fabric usage, read from Yosys' stat per-cell-type report (num_cells_by_type). Note that ideally, each target should have a custom post processing function blessed by the vendor to fairly extract their metrics. LUTs include three kinds of cell:
-
Lookup tables — the basic LUT primitives, whose names vary by vendor:
LUT1..LUT6,$lut,SB_LUT4(ice40),EFX_LUT4(efinix),CC_LUT*(gatemate),LUTFF(fabulous), andCFG1..CFG4(microchip PolarFire). -
Dedicated mux-fabric cells — the hardwired wide multiplexers that live in the same logic block as the LUTs and implement muxing a LUT-only fabric would otherwise spend LUTs on:
MUXF7/MUXF8(xilinx),mux4x0/mux8x0(quicklogic),MUX2_LUT5..8(gowin),LUTMUX7/8(adi),L6MUX21/PFUMX(lattice ECP5),CC_MX4/CC_MX8(gatemate),MX4(microchip). -
Hard DSP / multiply / MAC blocks — dedicated multiplier and multiply-accumulate cells:
DSP48E1(xilinx),MULT18X18D(lattice ECP5),CC_MULT(gatemate),MACC_PA(microchip),RBBDSP(adi),efpga_mult*(Zero ASIC). A fabric without them builds multipliers out of LUTs, so a target that uses a hard block would otherwise read as artificially LUT-light. (Carry/ALU cells such asCARRY4,ALU,CCU2C,ARI1are not DSPs and are not counted.)
Including mux cells keeps the comparison fair: ice40 has no dedicated mux, so its read/select logic is built entirely from LUTs and is fully counted; fabrics like QuickLogic or GateMate offload that same logic to mux cells, which would otherwise make their LUT count read artificially low (e.g. regfile on QuickLogic is mostly mux8x0 cells, not LUTs).
Every fabric cell counts as one, regardless of its capacity: a 6-input LUT (Xilinx, ADI) packs more logic than a 4-input LUT, and a hard mux (e.g. QuickLogic mux8x0) does an 8:1 select that a LUT-only fabric would spend several LUTs on — but each is one cell. This makes the metric a clean logic-cell utilization count, 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 LUT counts are informative rather than a strict apples-to-apples ranking — each architecture wins where its cell type fits the design (mux fabrics on mux/select/decode logic, LUT/carry fabrics on arithmetic).
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.
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 lb run --clk <ns>; 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 yosys_<pdk>/tardigrade_<pdk> lbflow path
the period is only a starting reference (FMAX is the minimum achievable period);
for the sc_<pdk> asicflow path it is the real optimization target that
place-and-route works to.
Runtime is the wall-clock time of the synthesis step, reported to 0.01 s.
LogikBench includes the lb command-line tool for batch processing benchmarks. It drives synthesis through SiliconCompiler:
each benchmark is a SiliconCompiler Design, and lb has two subcommands:
lb runsynthesizes the selected benchmarks for one or more targets and writes a per-target metrics file<-o>/<target>.json(default-o:build/results; printing its path). The write is incremental (read-modify-write), so running a subset updates only those benchmarks and preserves the rest. To publish into the committed results tree, run with-o results.lb runtakes the required-t/--targetplus an optional benchmark selector (-g/--groupor-n/--name; default: all groups).lb compare -m METRIC FILE...tabulates one metric across two or more metrics files and writes a CSV: rows are benchmarks, one column per file (labeled by its target), values are that metric (no deltas). The files are the<target>.jsonwritten byrun, so you can tabulate any set: several build results, several published results, or build vs results.
Run lb run -h or lb compare -h for the full option list.
-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 |
|---|---|
xilinx_virtex7 |
synth_xilinx -family xc7 |
quicklogic_polarpro |
synth_quicklogic -family pp3 |
microchip_polarfire |
synth_microchip -family polarfire |
lattice_ice40 |
synth_ice40 |
lattice_ecp5 |
synth_lattice -family ecp5 |
gowin_gw5a |
synth_gowin -family gw5a |
achronix_speedster |
synth_achronix |
adi_flex16ffc |
synth_analogdevices -tech t16ffc |
efinix_trion |
synth_efinix |
fabulous_generic |
synth_fabulous |
gatemate_cologne |
synth_gatemate |
zeroasic_z1015 |
synth_fpga -config <arch> (wildebeest) |
zeroasic_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 targets follow the same <tool>_<part> scheme as FPGA targets
(<vendor>_<partname>): the tool comes first, the PDK second. Three flavors --
yosys_<pdk> and tardigrade_<pdk> run the lightweight lbflow path (synthesis
- OpenSTA timing, no place-and-route), and
sc_<pdk>runs the full SiliconCompilerasicflow:
| Target | PDK / library | Flow |
|---|---|---|
yosys_freepdk45 |
FreePDK45 / Nangate45 (lambdapdk) | lbflow: Yosys synthesis + OpenSTA timing (no place-and-route) |
tardigrade_freepdk45 |
FreePDK45 | lbflow with tardigrade as the synthesis mapper |
sc_freepdk45 |
FreePDK45 | SiliconCompiler asicflow (synth -> floorplan -> place -> cts -> route) |
sc_asap7 |
ASAP7 7nm | SiliconCompiler asicflow |
sc_skywater130 |
SkyWater 130 | SiliconCompiler asicflow |
sc_gf180 |
GlobalFoundries 180 | SiliconCompiler asicflow |
sc_ihp130 |
IHP SG13G2 130 | SiliconCompiler asicflow |
The yosys_<pdk> / tardigrade_<pdk> targets run the lightweight lbflow path
used for the QoR metrics above: the mapper maps to the standard-cell library and
OpenSTA reports FMAX, with no place-and-route. The sc_<pdk> targets run the
full official SiliconCompiler asicflow (through routing) and are trimmed to a
single library and a single setup corner so each benchmark stays fast; use
--to synthesis to stop after synthesis. (yosys_<pdk>/tardigrade_<pdk>
cover the lambdapdk std-cell PDKs; sc_<pdk> additionally offers sc_interposer.)
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 run -g basic -t yosys_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.
lb run:
| Flag | Description |
|---|---|
-t, --target |
Synthesis target(s) to sweep (required); see the Targets table above |
-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>/<target>/<name> (default: build) |
-o, --output |
Directory for the per-target metrics file <DIR>/<target>.json (default: build/results; use -o results to publish into the committed results tree) |
-j |
Number of benchmarks to synthesize in parallel across the target x benchmark matrix (default: 1) |
--options |
Extra args passed verbatim to the FPGA synth command. Use the = form so leading dashes are not parsed as flags: --options=-abc9 (quote multiple: --options='-abc9 -nocarry') |
--clk |
ASIC clock period in nanoseconds for the generic SDC, scaled into each PDK's time unit; ignored for FPGA targets (default: 1.0) |
--from |
First flow step to run: synthesis, floorplan, place, cts, route (default: from the start) |
--to |
Last flow step to run (same choices; default: to the end) |
--resume |
Skip benchmarks whose build already completed successfully; only synthesize the rest |
--timeout |
Per-step wall-clock cap in seconds; a step that exceeds it is killed and marked failed (default: 3600; 0 disables) |
-v, --verbose |
Show full SiliconCompiler tool/scheduler logs (quieted by default) |
lb compare -m METRIC FILE...:
| Flag | Description |
|---|---|
FILE... |
two or more <target>.json metrics files to tabulate (as written by lb run, e.g. from build/results/ or results/) |
-m, --metric |
metric to tabulate, one column per file (e.g. luts, logicdepth, cellarea, fmax, cells, tasktime) |
-o, --output |
Output file; format chosen by extension (.json -> JSON {metric, targets, data}, else CSV). Default ./compare_<metric>.csv |
lb run wipes each benchmark's build directory before synthesizing, so runs are
always fresh (no SiliconCompiler build reuse); use --resume to skip completed
benchmarks. After building, lb run writes <-o>/<target>.json (default
build/results/<target>.json) incrementally (read-modify-write), so a subset
run updates only those benchmarks and preserves the rest.
Synthesize a group (metrics -> build/results/<target>.json):
lb run -g arithmetic -t xilinx_virtex7Synthesize a single benchmark for a Zero ASIC part (needs the wildebeest plugin):
lb run -n mux -t zeroasic_z1015Sweep several FPGA targets at once, 8 benchmarks in parallel:
lb run -g basic -t xilinx_virtex7 lattice_ice40 gowin_gw5a -j 8Tabulate a metric across the published results (no build needed):
lb compare -m cellarea results/yosys_asap7.json \
results/yosys_skywater130.json \
results/yosys_freepdk45.jsonBuild two FPGA targets, then compare their LUT counts:
lb run -g arithmetic -t xilinx_virtex7 lattice_ice40 -j 8
lb compare -m luts build/results/xilinx_virtex7.json \
build/results/lattice_ice40.jsonRun ASIC synthesis + timing (lbflow) on the freepdk45 PDK:
lb run -g basic -t yosys_freepdk45Run the asap7 SC asicflow target, synthesis only:
lb run -g basic -t sc_asap7 --to synthesis| Benchmark | Description | Verilog |
|---|---|---|
| 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 | fsm.v |
| 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 | muxhot.v |
| 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 | Verilog |
|---|---|---|
| abs | Absolute value | abs.v |
| absdiff | Absolute difference | absdiff.v |
| absdiffs | Signed absolute difference | absdiffs.v |
| add | Adder | add.v |
| addmod | Wide modular adder (a+b) mod m | addmod.v |
| addsub | Adder-subtractor | addsub.v |
| addtree | Balanced adder-reduction tree | addtree.v |
| argmax | Index of max over N | argmax.v |
| argmin | Index of min over N | argmin.v |
| atan | Arctangent (CORDIC vectoring) | atan.v |
| 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) | cos.v |
| 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) | div.v |
| divs | Signed integer divide (sequential) | divs.v |
| dotprod | Dot product | dotprod.v |
| exp | Exponential (range-reduce + poly) | exp.v |
| fmadd8 | Fused multiply-add, E4M3 fp8 | fmadd8.v |
| fmadd16 | Fused multiply-add, bf16 | fmadd16.v |
| fmadd32 | Fused multiply-add, fp32 | fmadd32.v |
| gelu | GELU activation (sigmoid approx) | gelu.v |
| hswish | Hard-swish activation | hswish.v |
| inc | Incrementer | inc.v |
| ln | Natural logarithm (normalize + poly) | ln.v |
| log2 | Log base 2 | log2.v |
| lrelu | Leaky ReLU activation | lrelu.v |
| 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) | mod.v |
| msub | Multiply-subtract | msub.v |
| mul | Multiplier | mul.v |
| muladd | Multiply-add | muladd.v |
| muladdc | Complex multiply-add | muladdc.v |
| muladds | Signed multiply-add | muladds.v |
| mulc | Complex multiply | mulc.v |
| mulreg | Registered multiplier | mulreg.v |
| muls | Signed multiplier | muls.v |
| 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) | recip.v |
| relu | ReLU activation function | relu.v |
| requant | Requantize (mul-shift-round-saturate) | requant.v |
| rotl | Rotate left (barrel) | rotl.v |
| rotr | Rotate right (barrel) | rotr.v |
| round | Rounder | round.v |
| rsqrt | Fixed-point inverse sqrt (sequential) | rsqrt.v |
| 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) | sigmoid.v |
| simdmul | Packed SIMD multiply | simdmul.v |
| sine | Sine function | sine.v |
| sqdiff | Squared difference | sqdiff.v |
| sqrt | Square root | sqrt.v |
| sub | Subtractor | sub.v |
| sum | Summation tree | sum.v |
| tanh | Tanh activation (PLAN PWL) | tanh.v |
| Benchmark | Description | Verilog |
|---|---|---|
| cache | Cache memory | cache.v |
| cam | Content-addressable memory | cam.v |
| 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 | regfile.v |
| rom | Read-only memory | rom.v |
| Benchmark | Description | Verilog |
|---|---|---|
| aes | AES encryption core | aes.sv |
| apbregs | APB register file | apbregs.v |
| axicrossbar | AXI crossbar | axi_crossbar.v |
| axiram | AXI RAM interface | axiram.v |
| blackparrot | BlackParrot RISC-V core | blackparrot/ |
| conv2d | Streaming 3x3 2D convolution | conv2d.v |
| coralnpu | CoralNPU neural accelerator | coralnpu.sv |
| crc32 | CRC-32 generator | crc32.v |
| codec8b10b | 8b/10b line encoder/decoder | codec8b10b.v |
| cva6 | CVA6 (Ariane) RISC-V core | cva6.sv |
| ddc | Digital down-converter (NCO/mixer/CIC/FIR) | ddc.v |
| ethmac | Ethernet MAC | ethmac.v |
| fft | Fast Fourier Transform | fft.v |
| 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 | gearbox66.v |
| hamming | Hamming ECC encoder/decoder | hamming.v |
| hft | Tick-to-trade HFT pipeline | hft.v |
| hmac | HMAC-SHA hashing | hmac.sv |
| huffman | Canonical Huffman encoder/decoder | huffman.v |
| i2c | I2C controller | i2c.sv |
| ialu | Integer ALU | ialu.v |
| jesd204b | JESD204B full-duplex link interface | jesd204b.v |
| lfsr | Linear feedback shift register | lfsr.v |
| linkmap | JESD204-style transport framer/deframer | linkmap.v |
| lpddr5 | LPDDR5 memory controller (UMI + DFI, ECC) | lpddr5_umi.v |
| lz77 | LZ77 (LZSS) compressor/decompressor | lz77.v |
| median3x3 | Streaming 3x3 median filter | median3x3.v |
| nvdla | NVDLA deep-learning accelerator | nvdla/ |
| ofdm | OFDM modem (QAM + IFFT/FFT) | ofdm.v |
| openpiton | OpenPiton manycore tile | openpiton.v |
| picorv32 | PicoRV32 RISC-V core | picorv32.v |
| reedsolomon | Reed-Solomon RS(544,514) codec | reedsolomon.v |
| rocket | Rocket RISC-V core | rocket.v |
| sad8x8 | 8x8 sum of absolute differences | sad8x8.v |
| serv | SERV bit-serial RISC-V core | serv/ |
| sobel3x3 | Streaming 3x3 Sobel edge detector | sobel3x3.v |
| spi | SPI controller | spi.sv |
| tpu | Weight-stationary systolic matrix multiply (TPU MXU) | tpu.v |
| uart | UART | uart.sv |
| umicross | UMI crossbar | umicross/ |
| umidev | UMI device endpoint | umidev/ |
| umiregs | UMI register file | umiregs.v |
| viterbi | Viterbi decoder | viterbi.v |
| vortex | Vortex GPU core | vortex/ |
| wally | CVW-Wally RISC-V core | wally/ |
| wordalign | Comma detect + bitslip aligner | wordalign.v |
| Benchmark | Description | Verilog |
|---|---|---|
| epfl_adder | EPFL adder benchmark | epfl_adder.v |
| epfl_arbiter | EPFL arbiter benchmark | epfl_arbiter.v |
| epfl_bar | Barrel shifter | epfl_bar.v |
| epfl_cavlc | CAVLC encoder | epfl_cavlc.v |
| epfl_dec | Decoder | epfl_dec.v |
| epfl_div | Divider | epfl_div.v |
| epfl_hyp | Hypotenuse calculator | epfl_hyp.v |
| epfl_i2c | I2C controller | epfl_i2c.v |
| epfl_int2float | Integer to float converter | epfl_int2float.v |
| epfl_log2 | Log base 2 | epfl_log2.v |
| epfl_max | Maximum | epfl_max.v |
| epfl_memctrl | Memory controller | epfl_memctrl.v |
| epfl_multiplier | Multiplier | epfl_multiplier.v |
| epfl_priority | Priority encoder | epfl_priority.v |
| epfl_router | Router | epfl_router.v |
| epfl_sin | Sine function | epfl_sin.v |
| epfl_sqrt | Square root | epfl_sqrt.v |
| epfl_square | Square function | epfl_square.v |
| epfl_voter | Voter circuit | epfl_voter.v |
Combinational gate-level circuits. See iscas85/README.md.
| Benchmark | Description | Verilog |
|---|---|---|
| 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 | Verilog |
|---|---|---|
| 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 |
Targets ranked by total LUTs over all benchmarks (config: small), lowest first. A benchmark with no result for a target is charged the highest LUT count any target reached on it.
Comparing different FPGA architectures is by definition an apples to oranges exercise. Ranking by no means implies quality or goodness, it's just a neat way to compress and order data.
ASIC leaderboard tables (cell area and FMAX, starting with freepdk45) are
work in progress and will be published here once results are collected.
LogikBench itself is pure Python and installs 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 |
The LogikBench project is licensed under the MIT license unless specified otherwise inside the individual benchmark folders.
