Synthesizer
veryl synth performs lightweight logic synthesis on the project and reports
approximate area, timing and power. It is intended as a quick feedback tool
during design exploration, not a replacement for a production synthesis flow.
The design is mapped to a representative subset of cells in the selected
library, but place-and-route, load capacitance, drive strength and Vth selection
are not considered.
$ veryl synth
The top module is selected as follows, in order of priority:
- CLI
--top <name>if supplied synth.topinVeryl.tomlif set- The first user module discovered in the project
The available configurations such as the cell library, clock frequency and
toggle activity are described in [synth].
Output
By default, veryl synth prints a one-line summary plus area / timing / power
detail blocks:
synth: TopModule — 123 gates, 17 FFs
library: sky130_fd_sc_hd ...
summary:
area: 1234.56 um² (comb 1000.00, seq 134.56, mem 100.00)
timing: 2.345 ns 8 levels in_dat → out_dat
power: 0.1234 mW (leak 0.0123 mW, dyn 0.1111 mW)
@ f_clk = 100 MHz, activity = 0.10
area:
...
timing:
...
power:
...
RAM inference
A large array is mapped to an SRAM macro instead of depth × width flip-flops
plus an address decode/mux tree. A bit-array macro is far denser and faster, so
modelling it directly keeps the area, timing and power estimates realistic for
memory-heavy designs such as caches and register files.
An array is inferred as a RAM block when all of the following hold:
- it has at least
ram_min_bits(default 1024) stored bits and a depth of 2 or more; - it is written without a reset, through whole-word dynamic-address writes
(
mem[addr] = data), with at mostram_max_write_ports(default 8) distinct write sites; - it is read through whole-word dynamic addresses (
mem[addr]), with at mostram_max_read_ports(default 16) distinct read addresses.
An array written under if_reset stays as flip-flops, because real SRAM has no
reset — so an array intended to become SRAM is written reset-less in the RTL.
Partial or sub-word writes also keep the array as flip-flops.
A dynamically-indexed array that fails inference but is larger than
ram_max_ff_bits (default 65536 stored bits) cannot be expanded into flip-flops
without exhausting memory, so synthesis reports an error instead. Write such an
array reset-less so it is inferred as RAM, or raise ram_max_ff_bits.
These thresholds are configurable in the [synth]
section of Veryl.toml.
The inferred memory area is reported as the mem term of the area summary, and
--dump-area lists each block grouped by shape (depth × width) and port count:
ram: 2 blocks
1024×32 1R1W ×1 32768 bits 189.40 um²
512×64 2R1W ×1 32768 bits 189.40 um²
Options
| Option | Description |
|---|---|
--top <name> | Top module name. Overrides synth.top in Veryl.toml. |
--timing-paths <n> | Number of worst-delay endpoints to report when dumping timing. Overrides synth.timing_paths. |
--dump-ir | Dump the gate-level IR (netlist of gates and flip-flops). |
--dump-area | Dump the per-cell-kind area breakdown, including inferred RAM blocks. |
--dump-timing | Dump the critical path trace. |
--dump-power | Dump the power estimate (leakage + dynamic breakdown). |
--format <format> | Output format: pretty (default, human-readable) or json. |
--format-version <n> | JSON report schema version. Only valid with --format json. Currently only 1. |
If no --dump-* flag is given, all three of area / timing / power are dumped.
JSON report
--format json writes a machine-readable report to stdout instead of the human-readable summary.
$ veryl synth --format json
{
"format_version": 1,
"top": "Counter",
"library": "sky130",
"status": "ok",
"cells": 19,
"ffs": 8,
"area": { "total": 302.5, "combinational": 122.5, "sequential": 180.0, "memory": 0.0 },
"timing": { "delay_ns": 0.38, "depth": 4, "from": "cnt[3]", "to": "cnt[6]" },
"power": { "total_mw": 0.0239, "leakage_mw": 0.0000271, "dynamic_mw": 0.0239, "clock_freq_mhz": 100.0, "activity": 0.1 }
}
The status field is ok when synthesis succeeded.
Otherwise it is unsupported for a construct which the synthesizer can’t handle, no_top when the top module is not found, and error for the other failures.
In these cases a message field describes the failure, and area, timing and power are null.