Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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:

  1. CLI --top <name> if supplied
  2. synth.top in Veryl.toml if set
  3. 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 most ram_max_write_ports (default 8) distinct write sites;
  • it is read through whole-word dynamic addresses (mem[addr]), with at most ram_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

OptionDescription
--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-irDump the gate-level IR (netlist of gates and flip-flops).
--dump-areaDump the per-cell-kind area breakdown, including inferred RAM blocks.
--dump-timingDump the critical path trace.
--dump-powerDump 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.