Skip to content

Repository files navigation

Build and test Documentation codecov

Slang Netlist

Slang Netlist is built on top of slang for analysing the source-level static connectivity of a SystemVerilog design. It uses slang's AST and data-flow analyses to construct a dependency graph of operations and provides facilities for interacting with this data structure.

Slang Netlist is a C++ library and provides a command-line tool for interactive use, and a Python module for straightforward integration into scripts. Possible applications include connectivity checks, CDC checks and timing path estimation.

Features

  • Bit-level resolution of data dependencies across continuous and procedural assignments.
  • Procedural flow analysis in always blocks, including evaluation of constant-valued conditions, unrolling of static loops, and tracking of non-blocking assignments.
  • Path finding and combinational loop detection.
  • Driver, port, and register reporting.
  • Multithreaded netlist construction for large designs.
  • A command-line tool (slang-netlist) for interactive use, plus a companion tool (slang-report) that surfaces the underlying AST information — port declarations, typed variables and nets, drivers, and the elaborated AST as JSON — with shared glob-aware --scope and --name filters.
  • Python bindings for scripting.

Example

Here's how to trace a path in a ripple-carry adder using the command-line tool:

module rca
  #(parameter WIDTH = 8)
  (input  logic               i_clk,
   input  logic               i_rst,
   input  logic [WIDTH-1:0]   i_op0,
   input  logic [WIDTH-1:0]   i_op1,
   output logic [WIDTH-1:0]   o_sum,
   output logic               o_co);

  logic [WIDTH-1:0] carry;
  logic [WIDTH-1:0] sum;

  assign carry[0] = 1'b0;
  assign {o_co, o_sum} = {co[WIDTH-1], sum};

  for (genvar i = 0; i < WIDTH - 1; i++) begin
    assign {carry[i+1], sum[i]} = i_op0[i] + i_op1[i] + carry[i];
  end
endmodule

Specifying start and end points for a path, slang-netlist searches for paths between these points and returns information about a path, if it finds one.

slang-netlist adder.sv --from rca.i_op0 --to rca.o_sum

Example output:

tests/driver/rca.sv:6:31: note: input port i_op1
   input  logic [p_width-1:0] i_op1,
                              ^
tests/driver/rca.sv:6:31: note: value rca.i_op1[0]
   input  logic [p_width-1:0] i_op1,
                              ^
tests/driver/rca.sv:19:12: note: assignment
    assign {carry[i+1], sum[i]} = i_op0[i] + i_op1[i] + carry[i];
           ^
tests/driver/rca.sv:10:23: note: value rca.carry[1]
  logic [p_width-1:0] carry;
                      ^
...
tests/driver/rca.sv:28:7: note: assignment
      co_q  <= carry[p_width-1];
      ^
tests/driver/rca.sv:13:23: note: value rca.co_q[0]
  logic               co_q;
                      ^
tests/driver/rca.sv:13:23: note: value rca.co_q[0]
  logic               co_q;
                      ^
tests/driver/rca.sv:16:10: note: assignment
  assign {o_co, o_sum} = {co_q, sum_q};
         ^
tests/driver/rca.sv:7:31: note: value rca.o_sum[7:0]
   output logic [p_width-1:0] o_sum,
                              ^
tests/driver/rca.sv:7:31: note: output port o_sum

Python bindings

The same kind of analysis can be performed using the Python bindings. The following example builds a netlist for a small ALU and checks connectivity between ports (see examples/connectivity_check.py):

import pyslang
import pyslang_netlist

# Compile the design.
tree = pyslang.syntax.SyntaxTree.fromText(r"""
  module alu(
    input  logic [7:0] a, b,
    input  logic       sel,
    output logic [7:0] result
  );
    assign result = sel ? (a + b) : (a - b);
  endmodule
""")
comp = pyslang.ast.Compilation()
comp.addSyntaxTree(tree)
comp.freeze()

# Run analysis and build the netlist.
am = pyslang.analysis.AnalysisManager()
am.analyze(comp)
graph = pyslang_netlist.NetlistGraph()
graph.build(comp, am)

# Check connectivity between two ports.
finder = pyslang_netlist.PathFinder()
path = finder.find(graph.lookup("alu.a"), graph.lookup("alu.result"))
assert not path.empty()

Installation

Currently there are no pre-built binaries, so you will need to build from source by cloning this repository or downloading a release.

Building from source

Prerequisites:

  • CMake >= 3.20
  • Python 3
  • C++20 compiler
git clone https://github.com/jameshanlon/slang-netlist.git
cd slang-netlist
cmake -B build \
    -DCMAKE_BUILD_TYPE=Release \
    -DCMAKE_INSTALL_PREFIX=$PWD/install \
    -DENABLE_PY_BINDINGS=ON
cmake --build build -j --target install
ctest --test-dir build

When using the Python bindings, it is recommended to use the pyslang shared object file that is produced and installed as part of the build. Different versions of the upstream slang Python bindings may not work.

Related Projects

  • Slang 'SystemVerilog compiler and language services' is the main library this project depends upon to provide access to an elaborated AST with facilities for code evaluation and data flow analysis.

  • Netlist Paths is a previous iteration of this project, but it instead used Verilator to provide access an elaborated AST. This approach had limitations in the way variable selections were represented, making it possible only to trace dependencies between named variables.

Contributing

Contributions are welcome, check the contributor guidelines.

License

Slang Netlist is licensed under the MIT license. See LICENSE for details.

About

A tool for analysing the source-level static connectivity of a SystemVerilog design

Resources

Contributing

Stars

26 stars

Watchers

5 watching

Forks

Releases

Packages

Contributors

Languages