Skip to content

Commit

Permalink
Readme restructured (#114)
Browse files Browse the repository at this point in the history
* Rework README

* Rework new Python scripts page

* typo

* Restructuring README, regress and naja_edit examples

* start moving regress to naja_edit examples

* update examples

* update examples

* reuse cleaning

* Improve README and naja_edit examples

* more cleaning
  • Loading branch information
xtofalex authored Oct 17, 2024
1 parent 0d80b77 commit b4b9333
Show file tree
Hide file tree
Showing 32 changed files with 244 additions and 160 deletions.
30 changes: 13 additions & 17 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,22 @@
*.DS_Store
build
install
venv
.vscode
__pycache__
regress/test_args/*.log
regress/adder/*.v
regress/vexriscv/*.v
regress/arm_core/*.v
regress/arm_core/*.log
regress/arm_core/*.gold
regress/arm_core/*.error
regress/*/abc.history
src/apps/naja_edit/examples/**/*.log
src/apps/naja_edit/examples/**/*.png
src/apps/naja_edit/examples/adder/*.v
src/apps/naja_edit/examples/vexriscv/*.v
src/apps/naja_edit/examples/arm_core/*.v
src/apps/naja_edit/examples/arm_core/*_snl
src/apps/naja_edit/examples/arm_core/*.gold
src/apps/naja_edit/examples/arm_core/*.error
src/apps/naja_edit/examples/arm_core/*.list
src/apps/naja_edit/examples/*/abc.history
src/apps/naja_edit/examples/abc.history
src/apps/naja_edit/examples/addaccu/addaccu_*.v
src/apps/naja_edit/examples/addaccu/*.log
src/apps/naja_edit/examples/addaccu/*.txt
src/apps/naja_edit/examples/addaccu/*_snl
regress/arm_core/comp/*
regress/arm_core/nodes.list
regress/arm_core/edges.list
regress/arm_core/arm_core_snl/*
regress/jpeg/*.log
regress/jpeg/jpeg_encoder_snl/*
regress/black_parrot/*.log
regress/black_parrot/black_parrot_snl/*
src/apps/naja_edit/examples/test_args/top_out.v
src/apps/naja_edit/examples/adder/verilator.done
2 changes: 1 addition & 1 deletion .reuse/dep5
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Files: .github/workflows/* .gitmodules
Copyright: 2022 The Naja Authors.
License: Apache-2.0

Files: README.md AUTHORS docs/*
Files: README.md README_pages/* AUTHORS docs/*
Copyright: 2022 The Naja Authors.
License: Apache-2.0

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile.regress
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ RUN rm -rf /naja-install
WORKDIR /naja/build
RUN cmake .. -DCMAKE_INSTALL_PREFIX=/naja-install && make -j$(nproc) && make install

WORKDIR /naja/regress
WORKDIR /naja/src/apps/naja_edit/examples
ENV SET_PYTHONPATH=/naja-install/lib/python
ENV LD_LIBRARY_PATH=/naja-install/lib
ENV NAJA_EDIT=/naja-install/bin/naja_edit
Expand Down
84 changes: 6 additions & 78 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ Naja is an Electronic Design Automation (EDA) project that provides open source

Naja best starting point is: [naja-edit](#naja_edit).



### Acknowledgement

[<img src="https://nlnet.nl/logo/banner.png" width=100>](https://nlnet.nl/project/Naja)
Expand All @@ -29,6 +27,8 @@ This project is supported and funded by NLNet through the [NGI0 Entrust](https:/
`naja_edit`, located in the `$NAJA_INSTALL/bin` directory, is a tool designed for
optimizing, editing and translating netlists.

:tv: We presented naja_edit’s latest features and results at [ORConf 2024](https://fossi-foundation.org/orconf/2024). You can watch the full presentation [here](https://www.youtube.com/watch?v=JpwZGCuWekU).

### Workflow Overview

The workflow for `naja_edit` is outlined in the schema below. It's important to note that the only mandatory step in the process is the initial loading of the input netlist.
Expand Down Expand Up @@ -71,85 +71,13 @@ naja_edit -f snl -t snl -i input.snl -o output.snl -a dle \
-e pre_script.py -z post_edit.py
```

`naja_edit` editing script examples are available [here](https://github.com/najaeda/naja/blob/main/src/apps/edit/examples).
This [page](README_pages/naja-edit-python-examples.md) provides a collection of example Python scripts for using the naja_edit API.

`naja_edit` editing script examples are also available [here](https://github.com/najaeda/naja/blob/main/src/apps/najae_edit/examples).

The [Naja Regress](https://github.com/najaeda/naja-regress) repository features a collection of examples
showcasing extensive use of `naja_edit`.

### Python API Examples

To use the Python API in `naja_edit`, start by creating a Python script containing an `edit` function.

```python
from naja import snl

def edit():
universe = snl.SNLUniverse.get()
top = universe.getTopDesign()

# Do something with 'top'
```

#### Print All Design Content

The following script recursively browses the design and prints instances, terminals, nets, and their connectivity.

```python
from naja import snl

def print_instance_tree(design):
for ins in design.getInstances():
print(f"Instance: {ins.getName()}")
model = ins.getModel()
for term in design.getTerms():
print(f" Terminal: {term}")
for net in design.getNets():
print(f" Net: {net}")
for bit in net.getBits():
for component in bit.getComponents():
print(f" Component: {component}")
print_instance_tree(model)

def edit():
universe = snl.SNLUniverse.get()
top = universe.getTopDesign()

print_instance_tree(top)
```

#### Remove Interface Buffers from an FPGA Design

The following script removes interface buffers `'IBUF'`, `'OBUF'`, and `'BUFG'` from a design synthesized for an FPGA.

```python
from naja import snl

def delete_io_bufs(design):
for ins in design.getInstances():
model = ins.getModel()
if model.isPrimitive():
model_name = model.getName()
if model_name in ['IBUF', 'BUFG']:
input_net = ins.getInstTerm(model.getScalarTerm('I')).getNet()
output_net = ins.getInstTerm(model.getScalarTerm('O')).getNet()
for component in output_net.getComponents():
component.setNet(input_net)
output_net.destroy()
ins.destroy()
elif model_name == 'OBUF':
input_net = ins.getInstTerm(model.getScalarTerm('I')).getNet()
output_net = ins.getInstTerm(model.getScalarTerm('O')).getNet()
for component in input_net.getComponents():
component.setNet(output_net)
input_net.destroy()
ins.destroy()

def edit():
universe = snl.SNLUniverse.get()
top = universe.getTopDesign()

delete_io_bufs(top)
```

<div align="right">[ <a href="#Introduction">↑ Back to top ↑</a> ]</div>

Expand Down Expand Up @@ -314,7 +242,7 @@ capnp decode --packed snl_implementation.capnp DBImplementation < snl/db_impleme

##### Verilog

For Verilog parsing, Naja relies on naja-verilog submodule (https://github.com/najaeda/naja-verilog).
For Verilog parsing, Naja relies on naja-verilog [submodule](https://github.com/najaeda/naja-verilog).
Leaf primitives are loaded through the Python primitive loader: [SNLPrimitivesLoader](https://github.com/najaeda/naja/blob/main/src/snl/python/primitives/SNLPrimitivesLoader.h).
An application snippet can be found [here](https://github.com/najaeda/naja/blob/main/src/snl/snippets/app/src/SNLVRLSnippet.cpp) and examples of
primitive libraries described using the Python interface can be found in the
Expand Down
Binary file added README_pages/images/design_stats.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
122 changes: 122 additions & 0 deletions README_pages/naja-edit-python-examples.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
# Naja Python API Examples

Naja Python API allows users to:

- browse the netlist data, collect informations, ...
- Apply ECO type transformations.

To use the Python API in `naja_edit`, start by creating a Python script containing an `edit` function.

```python
from naja import snl

def edit():
universe = snl.SNLUniverse.get()
top = universe.getTopDesign()

# Do something with 'top'
```

## Print All Design Content

The following script recursively browses the design and prints instances, terminals, nets, and their connectivity.

```python
from naja import snl

def print_instance_tree(design):
for ins in design.getInstances():
print(f"Instance: {ins.getName()}")
model = ins.getModel()
for term in design.getTerms():
print(f" Terminal: {term}")
for net in design.getNets():
print(f" Net: {net}")
for bit in net.getBits():
for component in bit.getComponents():
print(f" Component: {component}")
print_instance_tree(model)

def edit():
universe = snl.SNLUniverse.get()
top = universe.getTopDesign()

print_instance_tree(top)
```

## Remove Interface Buffers from an FPGA Design

The following script removes interface buffers `'IBUF'`, `'OBUF'`, and `'BUFG'` from a design synthesized for an FPGA.

```python
from naja import snl

def delete_io_bufs(design):
for ins in design.getInstances():
model = ins.getModel()
if model.isPrimitive():
model_name = model.getName()
if model_name in ['IBUF', 'BUFG']:
input_net = ins.getInstTerm(model.getScalarTerm('I')).getNet()
output_net = ins.getInstTerm(model.getScalarTerm('O')).getNet()
for component in output_net.getComponents():
component.setNet(input_net)
output_net.destroy()
ins.destroy()
elif model_name == 'OBUF':
input_net = ins.getInstTerm(model.getScalarTerm('I')).getNet()
output_net = ins.getInstTerm(model.getScalarTerm('O')).getNet()
for component in input_net.getComponents():
component.setNet(output_net)
input_net.destroy()
ins.destroy()

def edit():
universe = snl.SNLUniverse.get()
top = universe.getTopDesign()

delete_io_bufs(top)
```

## Browse all modules and display them based on their number of instances terms and nets

```python
from naja import snl
import pandas as pd
import matplotlib.pyplot as plt

def plot_design_stats(library):
data_list = []
for design in library.getDesigns():
nb_terms = sum(1 for _ in design.getBitTerms())
nb_nets = sum(1 for _ in design.getBitNets())
nb_instances = sum(1 for _ in design.getInstances())
data_list.append({
'design': design.getName(),
'nb_terms': nb_terms,
'nb_nets': nb_nets,
'nb_instances': nb_instances
})
pandas_data = pd.DataFrame(data_list).set_index('design')
plot = pandas_data.plot.bar(y=['nb_terms', 'nb_nets', 'nb_instances'], stacked=True)

# Set title and labels
plot.set_title('Design Statistics', fontsize=16, fontweight='bold')
plot.set_xlabel('Design Name', fontsize=12)
plot.set_ylabel('Count', fontsize=12)

plot_figure = plot.get_figure()
plot_figure.tight_layout()
plot_figure.savefig('design_stats.png')


def edit():
universe = snl.SNLUniverse.get()
topDesign = universe.getTopDesign()
topLibrary = topDesign.getLibrary() #top library contains top design

plot_design_stats(topLibrary)
```

This script generates a plot of design statistics, as illustrated in the image below:
![Design Stats](./images/design_stats.png)
8 changes: 0 additions & 8 deletions regress/Makefile.inc

This file was deleted.

46 changes: 0 additions & 46 deletions regress/arm_core/src/add_error.py

This file was deleted.

File renamed without changes.
8 changes: 8 additions & 0 deletions src/apps/naja_edit/examples/Makefile.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
YOSYS ?= yosys
EQY ?= eqy
VERILATOR ?= verilator
NAJA_EDIT ?= ../../../../../install/bin/naja_edit
PRIMITIVES ?= ../../../../../primitives/xilinx.py
ASAP7_PRIMITIVES ?= $(realpath ../../../primitives/asap7.py)
NANGATE45_PRIMITIVES ?= $(realpath ../../../primitives/nangate45.py)
SET_PYTHONPATH ?= ../../../../../install/lib/python
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
include ../Makefile.inc

all: adder_snl.v primitives.v verilator
all: adder_snl.v primitives.v verilator.done

verilator: adder_snl.v primitives.v
verilator.done: adder_snl.v primitives.v
${VERILATOR} --top-module adder --lint-only primitives.v adder_snl.v
touch verilator.done

adder_netlist.v: src/adder.v
${YOSYS} src/synth.ys
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loading

0 comments on commit b4b9333

Please sign in to comment.