HDL Export API¶
The bitlogic.hdl submodule turns a trained nn.Sequential — optionally
starting with a Thermometer /
DistributiveThermometer encoder plus
nn.Flatten, followed by one or more LogicDense
layers and one GroupSum head — into a single
SystemVerilog module, and optionally drives Yosys against the Nangate 45 nm
Open Cell Library to extract a NAND2-equivalent gate count — the primary
hardware-cost metric for bitlogic experiments.
When the encoder is present, the emitted module takes a packed x_int8
input (one unsigned 8-bit byte per input slot) and emits the thermometer
comparators inline as combinational logic. With no encoder, the legacy
x_bin port is kept for backwards-compatibility.
Sequential behavior is controlled via
HDLExportOptions. Each of the three stages
(encoder, logic layers, GroupSum) independently selects between
replication ("parallel", fully combinational) and iterative
decomposition ("iterative", time-multiplexed with a shared unit), and
each can have a flip-flop stage inserted at its output boundary
(pipeline_encoder / pipeline_logic_layers / pipeline_groupsum). All
defaults reproduce the pre-v2 pure-combinational emission so existing
callers see no change.
See the HDL Export guide for an end-to-end walkthrough.
Top-level helpers¶
emit_systemverilog ¶
emit_systemverilog(model: Module, *, top_name: str = 'logic_net', options: HDLExportOptions | None = None) -> str
Emit a SystemVerilog module for a trained bitlogic model.
The input model must be an nn.Sequential that optionally starts
with a :class:Thermometer / :class:DistributiveThermometer (plus
optional :class:nn.Flatten), then one or more :class:LogicDense
layers, then exactly one :class:GroupSum head. The model is put into
eval mode so learnable routing is frozen (via argmax) before LUT
extraction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Module
|
Trained module to export. |
required |
top_name
|
str
|
Name of the emitted SystemVerilog module. Also the Yosys top-level. |
'logic_net'
|
options
|
HDLExportOptions | None
|
Sequential-behavior controls. See :class: |
None
|
Returns:
| Type | Description |
|---|---|
str
|
A string containing the SystemVerilog source. Write it to a |
str
|
file before handing to Yosys. |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the model's submodule layout is unsupported, or an encoder is present but its configuration is outside the supported v2 scope. |
ValueError
|
If the last logic layer's |
HDLExportOptions
dataclass
¶
HDLExportOptions(encoder_style: Literal['parallel', 'iterative'] = 'parallel', groupsum_style: Literal['parallel', 'iterative'] = 'parallel', pipeline_encoder: bool = False, pipeline_logic_layers: bool = False, pipeline_groupsum: bool = False, io_shim: bool = False)
Knobs controlling the sequential behavior of the emitted module.
All defaults reproduce the pre-v2 pure-combinational emission so existing callers see no change.
Attributes:
| Name | Type | Description |
|---|---|---|
encoder_style |
Literal['parallel', 'iterative']
|
|
groupsum_style |
Literal['parallel', 'iterative']
|
Applies to whichever head the model uses.
|
pipeline_encoder |
bool
|
Insert a flip-flop on |
pipeline_logic_layers |
bool
|
Insert a flip-flop after every
:class: |
pipeline_groupsum |
bool
|
Insert a flip-flop on the |
io_shim |
bool
|
Wrap the generated core module in a thin BRAM-backed
register shim so place+route can succeed on FPGAs that don't
have enough physical pins to expose the wide |
resolve_liberty ¶
Return a path to a usable Nangate Liberty file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
explicit
|
str | Path | None
|
User-provided path. If given, it is returned as-is (after existence check) with no download or checksum verification. |
None
|
verify_sha
|
bool
|
If |
True
|
Returns:
| Type | Description |
|---|---|
Path
|
Absolute path to the Liberty file. |
Raises:
| Type | Description |
|---|---|
LibertyError
|
If no usable file can be resolved (network failure + no cache, bad explicit path, etc.). |
synthesize ¶
Yosys driver for bitlogic HDL export.
Writes a flow script, invokes yosys, and parses the resulting stat
report into a NAND2-equivalent gate count. Total chip area is divided by the
NAND2_X1 area (parsed out of the Liberty file in :mod:.liberty) to obtain
the nand2_ge metric.
The flow is intentionally a thin shell around a known-good Yosys incantation; no custom passes, no liberty-specific tuning. That keeps the metric reproducible and portable.
YosysError ¶
Bases: RuntimeError
Raised when the Yosys subprocess fails or its output is unparseable.
SynthMetrics
dataclass
¶
SynthMetrics(total_area_um2: float, nand2_area_um2: float, nand2_ge: float, cell_counts: dict[str, int] = dict(), top_module: str = 'logic_net', liberty_path: str = '')
Primary hardware-cost metrics extracted from a Yosys run.
synthesize ¶
synthesize(sv_path: str | Path, *, out_dir: str | Path, liberty_path: str | Path, top: str = 'logic_net', keep_tmp: bool = False, abc_fast: bool = False) -> SynthMetrics
Run Yosys on an emitted SystemVerilog file and extract NAND2-eq GE.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sv_path
|
str | Path
|
Path to the |
required |
out_dir
|
str | Path
|
Directory to write |
required |
liberty_path
|
str | Path
|
Path to |
required |
top
|
str
|
Top-level module name (must match :func: |
'logic_net'
|
keep_tmp
|
bool
|
If |
False
|
abc_fast
|
bool
|
If |
False
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
SynthMetrics
|
class: |
Raises:
| Type | Description |
|---|---|
YosysError
|
If |
LibertyError
|
If |
Metrics + exceptions¶
SynthMetrics
dataclass
¶
SynthMetrics(total_area_um2: float, nand2_area_um2: float, nand2_ge: float, cell_counts: dict[str, int] = dict(), top_module: str = 'logic_net', liberty_path: str = '')
Primary hardware-cost metrics extracted from a Yosys run.
cell_counts
class-attribute
instance-attribute
¶
LibertyError ¶
Bases: RuntimeError
Raised when the Nangate Liberty file cannot be resolved.
YosysError ¶
Bases: RuntimeError
Raised when the Yosys subprocess fails or its output is unparseable.
Low-level surfaces¶
nand2_area_um2 ¶
Parse the NAND2_X1 cell area (μm²) out of a Liberty file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lib_path
|
str | Path
|
Path to a Nangate 45 nm Liberty |
required |
Returns:
| Type | Description |
|---|---|
float
|
Area of the |
Raises:
| Type | Description |
|---|---|
LibertyError
|
If the file cannot be read or the cell / area field is not found. |
ExportModel
dataclass
¶
ExportModel(input_width: int, layers: tuple[_LayerSpec, ...], num_classes: int, group_width: int, head: _HeadSpec = None, encoder: _EncoderSpec | None = None)
Metadata for an exported model — intermediate between walk and emit.