Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/nmigen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 011bf2258e77
Choose a base ref
...
head repository: m-labs/nmigen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: b534e92dd5a7
Choose a head ref
  • 2 commits
  • 6 files changed
  • 1 contributor

Commits on Jan 14, 2019

  1. lib.io: lower to platform-independent tristate buffer.

    whitequark committed Jan 14, 2019
    Copy the full SHA
    6f66885 View commit details
  2. hdl.ir: allow explicitly requesting flattening.

    whitequark committed Jan 14, 2019
    Copy the full SHA
    b534e92 View commit details
Showing with 60 additions and 5 deletions.
  1. +12 −0 examples/tbuf.py
  2. +1 −0 nmigen/__init__.py
  3. +10 −4 nmigen/hdl/ir.py
  4. +1 −0 nmigen/hdl/xfrm.py
  5. +27 −1 nmigen/lib/io.py
  6. +9 −0 nmigen/test/test_hdl_ir.py
12 changes: 12 additions & 0 deletions examples/tbuf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from nmigen import *
from nmigen.cli import main


pin = Signal()
pin_t = TSTriple()

m = Module()
m.submodules += pin_t.get_tristate(pin)

if __name__ == "__main__":
main(m.lower(platform=None), ports=[pin, pin_t.oe, pin_t.i, pin_t.o])
1 change: 1 addition & 0 deletions nmigen/__init__.py
Original file line number Diff line number Diff line change
@@ -7,3 +7,4 @@
from .hdl.xfrm import ResetInserter, CEInserter

from .lib.cdc import MultiReg
from .lib.io import TSTriple
14 changes: 10 additions & 4 deletions nmigen/hdl/ir.py
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ def __init__(self):
self.domains = OrderedDict()
self.subfragments = []
self.generated = OrderedDict()
self.flatten = False

def add_ports(self, *ports, dir):
assert dir in ("i", "o", "io")
@@ -141,7 +142,16 @@ def add_subfrag(registry, entity, entry):
for domain, signal in self.iter_drivers():
add_subfrag(driver_subfrags, signal, (None, hierarchy))

flatten_subfrags = set()
for i, (subfrag, name) in enumerate(self.subfragments):
if name is None:
name = "<unnamed #{}>".format(i)
subfrag_hierarchy = hierarchy + (name,)

if subfrag.flatten:
# Always flatten subfragments that explicitly request it.
flatten_subfrags.add((subfrag, subfrag_hierarchy))

if isinstance(subfrag, Instance):
# For memories (which are subfragments, but semantically a part of superfragment),
# record that this fragment is driving it.
@@ -153,9 +163,6 @@ def add_subfrag(registry, entity, entry):
continue

# First, recurse into subfragments and let them detect driver conflicts as well.
if name is None:
name = "<unnamed #{}>".format(i)
subfrag_hierarchy = hierarchy + (name,)
subfrag_drivers, subfrag_memories = \
subfrag._resolve_hierarchy_conflicts(subfrag_hierarchy, mode)

@@ -167,7 +174,6 @@ def add_subfrag(registry, entity, entry):

# Find out the set of subfragments that needs to be flattened into this fragment
# to resolve driver-driver conflicts.
flatten_subfrags = set()
def flatten_subfrags_if_needed(subfrags):
if len(subfrags) == 1:
return []
1 change: 1 addition & 0 deletions nmigen/hdl/xfrm.py
Original file line number Diff line number Diff line change
@@ -237,6 +237,7 @@ def on_fragment(self, fragment):
self.map_named_ports(fragment, new_fragment)
else:
new_fragment = Fragment()
new_fragment.flatten = fragment.flatten
self.map_ports(fragment, new_fragment)
self.map_subfragments(fragment, new_fragment)
self.map_domains(fragment, new_fragment)
28 changes: 27 additions & 1 deletion nmigen/lib/io.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .. import *


__all__ = ["TSTriple"]
__all__ = ["TSTriple", "Tristate"]


class TSTriple:
@@ -19,3 +19,29 @@ def __len__(self):

def get_fragment(self, platform):
return Fragment()

def get_tristate(self, io):
return Tristate(self, io)


class Tristate:
def __init__(self, triple, io):
self.triple = triple
self.io = io

def get_fragment(self, platform):
if hasattr(platform, "get_tristate"):
return platform.get_tristate(self.triple)

m = Module()
m.d.comb += self.triple.i.eq(self.io)
m.submodules += Instance("$tribuf",
p_WIDTH=len(self.io),
i_EN=self.triple.oe,
i_A=self.triple.o,
o_Y=self.io,
)

f = m.lower(platform)
f.flatten = True
return f
9 changes: 9 additions & 0 deletions nmigen/test/test_hdl_ir.py
Original file line number Diff line number Diff line change
@@ -509,6 +509,15 @@ def test_conflict_memory_warning(self):
"top.<unnamed #1>; hierarchy will be flattened"):
self.f1._resolve_hierarchy_conflicts(mode="warn")

def test_explicit_flatten(self):
self.f1 = Fragment()
self.f2 = Fragment()
self.f2.flatten = True
self.f1.add_subfragment(self.f2)

self.f1._resolve_hierarchy_conflicts(mode="silent")
self.assertEqual(self.f1.subfragments, [])


class InstanceTestCase(FHDLTestCase):
def setUp_cpu(self):