Skip to content

Commit

Permalink
Experimenting with parsing from text, incremented version number (#164)
Browse files Browse the repository at this point in the history
  • Loading branch information
WorldofKerry authored Oct 11, 2023
1 parent 6137160 commit c5f72bf
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 12 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "python2verilog"
version = "0.2.7"
version = "0.2.8"
authors = [{ name = "Kerry Wang", email = "[email protected]" }]
description = "Converts a subset of python generator functions into synthesizable sequential SystemVerilog"
readme = "README.md"
Expand Down
17 changes: 9 additions & 8 deletions python2verilog/api/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from python2verilog.api.modes import Modes
from python2verilog.api.namespace import get_namespace
from python2verilog.backend.verilog.config import CodegenConfig, TestbenchConfig
from python2verilog.utils.typed import typed, typed_list
from python2verilog.utils.typed import guard, typed, typed_list


def py_to_codegen(
Expand Down Expand Up @@ -145,12 +145,12 @@ def get_file_and_line_num(node: ast.AST):
logging.info("Input param names %s", input_names)

initialized = False
input_types: list[type[Any]]
input_types: Optional[list[type[Any]]] = None
for output in test_cases:
if not initialized:
input_types = [type(val) for val in output]
initialized = True

assert guard(input_types, list)
for i, (expected_type, actual_value) in enumerate(zip(input_types, output)):
assert expected_type == type(
actual_value
Expand All @@ -163,7 +163,6 @@ def get_file_and_line_num(node: ast.AST):
lines = code.splitlines()
func_lines = lines[generator_ast.lineno - 1 : generator_ast.end_lineno]
func_str = "\n".join(func_lines)
# logging.debug(func_str)
exec(func_str, None, locals_)
try:
generator_func = locals_[function_name]
Expand Down Expand Up @@ -205,11 +204,13 @@ def get_file_and_line_num(node: ast.AST):
context.output_types = output_types
context.default_output_vars()

logging.info("Output param types %s", context.output_types)
logging.info("Output param names %s", context.output_vars)
logging.info("Output param types %s", context.output_types)
logging.info("Output param names %s", context.output_vars)

context.input_vars = [ir.Var(name) for name in input_names]
assert isinstance(input_types, list)
context.input_types = input_types
if input_types is not None:
assert isinstance(input_types, list)
context.input_types = input_types
context.test_cases = test_cases
context.py_ast = generator_ast
context.py_func = generator_func
Expand Down
1 change: 1 addition & 0 deletions python2verilog/frontend/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class GeneratorFunc:

def __init__(self, context: ir.Context) -> None:
self._context = copy.deepcopy(context)
print(self._context)

def create_root(self) -> tuple[ir.Node, ir.Context]:
"""
Expand Down
5 changes: 3 additions & 2 deletions python2verilog/ir/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def _repr(self):
"""
Avoids recursion on itself
"""
dic = self.__dict__
dic = copy.deepcopy(self.__dict__)
del dic["namespace"]
return dic

Expand Down Expand Up @@ -163,6 +163,7 @@ def output_mapper(arg: ast.Name) -> type[Any]:

assert check_list(self.output_types), self
assert check_list(self.output_vars), self
assert isinstance(self._output_vars, list)

assert isinstance(self.optimization_level, int), self
assert self.optimization_level >= 0, f"{self.optimization_level} {self.name}"
Expand Down Expand Up @@ -257,7 +258,7 @@ def output_vars(self):
"""
Output variables
"""
assert guard(self._output_vars, list)
assert guard(self._output_vars, list), f"Unknown output variables {self}"
return copy.deepcopy(self._output_vars)

@output_vars.setter
Expand Down
29 changes: 29 additions & 0 deletions tests/api/test_tempfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import tempfile
from importlib import util

raw = """
from python2verilog import verilogify
ns = {}
@verilogify(namespace=ns)
def fib() -> int:
a, b = 0, 1
while a < 30:
yield a
a, b = b, a + b
"""

# Create a temporary source code file
with tempfile.NamedTemporaryFile(suffix=".py") as tmp:
tmp.write(raw.encode())
tmp.flush()

# Now load that file as a module
spec = util.spec_from_file_location("tmp", tmp.name)
module = util.module_from_spec(spec)
spec.loader.exec_module(module)

# ...or, while the tmp file exists, you can query it externally
import inspect

print(inspect.getsource(module.fib))
print(module.ns)
15 changes: 15 additions & 0 deletions tests/api/test_text.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,23 @@
import subprocess
import unittest

from python2verilog.api.python import py_to_verilog


class TestConvert(unittest.TestCase):
def test_from_text(self):
code = """
def fib() -> int:
a, b = 0, 1
while a < 30:
yield a
a, b = b, a + b
"""
module, tb = py_to_verilog(
code, "fib", file_path="./from_text", extra_test_cases=[]
)
logging.debug(module)

def test_help(self):
CMD = "python3 -m python2verilog --help"
result = subprocess.run(
Expand Down
48 changes: 47 additions & 1 deletion tests/simulation/test_simulation.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,63 @@
import logging
import tempfile
import unittest
from importlib import util
from pathlib import Path

import pytest

from python2verilog.api import verilogify
from python2verilog.api.modes import Modes
from python2verilog.api.namespace import namespace_to_verilog, new_namespace
from python2verilog.api.namespace import (
get_namespace,
namespace_to_verilog,
new_namespace,
)
from python2verilog.api.verilogify import get_actual, get_actual_raw, get_expected
from python2verilog.simulation import iverilog


@pytest.mark.usefixtures("argparse")
class TestSimulation(unittest.TestCase):
def test_type_hint(self):
ns = {}

@verilogify(namespace=ns)
def func() -> int:
yield 123

module, testbench = namespace_to_verilog(ns)
logging.debug(module)

def test_type_hint_text(self):
raw = """
@verilogify
def func() -> int:
yield 123
"""
raw = "from python2verilog import verilogify\n" + raw

# Create a temporary source code file
with tempfile.NamedTemporaryFile(suffix=".py") as tmp:
tmp.write(raw.encode())
tmp.flush()

# Now load that file as a module
try:
spec = util.spec_from_file_location("tmp", tmp.name)
module = util.module_from_spec(spec)
spec.loader.exec_module(module)

# ...or, while the tmp file exists, you can query it externally
ns = get_namespace(tmp.name)
logging.debug(ns)
module, _ = namespace_to_verilog(ns)
logging.debug(module)

except Exception as e:
logging.error(e)
self.assertTrue(False)

def test_o0(self):
ns = {}

Expand Down

0 comments on commit c5f72bf

Please sign in to comment.