Skip to content

Latest commit

 

History

1,465 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Naja Logo

Naja

PyPI Open Chapter 1 Join Matrix Chat → Ubuntu Build MacOS Build codecov License REUSE status

What is Naja?

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

Architecture

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-if Cap'n Proto format provides a logical-view interchange path.
  • APIs and tools — najaeda exposes the engine through Python. Companion projects build on Naja directly or through that API: kepler-formal, naja-schematic, and naja-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 &amp; 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"

Loading

Get Started

The best entry point is the najaeda Python package:

pip install najaeda

Requires 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.

Tutorials

Six hands-on notebooks — open any of them in Colab with no local install needed:

# Topic Colab
1 Getting started — load Verilog, navigate hierarchy, visualize Open in Colab
2 Liberty primitives — load a synthesised design with standard cells Open in Colab
3 Editing a netlist — rename, disconnect, reconnect, delete Open in Colab
4 SystemVerilog elaboration — load and browse an elaborated SV design Open in Colab
5 ibex RISC-V core — explore a real-world SV core, collect stats Open in Colab
6 Fanout analysis — compute fanout for every net, trace drivers, export to pandas Open in Colab

naja_edit — Netlist CLI

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.py

Available optimizations (-a): all (DLE + constant propagation + primitives), dle.

Python script examples: src/apps/naja_edit/examples
Regression suite: naja-regress

Building from Source

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.

CMake

Dependencies

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 flex

macOS (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_8

Build, test, and install

git 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"

Bazel smoke build

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 git

macOS (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=auto

These 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.py

C++ API

Naja 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

Community

⭐ If you find Naja useful, starring the repo helps spread the word.

Acknowledgement

Supported by NLNet through the NGI0 Entrust Fund.

About

Netlist API (and more) for EDA flow development

Topics

Resources

Stars

163 stars

Watchers

8 watching

Forks

Releases

Used by

Contributors

Languages