From 6d843763b88e958ab5961b38030efe9410a27b51 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Wed, 12 Oct 2022 15:50:15 -0700 Subject: [PATCH 01/15] WIP --- magma/frontend/pyverilog_importer.py | 45 ++++++++++++++++++++++++++++ magma/stubify.py | 2 +- 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 34452a462..77dd76e0c 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -123,6 +123,10 @@ def visit_ModuleDef(self, defn): class PyverilogImporter(VerilogImporter): """Implementation of VerilogImporter using pyverilog""" + def __init__(self, type_map): + super().__init__(type_map) + self._magma_defn_to_pyverilog_defn = {} + def _import_defn(self, defn, mode): ports = {} default_params = {} @@ -165,6 +169,43 @@ class _FromVerilog(Circuit): return _FromVerilog, default_params + def post(self): + name_to_module_map = {d.name: d for d in self._magma_defn_to_pyverilog_defn.keys()} + import magma as m + decls = m.declare_from_verilog_file( + "/Users/rajsekhar/private/research/tile-pe-power/power-tool" + "/freepdk-45nm-stdcells-cleaned.v" + ) + for decl in decls: + assert decl.name not in name_to_module_map + name_to_module_map[decl.name] = decl + + def _get_instances(pyverilog_defn): + for child in pyverilog_defn.children(): + if isinstance(child, pyverilog.vparser.parser.Instance): + yield child + elif isinstance(child, pyverilog.vparser.parser.InstanceList): + yield from child.instances + + from magma.stubify import stubify + for magma_defn, pyverilog_defn in self._magma_defn_to_pyverilog_defn.items(): + mod = False + for inst in _get_instances(pyverilog_defn): + try: + instance_module = name_to_module_map[inst.module] + except KeyError: + raise Exception("bad!") from None + continue + mod = True + with magma_defn.open(): + i = instance_module() + stubify(i.interface) + if mod: + magma_defn.verilogFile = "" + magma_defn.verilog_source = "" + magma_defn._is_definition = True + stubify(magma_defn) + def import_(self, src, mode): parser = pyverilog.vparser.parser.VerilogParser() ast = parser.parse(src) @@ -172,6 +213,8 @@ def import_(self, src, mode): visitor.visit(ast) for name, defn in visitor.defns.items(): circ, default_params = self._import_defn(defn, mode) + print ("!", circ.name) + self._magma_defn_to_pyverilog_defn[circ] = defn if mode is ImportMode.DEFINE: circ.verilogFile = _get_lines(src, defn.lineno, defn.end_lineno) circ.verilog_source = src @@ -181,3 +224,5 @@ def import_(self, src, mode): } circ.default_kwargs = default_params self.add_module(circ) + if mode is ImportMode.DEFINE: + self.post() diff --git a/magma/stubify.py b/magma/stubify.py index d2a3c3de5..4cfaa9cd2 100644 --- a/magma/stubify.py +++ b/magma/stubify.py @@ -113,7 +113,7 @@ def _( # that we *can't* do this in the class itself, since we need to call open() # to tie the outputs first (in stubify()). Afterwards, we can override the # method. - setattr(ckt, "open", classmethod(_stub_open)) + #setattr(ckt, "open", classmethod(_stub_open)) def circuit_stub( From fe914bacfb74eba82a97fdf74ffc514fff4a92b5 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 13 Oct 2022 08:30:45 -0700 Subject: [PATCH 02/15] Revert "WIP" This reverts commit 88a20099e86a9e6ec3ab7665f5ee4bf95e45c9a9. --- magma/frontend/pyverilog_importer.py | 45 ---------------------------- magma/stubify.py | 2 +- 2 files changed, 1 insertion(+), 46 deletions(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 77dd76e0c..34452a462 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -123,10 +123,6 @@ def visit_ModuleDef(self, defn): class PyverilogImporter(VerilogImporter): """Implementation of VerilogImporter using pyverilog""" - def __init__(self, type_map): - super().__init__(type_map) - self._magma_defn_to_pyverilog_defn = {} - def _import_defn(self, defn, mode): ports = {} default_params = {} @@ -169,43 +165,6 @@ class _FromVerilog(Circuit): return _FromVerilog, default_params - def post(self): - name_to_module_map = {d.name: d for d in self._magma_defn_to_pyverilog_defn.keys()} - import magma as m - decls = m.declare_from_verilog_file( - "/Users/rajsekhar/private/research/tile-pe-power/power-tool" - "/freepdk-45nm-stdcells-cleaned.v" - ) - for decl in decls: - assert decl.name not in name_to_module_map - name_to_module_map[decl.name] = decl - - def _get_instances(pyverilog_defn): - for child in pyverilog_defn.children(): - if isinstance(child, pyverilog.vparser.parser.Instance): - yield child - elif isinstance(child, pyverilog.vparser.parser.InstanceList): - yield from child.instances - - from magma.stubify import stubify - for magma_defn, pyverilog_defn in self._magma_defn_to_pyverilog_defn.items(): - mod = False - for inst in _get_instances(pyverilog_defn): - try: - instance_module = name_to_module_map[inst.module] - except KeyError: - raise Exception("bad!") from None - continue - mod = True - with magma_defn.open(): - i = instance_module() - stubify(i.interface) - if mod: - magma_defn.verilogFile = "" - magma_defn.verilog_source = "" - magma_defn._is_definition = True - stubify(magma_defn) - def import_(self, src, mode): parser = pyverilog.vparser.parser.VerilogParser() ast = parser.parse(src) @@ -213,8 +172,6 @@ def import_(self, src, mode): visitor.visit(ast) for name, defn in visitor.defns.items(): circ, default_params = self._import_defn(defn, mode) - print ("!", circ.name) - self._magma_defn_to_pyverilog_defn[circ] = defn if mode is ImportMode.DEFINE: circ.verilogFile = _get_lines(src, defn.lineno, defn.end_lineno) circ.verilog_source = src @@ -224,5 +181,3 @@ def import_(self, src, mode): } circ.default_kwargs = default_params self.add_module(circ) - if mode is ImportMode.DEFINE: - self.post() diff --git a/magma/stubify.py b/magma/stubify.py index 4cfaa9cd2..d2a3c3de5 100644 --- a/magma/stubify.py +++ b/magma/stubify.py @@ -113,7 +113,7 @@ def _( # that we *can't* do this in the class itself, since we need to call open() # to tie the outputs first (in stubify()). Afterwards, we can override the # method. - #setattr(ckt, "open", classmethod(_stub_open)) + setattr(ckt, "open", classmethod(_stub_open)) def circuit_stub( From ba410a2f20915d890a20db7699870607c6423707 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 13 Oct 2022 08:34:42 -0700 Subject: [PATCH 03/15] [FromVerilog] Store Pyverilog ast node for imported modules --- magma/frontend/pyverilog_importer.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 34452a462..3d433b14d 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -123,6 +123,10 @@ def visit_ModuleDef(self, defn): class PyverilogImporter(VerilogImporter): """Implementation of VerilogImporter using pyverilog""" + def __init__(self, type_map): + super().__init__(type_map) + self._magma_defn_to_pyverilog_defn = {} + def _import_defn(self, defn, mode): ports = {} default_params = {} @@ -172,6 +176,7 @@ def import_(self, src, mode): visitor.visit(ast) for name, defn in visitor.defns.items(): circ, default_params = self._import_defn(defn, mode) + self._magma_defn_to_pyverilog_defn[circ] = defn if mode is ImportMode.DEFINE: circ.verilogFile = _get_lines(src, defn.lineno, defn.end_lineno) circ.verilog_source = src From 64ba7a016059b8013631ffef480d697160cc9d65 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 13 Oct 2022 09:41:45 -0700 Subject: [PATCH 04/15] WIP -- instances --- magma/frontend/pyverilog_importer.py | 58 ++++++++++++++++++++++++++++ magma/stubify.py | 2 +- 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 3d433b14d..640b66889 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -1,4 +1,6 @@ from collections import OrderedDict +import io + import hwtypes import pyverilog.dataflow.visit import pyverilog.vparser.parser @@ -14,6 +16,7 @@ VerilogImportError) from .verilog_utils import int_const_str_to_int from magma.bitutils import clog2 +from magma.stubify import stubify class PyverilogImportError(VerilogImportError): @@ -186,3 +189,58 @@ def import_(self, src, mode): } circ.default_kwargs = default_params self.add_module(circ) + + +def _show(node, **kwargs): + buf = io.StringIO() + node.show(buf=buf, **kwargs) + return buf.getvalue() + + +def _update_unique(dct, mapping): + for k, v in mapping.items(): + assert k not in dct, (k) + dct[k] = v + + +def _get_instances(defn): + for child in defn.children(): + if isinstance(child, pyverilog.vparser.parser.Instance): + yield child + elif isinstance(child, pyverilog.vparser.parser.InstanceList): + yield from child.instances + + +class PyverilogNetlistImporter(PyverilogImporter): + def __init__(self, type_map, stdcells): + super().__init__(type_map) + self._stdcells = stdcells + + def import_(self, src, mode): + super().import_(src, mode) + if mode is not ImportMode.DEFINE: + return + modules = { + defn.name: defn + for defn in self._magma_defn_to_pyverilog_defn.keys() + } + try: + _update_unique(modules, self._stdcells) + except AssertionError as e: + raise MultipleModuleDeclarationError(e.args[0]) + + for magma_defn, pyverilog_defn in ( + self._magma_defn_to_pyverilog_defn.items() + ): + mod = False + for inst in _get_instances(pyverilog_defn): + instance_module = modules[inst.module] + mod = True + with magma_defn.open(): + i = instance_module() + stubify(i.interface) + if mod: + magma_defn.verilogFile = "" + magma_defn.verilog_source = "" + magma_defn._is_definition = True + stubify(magma_defn) diff --git a/magma/stubify.py b/magma/stubify.py index d2a3c3de5..3d227e143 100644 --- a/magma/stubify.py +++ b/magma/stubify.py @@ -113,7 +113,7 @@ def _( # that we *can't* do this in the class itself, since we need to call open() # to tie the outputs first (in stubify()). Afterwards, we can override the # method. - setattr(ckt, "open", classmethod(_stub_open)) + # setattr(ckt, "open", classmethod(_stub_open)) def circuit_stub( From aa32dbaeded83c524017d320675ed8d892a3de55 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 13 Oct 2022 09:52:35 -0700 Subject: [PATCH 05/15] WIP -- wires --- magma/frontend/pyverilog_importer.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 640b66889..6106fabc6 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -211,6 +211,16 @@ def _get_instances(defn): yield from child.instances +def _get_wires(defn): + for child in defn.children(): + if not isinstance(child, pyverilog.vparser.parser.Decl): + continue + for subchild in child.children(): + if not isinstance(subchild, pyverilog.vparser.parser.Wire): + continue + yield subchild + + class PyverilogNetlistImporter(PyverilogImporter): def __init__(self, type_map, stdcells): super().__init__(type_map) @@ -233,6 +243,21 @@ def import_(self, src, mode): self._magma_defn_to_pyverilog_defn.items() ): mod = False + for wire in _get_wires(pyverilog_defn): + assert ( + not wire.signed + and wire.dimensions is None + and wire.value is None + ) + T = Bit + if wire.width is not None: + width = _get_width(wire.width, {}) + T = Bits[width] + mod = True + with magma_defn.open(): + t = T(name=wire.name) + t.unused() + t.undriven() for inst in _get_instances(pyverilog_defn): instance_module = modules[inst.module] mod = True From ea348842a39f7d8e460a19ed67fddbadf9a6ecff Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 13 Oct 2022 16:58:02 -0700 Subject: [PATCH 06/15] WIP --- magma/frontend/pyverilog_importer.py | 56 ++++++++++++++++++++++++---- 1 file changed, 49 insertions(+), 7 deletions(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 6106fabc6..749fe1c74 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -221,6 +221,41 @@ def _get_wires(defn): yield subchild +def _wire_directed_to_undirected(directed, undirected): + if isinstance(directed, Bits[1]): + directed = directed[0] + if isinstance(undirected, Bits[1]): + undirected = undirected[0] + if directed.is_input(): + directed @= undirected + return + if directed.is_output(): + undirected @= directed + return + raise Exception() + + +def _process_port_connections(pyverilog_inst, magma_inst, wires, modules): + for child in pyverilog_inst.children(): + if not isinstance(child, pyverilog.vparser.parser.PortArg): + continue + magma_port = getattr(magma_inst, child.portname) + if isinstance(child.argname, pyverilog.vparser.parser.IntConst): + assert magma_port.is_input() + driver = _evaluate_node(child.argname, {}) + magma_port @= driver + elif isinstance(child.argname, pyverilog.vparser.parser.Identifier): + try: + value = wires[child.argname.name] + except KeyError: + value = None + if value is None: + continue + _wire_directed_to_undirected(magma_port, value) + else: + pass + + class PyverilogNetlistImporter(PyverilogImporter): def __init__(self, type_map, stdcells): super().__init__(type_map) @@ -243,6 +278,7 @@ def import_(self, src, mode): self._magma_defn_to_pyverilog_defn.items() ): mod = False + wires = {} for wire in _get_wires(pyverilog_defn): assert ( not wire.signed @@ -254,16 +290,22 @@ def import_(self, src, mode): width = _get_width(wire.width, {}) T = Bits[width] mod = True + assert wire.name not in wires + wires[wire.name] = T(name=wire.name) with magma_defn.open(): - t = T(name=wire.name) - t.unused() - t.undriven() - for inst in _get_instances(pyverilog_defn): - instance_module = modules[inst.module] + wires[wire.name].undriven() + for pyverilog_inst in _get_instances(pyverilog_defn): + instance_module = modules[pyverilog_inst.module] mod = True with magma_defn.open(): - i = instance_module() - stubify(i.interface) + magma_inst = instance_module() + _process_port_connections( + pyverilog_inst, + magma_inst, + wires, + modules, + ) + stubify(magma_inst.interface) if mod: magma_defn.verilogFile = "" magma_defn.verilog_source = "" From c9d27e9fa507f85aab41823877922362f964c087 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 13 Oct 2022 17:11:13 -0700 Subject: [PATCH 07/15] WIP --- magma/frontend/pyverilog_importer.py | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 749fe1c74..0ed34c5d9 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -227,15 +227,23 @@ def _wire_directed_to_undirected(directed, undirected): if isinstance(undirected, Bits[1]): undirected = undirected[0] if directed.is_input(): + if undirected.is_input(): + return False directed @= undirected - return + return True if directed.is_output(): undirected @= directed - return + return True raise Exception() -def _process_port_connections(pyverilog_inst, magma_inst, wires, modules): +def _process_port_connections( + pyverilog_inst, + magma_inst, + containing_magma_defn, + wires, +): + stash = [] for child in pyverilog_inst.children(): if not isinstance(child, pyverilog.vparser.parser.PortArg): continue @@ -248,12 +256,14 @@ def _process_port_connections(pyverilog_inst, magma_inst, wires, modules): try: value = wires[child.argname.name] except KeyError: - value = None - if value is None: - continue - _wire_directed_to_undirected(magma_port, value) + value = containing_magma_defn.interface.ports[child.argname.name] + wired = _wire_directed_to_undirected(magma_port, value) + if not wired: + stash.append((magma_port, value)) else: pass + if stash: + print ("@", stash) class PyverilogNetlistImporter(PyverilogImporter): @@ -302,8 +312,8 @@ def import_(self, src, mode): _process_port_connections( pyverilog_inst, magma_inst, + magma_defn, wires, - modules, ) stubify(magma_inst.interface) if mod: From 37d411904e3e48c6cfffc7d1a2123c7d399ec58b Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 13 Oct 2022 17:17:01 -0700 Subject: [PATCH 08/15] WIP --- magma/frontend/pyverilog_importer.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 0ed34c5d9..cfd7843fe 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -262,8 +262,7 @@ def _process_port_connections( stash.append((magma_port, value)) else: pass - if stash: - print ("@", stash) + return stash class PyverilogNetlistImporter(PyverilogImporter): @@ -304,18 +303,21 @@ def import_(self, src, mode): wires[wire.name] = T(name=wire.name) with magma_defn.open(): wires[wire.name].undriven() + stash = [] for pyverilog_inst in _get_instances(pyverilog_defn): instance_module = modules[pyverilog_inst.module] mod = True with magma_defn.open(): magma_inst = instance_module() - _process_port_connections( + stash += _process_port_connections( pyverilog_inst, magma_inst, magma_defn, wires, ) stubify(magma_inst.interface) + for inst_port, driver in stash: + inst_port @= driver.trace() if mod: magma_defn.verilogFile = "" magma_defn.verilog_source = "" From 5d0e3d8101c32c62c106255009b035c7f162df35 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 13 Oct 2022 17:27:30 -0700 Subject: [PATCH 09/15] WIP --- magma/frontend/pyverilog_importer.py | 35 +++++++++++++++------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index cfd7843fe..03777e28b 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -10,7 +10,7 @@ from ..circuit import Circuit from ..interface import IO from ..passes.tsort import tsort -from ..t import In, Out, InOut +from ..t import In, Out, InOut, Type from .verilog_importer import (ImportMode, MultipleModuleDeclarationError, MultiplePortDeclarationError, VerilogImporter, VerilogImportError) @@ -227,7 +227,7 @@ def _wire_directed_to_undirected(directed, undirected): if isinstance(undirected, Bits[1]): undirected = undirected[0] if directed.is_input(): - if undirected.is_input(): + if isinstance(undirected, Type) and undirected.is_input(): return False directed @= undirected return True @@ -237,6 +237,14 @@ def _wire_directed_to_undirected(directed, undirected): raise Exception() +def _evaluate_arg(node, values): + if isinstance(node, pyverilog.vparser.parser.IntConst): + return _evaluate_node(node, {}) + if isinstance(node, pyverilog.vparser.parser.Identifier): + return values[node.name] + return None + + def _process_port_connections( pyverilog_inst, magma_inst, @@ -244,24 +252,19 @@ def _process_port_connections( wires, ): stash = [] + magma_values = {} + magma_values.update(wires) + magma_values.update(containing_magma_defn.interface.ports) for child in pyverilog_inst.children(): if not isinstance(child, pyverilog.vparser.parser.PortArg): continue magma_port = getattr(magma_inst, child.portname) - if isinstance(child.argname, pyverilog.vparser.parser.IntConst): - assert magma_port.is_input() - driver = _evaluate_node(child.argname, {}) - magma_port @= driver - elif isinstance(child.argname, pyverilog.vparser.parser.Identifier): - try: - value = wires[child.argname.name] - except KeyError: - value = containing_magma_defn.interface.ports[child.argname.name] - wired = _wire_directed_to_undirected(magma_port, value) - if not wired: - stash.append((magma_port, value)) - else: - pass + magma_arg = _evaluate_arg(child.argname, magma_values) + if magma_arg is None: + continue + wired = _wire_directed_to_undirected(magma_port, magma_arg) + if not wired: + stash.append((magma_port, magma_arg)) return stash From cb3c419bffc0f5264474610e53e6a54028f2a8ca Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 13 Oct 2022 17:31:14 -0700 Subject: [PATCH 10/15] WIP --- magma/frontend/pyverilog_importer.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 03777e28b..9de994c68 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -242,6 +242,10 @@ def _evaluate_arg(node, values): return _evaluate_node(node, {}) if isinstance(node, pyverilog.vparser.parser.Identifier): return values[node.name] + if isinstance(node, pyverilog.vparser.parser.Pointer): + value = _evaluate_arg(node.var, values) + index = _evaluate_node(node.ptr, {}) + return value[index] return None From d9b8c59644ac773be34907f4420c523c2fec4d10 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Fri, 14 Oct 2022 00:46:45 -0700 Subject: [PATCH 11/15] WIP --- magma/frontend/pyverilog_importer.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 9de994c68..86f9c9591 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -246,6 +246,11 @@ def _evaluate_arg(node, values): value = _evaluate_arg(node.var, values) index = _evaluate_node(node.ptr, {}) return value[index] + if isinstance(node, pyverilog.vparser.parser.Partselect): + value = _evaluate_arg(node.var, values) + msb = _evaluate_node(node.msb, {}) + lsb = _evaluate_node(node.lsb, {}) + return value[lsb : msb + 1] return None From 9e59dcdb163b9a2e204088f942402beb8230603a Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Fri, 14 Oct 2022 00:55:18 -0700 Subject: [PATCH 12/15] WIP --- magma/frontend/pyverilog_importer.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 86f9c9591..144e671a5 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -16,6 +16,7 @@ VerilogImportError) from .verilog_utils import int_const_str_to_int from magma.bitutils import clog2 +from magma.conversions import concat from magma.stubify import stubify @@ -251,7 +252,9 @@ def _evaluate_arg(node, values): msb = _evaluate_node(node.msb, {}) lsb = _evaluate_node(node.lsb, {}) return value[lsb : msb + 1] - return None + if isinstance(node, pyverilog.vparser.parser.Concat): + return concat(*(_evaluate_arg(n, values) for n in reversed(node.list))) + raise Exception() def _process_port_connections( @@ -269,8 +272,6 @@ def _process_port_connections( continue magma_port = getattr(magma_inst, child.portname) magma_arg = _evaluate_arg(child.argname, magma_values) - if magma_arg is None: - continue wired = _wire_directed_to_undirected(magma_port, magma_arg) if not wired: stash.append((magma_port, magma_arg)) @@ -313,8 +314,6 @@ def import_(self, src, mode): mod = True assert wire.name not in wires wires[wire.name] = T(name=wire.name) - with magma_defn.open(): - wires[wire.name].undriven() stash = [] for pyverilog_inst in _get_instances(pyverilog_defn): instance_module = modules[pyverilog_inst.module] From c99f24430bfd44cdb9677a5781c8a617ba014e59 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Wed, 16 Nov 2022 13:34:15 -0800 Subject: [PATCH 13/15] Use instance name --- magma/frontend/pyverilog_importer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 144e671a5..49c70d5d7 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -319,7 +319,7 @@ def import_(self, src, mode): instance_module = modules[pyverilog_inst.module] mod = True with magma_defn.open(): - magma_inst = instance_module() + magma_inst = instance_module(name=pyverilog_inst.name) stash += _process_port_connections( pyverilog_inst, magma_inst, From 6fe29f1b9632df568f1908084eaf5baad40ed384 Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 17 Nov 2022 10:04:24 -0800 Subject: [PATCH 14/15] Add inout --- magma/frontend/pyverilog_importer.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 49c70d5d7..677c420fa 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -18,6 +18,7 @@ from magma.bitutils import clog2 from magma.conversions import concat from magma.stubify import stubify +from magma.wire import wire class PyverilogImportError(VerilogImportError): @@ -235,6 +236,9 @@ def _wire_directed_to_undirected(directed, undirected): if directed.is_output(): undirected @= directed return True + if directed.is_inout(): + wire(directed, undirected) + return True raise Exception() From 48073d45ef4e3bb60d06f8593b3cb2cf42d0374c Mon Sep 17 00:00:00 2001 From: rsetaluri Date: Thu, 17 Nov 2022 10:16:25 -0800 Subject: [PATCH 15/15] WIP -- support offset in lsb --- magma/frontend/pyverilog_importer.py | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/magma/frontend/pyverilog_importer.py b/magma/frontend/pyverilog_importer.py index 677c420fa..ba1a94f09 100644 --- a/magma/frontend/pyverilog_importer.py +++ b/magma/frontend/pyverilog_importer.py @@ -60,10 +60,13 @@ def _evaluate_node(node, params): raise PyverilogImportError(f"Unsupported expression: {type(node)}") -def _get_width(width, param_map): +def _get_width(width, param_map, metadata=None): """Evaluates width.msb, width.lsb and returns their difference""" msb = _evaluate_node(width.msb, param_map) lsb = _evaluate_node(width.lsb, param_map) + if metadata is not None: + metadata["msb"] = msb + metadata["lsb"] = lsb return msb - lsb + 1 @@ -242,20 +245,30 @@ def _wire_directed_to_undirected(directed, undirected): raise Exception() -def _evaluate_arg(node, values): +def _get_offset(name, metadata): + try: + msb, lsb = metadata[name].values() + except KeyError: + return 0 + return lsb + + +def _evaluate_arg(node, values, metadata={}): if isinstance(node, pyverilog.vparser.parser.IntConst): return _evaluate_node(node, {}) if isinstance(node, pyverilog.vparser.parser.Identifier): return values[node.name] if isinstance(node, pyverilog.vparser.parser.Pointer): + offset = _get_offset(node.var.name, metadata) value = _evaluate_arg(node.var, values) index = _evaluate_node(node.ptr, {}) - return value[index] + return value[index - offset] if isinstance(node, pyverilog.vparser.parser.Partselect): + offset = _get_offset(node.var.name, metadata) value = _evaluate_arg(node.var, values) msb = _evaluate_node(node.msb, {}) lsb = _evaluate_node(node.lsb, {}) - return value[lsb : msb + 1] + return value[lsb - offset : msb + 1 - offset] if isinstance(node, pyverilog.vparser.parser.Concat): return concat(*(_evaluate_arg(n, values) for n in reversed(node.list))) raise Exception() @@ -266,6 +279,7 @@ def _process_port_connections( magma_inst, containing_magma_defn, wires, + metadata, ): stash = [] magma_values = {} @@ -275,7 +289,7 @@ def _process_port_connections( if not isinstance(child, pyverilog.vparser.parser.PortArg): continue magma_port = getattr(magma_inst, child.portname) - magma_arg = _evaluate_arg(child.argname, magma_values) + magma_arg = _evaluate_arg(child.argname, magma_values, metadata) wired = _wire_directed_to_undirected(magma_port, magma_arg) if not wired: stash.append((magma_port, magma_arg)) @@ -303,6 +317,7 @@ def import_(self, src, mode): for magma_defn, pyverilog_defn in ( self._magma_defn_to_pyverilog_defn.items() ): + metadata = {} mod = False wires = {} for wire in _get_wires(pyverilog_defn): @@ -313,7 +328,7 @@ def import_(self, src, mode): ) T = Bit if wire.width is not None: - width = _get_width(wire.width, {}) + width = _get_width(wire.width, {}, metadata.setdefault(wire.name, {})) T = Bits[width] mod = True assert wire.name not in wires @@ -329,6 +344,7 @@ def import_(self, src, mode): magma_inst, magma_defn, wires, + metadata, ) stubify(magma_inst.interface) for inst_port, driver in stash: