This project implements different 32-bit multiplier algorithms in digital design and will analyze metrics using open-source EDA tools.
Currently, this project has three different implementations:
- Default
*operator in SystemVerilog - Radix-2 Pipelined Multiplication
- Radix-4 Multiplication
Verilator- Fast RTL simulation and lintingIcarus Verilog- 4-state RTL simulationCocoTB- Python-based HDL verificationYosys- RTL synthesisOpenLane 2- ASIC RTL-to-GDSII flowOpenSTA- Static timing analysis, included through OpenLaneOpenROAD- Place-and-route, included through OpenLaneGTKWaveorSurfer- Waveform viewing (Either works well)
Recommended to use Python3.10+, git, and Ubuntu.
This project implements and verifies a 32-bit radix-4 multiplier in SystemVerilog, then runs it through an open-source ASIC flow using OpenLane 2 and the SkyWater SKY130 PDK.
config.json- Synthesis Config FileMakefilertl/- Where all RTL livesradix4_mult.svcounter.sv
tests/- System Verilog Testbenchestb_radix4_mult/- Main Testbench
cocotests/- CocoTB tests if neededscripts/- Helpful automation scriptsruns/- OpenLane Results
Currently, this project is organized as three separate multiplier implementations:
def_mult/ # RTL-inferred SystemVerilog '*' multiplier
radix2_mul/ # Radix-2 pipelineed multiplier
radix4_mul/ # Radix-4 Booth multiplier
The project required to be run on an Ubuntu Linux-baed machine using GNU Make.
Install common dependencies:
sudo apt update
sudo apt install -y \
build-essential \
git \
make \
findutils \
coreutils \
python3 \
python3-pip \
python3-venv \
python3-dev \
verilator \
iverilog \
gtkwaveVerify the installed RTL tools:
verilator --version
iverilog -V
vvp -V
python3 --version
make --versionCreate a Python virtual environment from the repository root:
python3 -m venv .venv
source .venv/bin/activateInstall the Python dependencies used by cocotb and the result-processing scripts:
python3 -m pip install --upgrade pip
python3 -m pip install cocotb matplotlibVerify the cocotb installation:
cocotb-config --versionActivate the environment before running cocotb tests or Python data-analysis scripts:
source .venv/bin/activateDeactivate the environment when finished:
deactivateThis project invokes OpenLane using the Classic flow interface:
openlane --flow Classic config.jsonOpenLane provides the RTL-to-GDSII ASIC flow and uses tools including Yosys, OpenROAD, OpenSTA, Magic, KLayout, and the SkyWater SKY130 PDK.
Enter the OpenLane environment before running physical-design commands. For a Nix-based installation, this is typically done from the OpenLane installation directory:
nix-shell --pure shell.nixVerify that OpenLane and OpenROAD are available:
openlane --version
openroad -versionKeep the OpenLane installation outside this repository. The multiplier repository should contain project RTL, configurations, scripts, and saved flow results rather than a local copy of the ASIC toolchain.
The Makefile passes PDKPATH as an include path during linting and uses it for gate-level simulation. The OpenROAD Tcl loader also uses it, when provided, to locate the Sky130A PDK Liberty timing models.
Set PDKPATH to the root of the installed Sky130A PDK:
export PDKPATH=/path/to/sky130AFor example, a Volare-based installation may look similar to:
export PDKPATH="$HOME/.volare/volare/sky130/versions/<version>/sky130A"Confirm that it is set:
echo "$PDKPATH"To persist this variable between terminal sessions, add it to ~/.bashrc:
echo 'export PDKPATH=/path/to/sky130A' >> ~/.bashrc
source ~/.bashrcReplace /path/to/sky130A with the actual local PDK installation path.
From a multiplier directory, such as radix4_mul/, run:
verilator --version
iverilog -V
cocotb-config --version
openlane --version
openroad -version
echo "$PDKPATH"A successful result from each tool and a non-empty PDKPATH indicate that the required environment is available.
Run the following commands from one multiplier directory:
cd radix4_mulRun Verilator linting on all RTL files:
make lintLint a specific top-level module:
make lint_top TOP_MODULE=<module_name> TOP_FILE=<rtl_file>Example:
make lint_top TOP_MODULE=radix4_mult TOP_FILE=rtl/radix4_mult.svRun all SystemVerilog tests using Verilator, the default simulator:
make testsThe default make target performs both linting and RTL simulation:
makeRun the same SystemVerilog tests using Icarus Verilog:
make itestsThis invokes:
ICARUS=1 make testsUse both simulators when practical:
- Verilator is the default fast simulator and linter.
- Icarus Verilog provides event-driven, four-state simulation and can expose initialization or unknown-value behavior not visible in a two-state simulation flow.
Run all cocotb test directories:
make cocotestsActivate the Python environment first:
source ../.venv/bin/activate
make cocotestsWhen invoked from a multiplier directory, the virtual environment is expected to be located one directory above it in the repository root.
Run OpenLane using the default configuration file:
make openlaneThe Makefile uses:
openlane --flow Classic config.*To run a specific configuration file explicitly:
make config.jsonor:
make config.yamlOpenLane writes its artifacts to the local runs/ directory. After a successful flow, the Makefile updates:
runs/recent
to point to the newest generated run directory.
For reproducible experiments, record the exact timestamped run directory rather than relying only on runs/recent.
Once the multiplier design has completed through the flow (or at the very least passed an openlane run), a gate-level netlist will be generated. This is a verilog file of your design using only standard cell gates.
It can be found in the pnl folder of your final results. Look in runs/recent/final/pnl/
Note: this must be run on Icarus Verilog because Verilator does not support certain gate-level features (as far as I know).
Run gate-level simulation against the most recent post-layout netlist:
make gl_testsLaunch OpenROAD and load the most recent finalized OpenLane result:
make openroadThis is equivalent to:
RUN_DIR=runs/recent openroad -gui scripts/openroad_load.tclThe Tcl loader automatically:
- locates the final OpenDB database and SDC constraints;
- finds the Sky130 HD Liberty timing model;
- attempts to load extracted SPEF parasitics;
- reports worst setup and hold slack;
- prints the top setup and hold timing paths;
- opens the OpenROAD GUI.
Open a specific historical run:
make openroad RUN_DIR=runs/RUN_YYYY-MM-DD_HH-MM-SSUse a different timing Liberty corner:
make openroad LIB_CORNER=sky130_fd_sc_hd__tt_025C_1v80.libBy default, the Tcl loader uses:
sky130_fd_sc_hd__ss_100C_1v60.lib
This slow process, high-temperature, low-voltage corner is appropriate for inspecting setup-critical paths.
Remove generated test waveforms, simulation binaries, logs, and Verilator build directories:
make cleanThis removes generated files under the local tests/ directory, including:
*.vcd
*.log
a.out
obj_dir/
- Use
collect_metrics.pyto parse through an openlane run and gather essential metrics.
-
Default run on a single run:
python3 scripts/collect_metrics.py runs/recentor
python3 scripts/collect_metrics.py \ --design default:def_mult/runs/recent \ --design radix4_mul:radix4/runs/recent \ --design radix2_mul:radix2_mult/runs/recent \ --out-csv results/metrics_summary.csv \ --out-json results/metrics_summary.json- Use
--name default_multo label which multiplication algorithm - Use
--summaryto write a summary after writing CSV or JSON
- Use
-
Use
plot_metrics.pyto plotcollect_metrics.pyresultspython3 scripts/plot_metrics.py results/metrics_summary.csv- Use
--out-dirto specifify output directory. Defaults toresults/plots - Use
--formatto specify output format. Only PDF, PNG, or SVG.- For example:
python3 scripts/plot_metrics.py results/metrics_summary.csv \ --out-dir paper/figures \ --format pdf
- For example:
- Use
--dpisets the resolution used for raster format. Dedfaults to 300-
For example:
python3 scripts/plot_metrics.py results/metrics_summary.csv \ --format png \ --dpi 600
-
- Use
Use antenna_debug.py to review antenna violation information for debugging.
-
Default Run:
python3 scripts/antenna_debug.py runs/<RUN>Writes report to default path:
runs/<RUN>/antenna_debug_summary.txt -
Use
--show-cleanto include steps where antenna violations are zero. This can be useful to show a timeline of where violaions appeared or repaired. -
Use
--net <NET>to report around a specific net- Ex:
python3 scripts/antenna_debug.py runs/RUN_2026-06-17_21-29-12 --net _01566_will only include antenna reports that mention_01566_, Additionally, it will also mention the net-context section searches for_01566_in DEF, Verilog, and antenna logs.
- Ex:
-
Use
--out <DIR>to write the report to a specific directory.
- Check out Cal Poly's CARP website for more information and resources: