This repository is not intended to be used as a standalone project. It is vendored and consumed by the GENIAL and Flowy projects. Prefer calling these utilities through those parent toolchains. If you do use it directly, do so inside that context and at your own discretion.
Lightweight helpers to parse synthesised netlists and compute switching activity from simulation databases. Shared by GENIAL and Flowy to keep logic consistent across projects.
- Overview
- Features
- Install
- Quick Usage
- Inputs and assumptions
- Supported operations and technologies
- Testing
- License
swact centralises small, dependency‑light routines used to:
- Extract a wire‑level graph and per‑wire “weights” (e.g., transistor count, area, capacitance) from synthesised Verilog netlists.
- Turn time‑series of wire values into per‑wire switching vectors and aggregate activity metrics.
Keeping this in one package ensures GENIAL and Flowy share the exact same implementation and benefit simultaneously from fixes and improvements.
- Vectorised switching‑vector computation from DataFrames of wire values.
- Weighted activity using fan‑out metrics (transistor count, gate area, capacitance when available).
- Netlist parsing: cell graph, per‑wire fan‑out, depth metrics, and Yosys primitive renaming.
- Lightweight: pure Python with
numpyandpandasonly.
Inside the monorepo (recommended):
uv pip install -e ext/swactStandalone (not recommended; see disclaimer):
pip install -e .Import paths below assume the package is installed (editable or wheel) and your Python environment is active.
Compute aggregate switching metrics directly from a synthesised netlist and a simulation database (Parquet):
from swact import analysis_swact
stats = analysis_swact(
synthed_design_path="synth/out/mydesign_yosys.v",
tb_results_path="sim/results.parquet",
in_bitwidth=8,
out_bitwidth=16,
operation="multiplication", # or addition, subtraction, encoding, mux_sign
technology_name="notech_yosys", # or asap7
weight_key="transistor_count", # or gate_area, capacitance, capacitance_calibrated (if present)
)
print(stats)
# {
# 'swact_count': 0.xx, # mean toggles/cycle (unweighted)
# 'swact_count_weighted': 0.yy, # mean weighted toggles/cycle
# 'n_cycles': 1234,
# 'n_wires': 456
# }When you already have a DataFrame of time‑series values (or want to reuse design parsing across many sims):
import pandas as pd
from swact import extract_data_from_design, extract_swact_from_tb_results
design = extract_data_from_design(
"synth/out/mydesign_yosys.v",
in_bitwidth=8, out_bitwidth=16,
operation="multiplication",
technology_name="notech_yosys",
weight_key="transistor_count",
)
df = pd.read_parquet("sim/results.parquet")
stats = extract_swact_from_tb_results(df, design)import pandas as pd
from swact import get_swact_table, apply_weights_to_switch_vectors
# `df` contains columns that are either per‑wire bits or will be expanded by the caller.
db_switch, db_switch_weighted = get_swact_table(df, wire_fanout_dict={})
db_switch_weighted = apply_weights_to_switch_vectors(db_switch, wire_fanout_dict)- The simulation database is expected as a
pandasDataFrame (e.g., loaded from Parquet) where each column is a wire value over time. - If your DB stores operand representations as binary strings (e.g., columns like
input0_rep,input1_rep), upstream code in GENIAL/Flowy expands those to per‑bit wires.swactalso provides a helperreformat_result_databaseswhen needed. - Netlists should be the synthesised Verilog emitted by Yosys or a mapped library;
swactincludes a light renaming pass to normalise Yosys$primitives.
- Operations (wire list generation):
multiplication,addition,subtraction,encoding,mux_sign. - Technologies (gate dictionaries and renaming):
notech_yosys,asap7.
Weights can be sourced from:
transistor_count(default)gate_areacapacitance,capacitance_calibrated(if the corresponding JSON exists underswact/resources/libraries/<tech>/).
See swact.gates_configuration.GatesConfig for details.
Run the test suite from this folder:
uv pip install -e .[test]
pytest -q- See LICENSE.md