Naja is an open source EDA framework for loading, elaborating, analyzing, optimizing, and transforming hardware designs from SystemVerilog and VHDL RTL through structural netlists. It is usable from Python or C++.
- SV/Verilog frontend — parse Verilog and elaborate SystemVerilog RTL into a browsable design model
- VHDL frontend (Beta) — parse and elaborate supported VHDL RTL into the same design model
- Netlist analysis — hierarchy, connectivity, equipotentials
- Logic optimization — dead logic elimination, constant propagation
- ECO transformations — direct netlist editing
- Serialization — SNL interchange format (Cap'n Proto) and Verilog output
The diagram below shows how formats, frontends, APIs, and companion tools integrate around Naja's C++ netlist engine:
- Design inputs — SystemVerilog is parsed and elaborated through
slang; VHDL is parsed and elaborated through the naja-vhdl frontend (Beta); gate-level Verilog can be loaded and emitted; and Liberty plus the Python primitive libraries provide cell and primitive models. - Core and interchange — Naja represents hierarchy, buses, bit-level nets
and terms, connectivity, and primitive functional models. The
naja-ifCap'n Proto format provides a logical-view interchange path. - APIs and tools —
najaedaexposes the engine through Python. Companion projects build on Naja directly or through that API:kepler-formal,naja-schematic, andnaja-scope.
---
config:
layout: dagre
theme: base
themeVariables:
fontFamily: ''
fontSize: 14px
primaryTextColor: '#172033'
lineColor: '#64748b'
clusterBkg: '#f8fafc'
clusterBorder: '#cbd5e1'
---
flowchart LR
sv["`**SystemVerilog**`"] ==> slang(["`**slang**<br>SystemVerilog Frontend`"])
vhdl["`**VHDL**`"] ==> naja-vhdl["`**naja-vhdl**<br> VHDL Frontend (Beta)`"]
verilog["`**gate-level verilog**`"] ==> naja-verilog["`**naja-verilog**<br>gate verilog Parser`"]
naja-verilog ==> naja["`**naja C++ · netlist engine**<br><br>hierarchy · buses<br>bit-level nets & terms · connectivity<br>Primitive Functional Models`"]
naja-vhdl =="`**Elaboration**`"==> naja
najaif@{ label: "**naja-if**<br>Logical View Interchange Format<br>Cap'n Proto" } <==> naja
slang =="`**Elaboration**`"==> naja
naja <==> najaeda["`**najaeda**<br>Python API`"]
naja ==> kf("`**kepler-formal**<br>Formal Comparison`") & ns("`**naja-schematic**<br>Schematic Viewer`")
najaeda ==> scope("`**naja-scope**<br>najaeda MCP server`")
kf ==> kfm("`**kepler-formal-mcp**<br>kepler-formal MCP server`")
lib["`**Liberty**`"] ==> naja
pythonlibs["`**Python libraries**<br>naja representation`"] ==> naja
sv@{ shape: disk}
vhdl@{ shape: disk}
verilog@{ shape: disk}
naja@{ shape: rounded}
najaif@{ shape: disk}
lib@{ shape: disk}
pythonlibs@{ shape: disk}
sv:::input
vhdl:::input
slang:::frontend
naja-verilog:::frontend
naja-vhdl:::frontend
verilog:::input
naja:::core
najaif:::input
najaeda:::api
kf:::tool
kfm:::tool
ns:::tool
scope:::tool
lib:::input
pythonlibs:::input
classDef input fill:#eef2ff,stroke:#6366f1,color:#1e1b4b,stroke-width:2px
classDef frontend fill:#fff7ed,stroke:#f97316,color:#431407,stroke-width:2px
classDef core fill:#fef2f2,stroke:#ef4444,color:#450a0a,stroke-width:3px
classDef api fill:#f0fdfa,stroke:#14b8a6,color:#042f2e,stroke-width:2px
classDef tool fill:#f5f3ff,stroke:#8b5cf6,color:#2e1065,stroke-width:2px
click slang "https://github.com/MikePopoloski/slang"
click naja-verilog "https://github.com/najaeda/naja-verilog"
click naja "https://github.com/najaeda/naja"
click najaif "https://github.com/najaeda/naja-if"
click najaeda "https://pypi.org/project/najaeda/"
click kf "https://github.com/keplertech/kepler-formal"
click kfm "https://github.com/keplertech/kepler-formal-mcp"
click ns "https://github.com/najaeda/naja-schematic"
click scope "https://github.com/najaeda/naja-scope"
The best entry point is the najaeda Python package:
pip install najaedaRequires Python 3.10 or later. Pre-built wheels are published for:
- Linux x86_64 and AArch64 (
manylinux_2_28; glibc 2.28 or later) - macOS Apple Silicon (arm64), macOS 11 or later
- Windows x86_64
Full documentation: najaeda.readthedocs.io
For AI-assisted design exploration, naja-scope
is a najaeda-based MCP server that gives MCP-compatible assistants a precise,
structured view of elaborated SystemVerilog or VHDL designs. Instead of pasting large
RTL files into chat, agents can ask targeted questions — what drives a signal,
what is inside a module, where a net comes from — and get small, exact answers
with file-and-line references.
Six hands-on notebooks — open any of them in Colab with no local install needed:
naja_edit is a command-line tool for optimizing and translating netlists.
📺 Presented at ORConf 2024.
# Translate Verilog → SNL
naja_edit -f verilog -t snl -i input.v -o output.snl
# Parse SystemVerilog with explicit top
naja_edit -f systemverilog -t verilog -i input.sv -o output.v --sv_top top
# Dead logic elimination
naja_edit -f snl -t snl -i input.snl -o output.snl -a dle
# Chain optimizations with Python scripts
naja_edit -f snl -t snl -i input.snl -o output.snl -a dle -e pre.py -z post.pyAvailable optimizations (-a): all (DLE + constant propagation + primitives), dle.
Python script examples: src/apps/naja_edit/examples
Regression suite: naja-regress
CMake is Naja's primary build, test, and install workflow. Bazel is maintained as a build-and-test smoke path; it does not replace the CMake install and packaging workflows.
Ubuntu:
sudo apt-get update
sudo apt-get install build-essential cmake git libboost-dev python3-dev \
capnproto libcapnp-dev libtbb-dev pkg-config bison flexmacOS (Homebrew):
brew install cmake capnp tbb bison flex boost
export PATH="/opt/homebrew/opt/flex/bin:/opt/homebrew/opt/bison/bin:$PATH"Nix:
nix-shell -p cmake gnumake boost python3 capnproto bison flex pkg-config tbb_2021_8git clone --recurse-submodules https://github.com/najaeda/naja.git
cd naja
export NAJA_INSTALL="$PWD/install"
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX="$NAJA_INSTALL"
cmake --build build --parallel
ctest --test-dir build --output-on-failure
cmake --install build
# Add the installed Python package to your environment.
export PYTHONPATH="${PYTHONPATH:+$PYTHONPATH:}$NAJA_INSTALL/lib/python"The Bazel build covers the repository's build and test targets on Ubuntu and
macOS. The version is pinned in .bazelversion; using
Bazelisk as the bazel command
automatically selects it.
Bazel fetches its own pinned copies of the shared source dependencies, so a Bazel-only checkout does not need Git submodules. It still uses system toolchains and libraries for parts of the build.
Ubuntu:
sudo apt-get update
sudo apt-get install build-essential cmake libboost-dev libfl-dev libtbb-dev \
bison flex m4 pkg-config python3-dev gitmacOS (Homebrew):
Install the Xcode Command Line Tools, then:
brew install cmake capnp tbb bison flex boost fmt tomlplusplus pkg-config
export PATH="$(brew --prefix flex)/bin:$(brew --prefix bison)/bin:$PATH"Build and test from the repository root:
git clone https://github.com/najaeda/naja.git
cd naja
bazel build //... --jobs=auto
bazel test //... --test_output=errors --jobs=autoThese are the same smoke commands used by
ubuntu-bazel.yml and
macos-bazel.yml. There is no Bazel
install target; use the CMake workflow above when you need an installed
library, Python package, or packaged artifact.
When changing a shared dependency pin, keep the Git submodule and
MODULE.bazel entries synchronized, then run:
python3 ci/check_submodule_bazel_sync.pyNaja exposes two complementary APIs:
- SNL (Structured Netlist) — full read/write netlist representation
- DNL (Dissolved Netlist) — fast, read-only flattened view for parallel analysis
Extended documentation: naja.readthedocs.io
C++ snippet: NLUniverseSnippet.cpp
App template (copy to start a new tool): src/app_snippet
- Chat: Matrix #naja:fossi-chat.org
- Bugs / features: GitHub Issues
- Contact: contact@keplertech.io
⭐ If you find Naja useful, starring the repo helps spread the word.
Supported by NLNet through the NGI0 Entrust Fund.

