Skip to main content

Converts a subset of python generator functions into synthesizable sequential SystemVerilog

Project description

Python Package Documentation Status PyPI PyPI - Downloads

Python 2 Verilog

Converts a subset of python generator functions into synthesizable sequential SystemVerilog.

A use case is for drawing shapes on grids (for VGA output), where the user may prototype the algorithm in python and then convert it to verilog for use in an FPGA.

A testbench can also be generated and asserted against the Python outputs.

Supports Python Generator functions as well as the following block types:

  • if
  • while

Warning: Variables are treated as global and therefore no variable shadowing.

Sample Usage

pip install python2verilog

Basic Usage

Create a python file containing a generator function with output type hints, named <name>.py.

A sample can be found here

python3 -m python2verilog.convert <name>.py. Use --help for additional options, including outputting a testbench.

Testing

Requirements

Warning: may be outdated, refer to github workflow for most update-to-date information for Ubuntu.

Verilog simulation: sudo apt-get install iverilog expected (uses the unbuffer app in expected). The online simulator EDA Playground can be used as a subsitute, given that you paste the output into the "actual file" specified in the config.ini of the test.

Python Libraries: python3 -m pip install -r tests/requirements.txt

Creating New Test

To create a new test case and set up configs, run python3 tests/integration/new_test_case.py <test-name>.

Running Tests

To run tests, use python3 -m pytest --verbose to generate the module, testbench, visualizations, dumps, and expected/actual outputs. Those files will be stored in tests/integration/data/integration/<test-name>/.

Tested Generations

Outputs of tests in repo can be found as a github workflow artifact

For Developers

Based on my experimentation with a C to Verilog converter.

Architecture is based on LLVM.

To setup pre-commit, run pre-commit install.

Epics

  • Support arrays
  • Mimic combinational logic with "regular" Python functions
  • Division approximations

Docs

  • cd to docs/
  • sphinx-apidoc -o . ../python2verilog/
  • make html

Random Planning, Design, and Notes

What needs to be duplicated in testbenches?

declare I/O and other signals declare DUT start clock

loop for each test case

  • start signal
  • while wait for done signal
    • clock
    • set start zero
    • display output endloop

Potential API

import python2verilog as p2v
import ast

func = ast.parse(code).body[0]

ir = p2v.from_python_get_ir(func.body)

# Optimization passes
ir = p2v.optimizations.replace_single_item_cases(ir)
ir = p2v.optimizations.remove_nesting(ir)
ir = p2v.optimizations.combine_statements(ir)

verilog = p2v.Verilog()
verilog.from_python_do_setup(ir.get_context()) # module I/O is dependent on Python
verilog.from_ir_fill_body(ir.get_root()) # fills the body

# whether has valid or done signal,
# whether initialization is always happening or only on start,
# verilog sim name
verilog.config(has_valid=True, has_done=True, lazy_start=True, verilog_sim="iverilog")

with open(f"{verilog.get_module_name()}.sv", mode="w") as module:
  module.write(verilog.get_module())
with open(f"{verilog.get_module_name()}_tb.sv", mode="w") as tb:
  tb.write(verilog.get_testbench())

print(verilog.get_verilog_run_cmd())
assert verilog.test_outputs() # checks if verilog and python output same

Rectangle Filled

def draw_rectangle(s_x, s_y, height, width) -> tuple[int, int]:
    for i0 in range(0, width):
        for i1 in range(0, height):
            yield (s_x + i1, s_y + i0)
case (STATE)
  0: begin
    if (i0 < width) begin
      STATE <= STATE_1;
    end else begin
      case (STATE_INNER)
        0: begin
          if (i1 < height) begin
            STATE_INNER <= STATE_INNER + 1;
          end else begin
            case (STATE_INNER_INNER)
              0: begin
                out0 <= s_x + i1;
                out1 <= s_y + i0;
                i1 <= i1 + 1;

                STATE_INNER_INNER <= STATE_INNER_INNER + 1;
                STATE_INNER_INNER <= 0; // flag to either wrap around or remain
              end
          end
          STATE_INNER <= 0;
        end
      endcase
    end
  end
  STATE_1: begin
    done <= 1;
  end
endcase

Converting a While Loop

i = 0
while <condition>:
    <statement 1>
    <statement 2>
    ...
case (STATE)
  0: begin
    // For loop start
    if (condition) begin
      STATE <= STATE + 1;
    end else begin
      case (STATE_INNER)
        0: begin
          // statement 1
        end
        1: begin
          // statement 2
        end
        // ...
        10: begin
          STATE_INNER <= 0;
        end
      endcase
    end
    // For loop end
  end
  // ...
endcase

If Statement Analysis

// IF START
case (_STATE_IF)
  0: begin
    if (condition) _STATE_IF <= 1;
    else _STATE_IF <= 2;
  end
  1: begin
    // THEN BODY START
    case ()
    // ...
      _STATE_IF <= 0;
    // THEN BODY END
  end
  2: begin
    // ELSE BODY START
    // ...
     __STATE_IF <= 0;
    // ELSE BODY END
  end
endcase
// IF END

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

python2verilog-0.0.4.tar.gz (24.7 kB view details)

Uploaded Source

Built Distribution

python2verilog-0.0.4-py3-none-any.whl (28.9 kB view details)

Uploaded Python 3

File details

Details for the file python2verilog-0.0.4.tar.gz.

File metadata

  • Download URL: python2verilog-0.0.4.tar.gz
  • Upload date:
  • Size: 24.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.9.17

File hashes

Hashes for python2verilog-0.0.4.tar.gz
Algorithm Hash digest
SHA256 678ff6052520c5d69f9708ae48a3264413b3af5e8d6f2678ecb164c7e383bb13
MD5 2b000d641b1080e102212a9f573df9e3
BLAKE2b-256 de0ce9d4b9c8bb061d41ab737ea4901c5061cd6850daa01fbe5a0f447d2c2bc3

See more details on using hashes here.

File details

Details for the file python2verilog-0.0.4-py3-none-any.whl.

File metadata

File hashes

Hashes for python2verilog-0.0.4-py3-none-any.whl
Algorithm Hash digest
SHA256 3824fe05658fb24b994d81a0d3f94131f287547d4b9e63b6e795e5ece2e1d21a
MD5 83a967a5f525cf8b3d1991ba7c78c1fe
BLAKE2b-256 9ed579f04597bf73943e93ce691057e3fad67014778f3b67023f2201c3b47809

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page