mirror of
https://github.com/YosysHQ/yosys
synced 2025-11-23 06:01:27 +00:00
pyosys: __getitem__ for supported classes
- functions that have a const `[]` operator method now support `__getitem__` in Python - fields of a pointer type now return a `reference_internal` instead of a `copy` because classes referenced to by pointers typically aren't copyable (e.g. RTLIL::Wire, RTLIL::Module, etc) - removed duplicate of test_script.py
This commit is contained in:
parent
9aa2dde7ef
commit
58e831486d
4 changed files with 36 additions and 24 deletions
|
|
@ -193,7 +193,7 @@ pyosys_headers = [
|
||||||
),
|
),
|
||||||
PyosysClass("SigChunk"),
|
PyosysClass("SigChunk"),
|
||||||
PyosysClass("SigBit", hash_expr="s"),
|
PyosysClass("SigBit", hash_expr="s"),
|
||||||
PyosysClass("SigSpec", hash_expr="s", denylist={"chunks"}),
|
PyosysClass("SigSpec", hash_expr="s", denylist=frozenset({"chunks"})),
|
||||||
PyosysClass(
|
PyosysClass(
|
||||||
"Cell",
|
"Cell",
|
||||||
ref_only=True,
|
ref_only=True,
|
||||||
|
|
@ -539,6 +539,8 @@ class PyosysWrapperGenerator(object):
|
||||||
python_name_override = "__ne__"
|
python_name_override = "__ne__"
|
||||||
elif function.operator == "<":
|
elif function.operator == "<":
|
||||||
python_name_override = "__lt__"
|
python_name_override = "__lt__"
|
||||||
|
elif function.operator == "[]" and function.const:
|
||||||
|
python_name_override = "__getitem__"
|
||||||
else:
|
else:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
@ -592,7 +594,10 @@ class PyosysWrapperGenerator(object):
|
||||||
# care
|
# care
|
||||||
return
|
return
|
||||||
|
|
||||||
has_containers = self.register_containers(field)
|
self.register_containers(field)
|
||||||
|
rvp = "py::return_value_policy::copy"
|
||||||
|
if isinstance(field.type, Pointer):
|
||||||
|
rvp = "py::return_value_policy::reference_internal"
|
||||||
|
|
||||||
definition_fn = f"def_{'readonly' if field.type.const else 'readwrite'}"
|
definition_fn = f"def_{'readonly' if field.type.const else 'readwrite'}"
|
||||||
if field.static:
|
if field.static:
|
||||||
|
|
@ -604,7 +609,7 @@ class PyosysWrapperGenerator(object):
|
||||||
f'"{field_python_basename}"',
|
f'"{field_python_basename}"',
|
||||||
f"&{metadata.name}::{field.name}",
|
f"&{metadata.name}::{field.name}",
|
||||||
]
|
]
|
||||||
def_args.append("py::return_value_policy::copy")
|
def_args.append(rvp)
|
||||||
print(
|
print(
|
||||||
f"\t\t\t.{definition_fn}({', '.join(def_args)})",
|
f"\t\t\t.{definition_fn}({', '.join(def_args)})",
|
||||||
file=self.f,
|
file=self.f,
|
||||||
|
|
|
||||||
|
|
@ -1,20 +0,0 @@
|
||||||
import os
|
|
||||||
from pyosys import libyosys as ys
|
|
||||||
|
|
||||||
__dir__ = os.path.dirname(os.path.abspath(__file__))
|
|
||||||
add_sub = os.path.join(__dir__, "..", "common", "add_sub.v")
|
|
||||||
|
|
||||||
base = ys.Design()
|
|
||||||
ys.run_pass(f"read_verilog {add_sub}", base)
|
|
||||||
ys.run_pass("hierarchy -top top", base)
|
|
||||||
ys.run_pass("proc", base)
|
|
||||||
ys.run_pass("equiv_opt -assert -map +/ecp5/cells_sim.v synth_ecp5", base)
|
|
||||||
|
|
||||||
postopt = ys.Design()
|
|
||||||
ys.run_pass("design -load postopt", postopt)
|
|
||||||
ys.run_pass("cd top", postopt)
|
|
||||||
ys.run_pass("select -assert-min 25 t:LUT4", postopt)
|
|
||||||
ys.run_pass("select -assert-max 26 t:LUT4", postopt)
|
|
||||||
ys.run_pass("select -assert-count 10 t:PFUMX", postopt)
|
|
||||||
ys.run_pass("select -assert-count 6 t:L6MUX21", postopt)
|
|
||||||
ys.run_pass("select -assert-none t:LUT4 t:PFUMX t:L6MUX21 %% t:* %D", postopt)
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from pyosys import libyosys as ys
|
from pyosys import libyosys as ys
|
||||||
|
|
||||||
|
|
||||||
__file_dir__ = Path(__file__).absolute().parent
|
__file_dir__ = Path(__file__).absolute().parent
|
||||||
add_sub = __file_dir__.parent / "arch" / "common" / "add_sub.v"
|
add_sub = __file_dir__.parent / "arch" / "common" / "add_sub.v"
|
||||||
|
|
||||||
28
tests/pyosys/test_sigspec_it.py
Normal file
28
tests/pyosys/test_sigspec_it.py
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
from pyosys import libyosys as ys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
__file_dir__ = Path(__file__).absolute().parent
|
||||||
|
|
||||||
|
def _dump_sigbit(bit):
|
||||||
|
if bit.is_wire():
|
||||||
|
if bit.wire.width == 1:
|
||||||
|
return bit.wire.name.str()
|
||||||
|
else:
|
||||||
|
return f"{bit.wire.name} [{bit.offset}]"
|
||||||
|
else:
|
||||||
|
if bit.data == ys.State.S1:
|
||||||
|
return 1
|
||||||
|
elif bit.data == ys.State.S0:
|
||||||
|
return 0
|
||||||
|
else:
|
||||||
|
assert "unknown constants not supported"
|
||||||
|
|
||||||
|
d = ys.Design()
|
||||||
|
|
||||||
|
ys.run_pass(f"read_verilog {__file_dir__ / 'spm.cut.v.gz'}", d)
|
||||||
|
ys.run_pass(f"hierarchy -top spm", d)
|
||||||
|
module = d.module(r"\spm")
|
||||||
|
for conn_from, conn_to in module.connections_:
|
||||||
|
for bit_from, bit_to in zip(conn_from, conn_to):
|
||||||
|
print(f"assign {_dump_sigbit(bit_from)} = {_dump_sigbit(bit_to)};")
|
||||||
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue