parent
9d2cbbabb8
commit
fa0fa056ba
|
@ -38,8 +38,8 @@ Compatibility summary
|
||||||
<br>Note: `transform_*` methods not considered part of public API.
|
<br>Note: `transform_*` methods not considered part of public API.
|
||||||
- (⊙) `ModuleTransformer` **brk**
|
- (⊙) `ModuleTransformer` **brk**
|
||||||
- (⊙) `ControlInserter` **brk**
|
- (⊙) `ControlInserter` **brk**
|
||||||
- (-) `CEInserter` **obs**
|
- (+) `CEInserter` → `EnableInserter`
|
||||||
- (-) `ResetInserter` **obs**
|
- (+) `ResetInserter` id
|
||||||
- (+) `ClockDomainsRenamer` → `DomainRenamer`, `cd_remapping=`→`domain_map=`
|
- (+) `ClockDomainsRenamer` → `DomainRenamer`, `cd_remapping=`→`domain_map=`
|
||||||
- (⊙) `edif` **brk**
|
- (⊙) `edif` **brk**
|
||||||
- (+) `module` **obs** → `.hdl.dsl`
|
- (+) `module` **obs** → `.hdl.dsl`
|
||||||
|
|
|
@ -6,30 +6,30 @@ class Counter(Elaboratable):
|
||||||
def __init__(self, width):
|
def __init__(self, width):
|
||||||
self.v = Signal(width, reset=2**width-1)
|
self.v = Signal(width, reset=2**width-1)
|
||||||
self.o = Signal()
|
self.o = Signal()
|
||||||
self.ce = Signal()
|
self.en = Signal()
|
||||||
|
|
||||||
def elaborate(self, platform):
|
def elaborate(self, platform):
|
||||||
m = Module()
|
m = Module()
|
||||||
m.d.sync += self.v.eq(self.v + 1)
|
m.d.sync += self.v.eq(self.v + 1)
|
||||||
m.d.comb += self.o.eq(self.v[-1])
|
m.d.comb += self.o.eq(self.v[-1])
|
||||||
return CEInserter(self.ce)(m)
|
return EnableInserter(self.en)(m)
|
||||||
|
|
||||||
|
|
||||||
ctr = Counter(width=16)
|
ctr = Counter(width=16)
|
||||||
|
|
||||||
print(verilog.convert(ctr, ports=[ctr.o, ctr.ce]))
|
print(verilog.convert(ctr, ports=[ctr.o, ctr.en]))
|
||||||
|
|
||||||
with pysim.Simulator(ctr,
|
with pysim.Simulator(ctr,
|
||||||
vcd_file=open("ctrl.vcd", "w"),
|
vcd_file=open("ctrl.vcd", "w"),
|
||||||
gtkw_file=open("ctrl.gtkw", "w"),
|
gtkw_file=open("ctrl.gtkw", "w"),
|
||||||
traces=[ctr.ce, ctr.v, ctr.o]) as sim:
|
traces=[ctr.en, ctr.v, ctr.o]) as sim:
|
||||||
sim.add_clock(1e-6)
|
sim.add_clock(1e-6)
|
||||||
def ce_proc():
|
def ce_proc():
|
||||||
yield; yield; yield
|
yield; yield; yield
|
||||||
yield ctr.ce.eq(1)
|
yield ctr.en.eq(1)
|
||||||
yield; yield; yield
|
yield; yield; yield
|
||||||
yield ctr.ce.eq(0)
|
yield ctr.en.eq(0)
|
||||||
yield; yield; yield
|
yield; yield; yield
|
||||||
yield ctr.ce.eq(1)
|
yield ctr.en.eq(1)
|
||||||
sim.add_sync_process(ce_proc())
|
sim.add_sync_process(ce_proc())
|
||||||
sim.run_until(100e-6, run_passive=True)
|
sim.run_until(100e-6, run_passive=True)
|
|
@ -4,4 +4,5 @@ from .cd import ClockDomain
|
||||||
from .ir import Elaboratable, Fragment, Instance
|
from .ir import Elaboratable, Fragment, Instance
|
||||||
from .mem import Memory
|
from .mem import Memory
|
||||||
from .rec import Record
|
from .rec import Record
|
||||||
from .xfrm import DomainRenamer, ResetInserter, CEInserter
|
from .xfrm import DomainRenamer, ResetInserter, EnableInserter, \
|
||||||
|
CEInserter # deprecated
|
||||||
|
|
|
@ -2,7 +2,7 @@ from abc import ABCMeta, abstractmethod
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
from collections.abc import Iterable
|
from collections.abc import Iterable
|
||||||
|
|
||||||
from ..tools import flatten
|
from ..tools import flatten, deprecated
|
||||||
from .. import tracer
|
from .. import tracer
|
||||||
from .ast import *
|
from .ast import *
|
||||||
from .ast import _StatementList
|
from .ast import _StatementList
|
||||||
|
@ -18,7 +18,7 @@ __all__ = ["ValueVisitor", "ValueTransformer",
|
||||||
"DomainCollector", "DomainRenamer", "DomainLowerer",
|
"DomainCollector", "DomainRenamer", "DomainLowerer",
|
||||||
"SampleDomainInjector", "SampleLowerer",
|
"SampleDomainInjector", "SampleLowerer",
|
||||||
"SwitchCleaner", "LHSGroupAnalyzer", "LHSGroupFilter",
|
"SwitchCleaner", "LHSGroupAnalyzer", "LHSGroupFilter",
|
||||||
"ResetInserter", "CEInserter"]
|
"ResetInserter", "EnableInserter", "CEInserter"]
|
||||||
|
|
||||||
|
|
||||||
class ValueVisitor(metaclass=ABCMeta):
|
class ValueVisitor(metaclass=ABCMeta):
|
||||||
|
@ -657,7 +657,7 @@ class ResetInserter(_ControlInserter):
|
||||||
fragment.add_statements(Switch(self.controls[domain], {1: stmts}, src_loc=self.src_loc))
|
fragment.add_statements(Switch(self.controls[domain], {1: stmts}, src_loc=self.src_loc))
|
||||||
|
|
||||||
|
|
||||||
class CEInserter(_ControlInserter):
|
class EnableInserter(_ControlInserter):
|
||||||
def _insert_control(self, fragment, domain, signals):
|
def _insert_control(self, fragment, domain, signals):
|
||||||
stmts = [s.eq(s) for s in signals]
|
stmts = [s.eq(s) for s in signals]
|
||||||
fragment.add_statements(Switch(self.controls[domain], {0: stmts}, src_loc=self.src_loc))
|
fragment.add_statements(Switch(self.controls[domain], {0: stmts}, src_loc=self.src_loc))
|
||||||
|
@ -671,3 +671,6 @@ class CEInserter(_ControlInserter):
|
||||||
en_port = Mux(self.controls[clk_port.domain], en_port, Const(0, len(en_port)))
|
en_port = Mux(self.controls[clk_port.domain], en_port, Const(0, len(en_port)))
|
||||||
new_fragment.named_ports["EN"] = en_port, en_dir
|
new_fragment.named_ports["EN"] = en_port, en_dir
|
||||||
return new_fragment
|
return new_fragment
|
||||||
|
|
||||||
|
|
||||||
|
CEInserter = deprecated("instead of `CEInserter`, use `EnableInserter`")(EnableInserter)
|
||||||
|
|
|
@ -18,7 +18,7 @@ class ExamplesTestCase(FHDLTestCase):
|
||||||
test_arst = example_test("basic/arst.py")
|
test_arst = example_test("basic/arst.py")
|
||||||
test_cdc = example_test("basic/cdc.py")
|
test_cdc = example_test("basic/cdc.py")
|
||||||
test_ctr = example_test("basic/ctr.py")
|
test_ctr = example_test("basic/ctr.py")
|
||||||
test_ctr_ce = example_test("basic/ctr_ce.py")
|
test_ctr_en = example_test("basic/ctr_en.py")
|
||||||
test_fsm = example_test("basic/fsm.py")
|
test_fsm = example_test("basic/fsm.py")
|
||||||
test_gpio = example_test("basic/gpio.py")
|
test_gpio = example_test("basic/gpio.py")
|
||||||
test_inst = example_test("basic/inst.py")
|
test_inst = example_test("basic/inst.py")
|
||||||
|
|
|
@ -437,21 +437,21 @@ class ResetInserterTestCase(FHDLTestCase):
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
|
||||||
class CEInserterTestCase(FHDLTestCase):
|
class EnableInserterTestCase(FHDLTestCase):
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.s1 = Signal()
|
self.s1 = Signal()
|
||||||
self.s2 = Signal()
|
self.s2 = Signal()
|
||||||
self.s3 = Signal()
|
self.s3 = Signal()
|
||||||
self.c1 = Signal()
|
self.c1 = Signal()
|
||||||
|
|
||||||
def test_ce_default(self):
|
def test_enable_default(self):
|
||||||
f = Fragment()
|
f = Fragment()
|
||||||
f.add_statements(
|
f.add_statements(
|
||||||
self.s1.eq(1)
|
self.s1.eq(1)
|
||||||
)
|
)
|
||||||
f.add_driver(self.s1, "sync")
|
f.add_driver(self.s1, "sync")
|
||||||
|
|
||||||
f = CEInserter(self.c1)(f)
|
f = EnableInserter(self.c1)(f)
|
||||||
self.assertRepr(f.statements, """
|
self.assertRepr(f.statements, """
|
||||||
(
|
(
|
||||||
(eq (sig s1) (const 1'd1))
|
(eq (sig s1) (const 1'd1))
|
||||||
|
@ -461,7 +461,7 @@ class CEInserterTestCase(FHDLTestCase):
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def test_ce_cd(self):
|
def test_enable_cd(self):
|
||||||
f = Fragment()
|
f = Fragment()
|
||||||
f.add_statements(
|
f.add_statements(
|
||||||
self.s1.eq(1),
|
self.s1.eq(1),
|
||||||
|
@ -470,7 +470,7 @@ class CEInserterTestCase(FHDLTestCase):
|
||||||
f.add_driver(self.s1, "sync")
|
f.add_driver(self.s1, "sync")
|
||||||
f.add_driver(self.s2, "pix")
|
f.add_driver(self.s2, "pix")
|
||||||
|
|
||||||
f = CEInserter({"pix": self.c1})(f)
|
f = EnableInserter({"pix": self.c1})(f)
|
||||||
self.assertRepr(f.statements, """
|
self.assertRepr(f.statements, """
|
||||||
(
|
(
|
||||||
(eq (sig s1) (const 1'd1))
|
(eq (sig s1) (const 1'd1))
|
||||||
|
@ -481,7 +481,7 @@ class CEInserterTestCase(FHDLTestCase):
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def test_ce_subfragment(self):
|
def test_enable_subfragment(self):
|
||||||
f1 = Fragment()
|
f1 = Fragment()
|
||||||
f1.add_statements(
|
f1.add_statements(
|
||||||
self.s1.eq(1)
|
self.s1.eq(1)
|
||||||
|
@ -495,7 +495,7 @@ class CEInserterTestCase(FHDLTestCase):
|
||||||
f2.add_driver(self.s2, "sync")
|
f2.add_driver(self.s2, "sync")
|
||||||
f1.add_subfragment(f2)
|
f1.add_subfragment(f2)
|
||||||
|
|
||||||
f1 = CEInserter(self.c1)(f1)
|
f1 = EnableInserter(self.c1)(f1)
|
||||||
(f2, _), = f1.subfragments
|
(f2, _), = f1.subfragments
|
||||||
self.assertRepr(f1.statements, """
|
self.assertRepr(f1.statements, """
|
||||||
(
|
(
|
||||||
|
@ -514,16 +514,16 @@ class CEInserterTestCase(FHDLTestCase):
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def test_ce_read_port(self):
|
def test_enable_read_port(self):
|
||||||
mem = Memory(width=8, depth=4)
|
mem = Memory(width=8, depth=4)
|
||||||
f = CEInserter(self.c1)(mem.read_port(transparent=False)).elaborate(platform=None)
|
f = EnableInserter(self.c1)(mem.read_port(transparent=False)).elaborate(platform=None)
|
||||||
self.assertRepr(f.named_ports["EN"][0], """
|
self.assertRepr(f.named_ports["EN"][0], """
|
||||||
(m (sig c1) (sig mem_r_en) (const 1'd0))
|
(m (sig c1) (sig mem_r_en) (const 1'd0))
|
||||||
""")
|
""")
|
||||||
|
|
||||||
def test_ce_write_port(self):
|
def test_enable_write_port(self):
|
||||||
mem = Memory(width=8, depth=4)
|
mem = Memory(width=8, depth=4)
|
||||||
f = CEInserter(self.c1)(mem.write_port()).elaborate(platform=None)
|
f = EnableInserter(self.c1)(mem.write_port()).elaborate(platform=None)
|
||||||
self.assertRepr(f.named_ports["EN"][0], """
|
self.assertRepr(f.named_ports["EN"][0], """
|
||||||
(m (sig c1) (cat (repl (slice (sig mem_w_en) 0:1) 8)) (const 8'd0))
|
(m (sig c1) (cat (repl (slice (sig mem_w_en) 0:1) 8)) (const 8'd0))
|
||||||
""")
|
""")
|
||||||
|
@ -549,13 +549,13 @@ class TransformedElaboratableTestCase(FHDLTestCase):
|
||||||
|
|
||||||
def test_getattr(self):
|
def test_getattr(self):
|
||||||
e = _MockElaboratable()
|
e = _MockElaboratable()
|
||||||
te = CEInserter(self.c1)(e)
|
te = EnableInserter(self.c1)(e)
|
||||||
|
|
||||||
self.assertIs(te.s1, e.s1)
|
self.assertIs(te.s1, e.s1)
|
||||||
|
|
||||||
def test_composition(self):
|
def test_composition(self):
|
||||||
e = _MockElaboratable()
|
e = _MockElaboratable()
|
||||||
te1 = CEInserter(self.c1)(e)
|
te1 = EnableInserter(self.c1)(e)
|
||||||
te2 = ResetInserter(self.c2)(te1)
|
te2 = ResetInserter(self.c2)(te1)
|
||||||
|
|
||||||
self.assertIsInstance(te1, TransformedElaboratable)
|
self.assertIsInstance(te1, TransformedElaboratable)
|
||||||
|
|
Loading…
Reference in a new issue