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: 8cc900c4ef02
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: 6672ab2e3fd7
Choose a head ref
  • 3 commits
  • 5 files changed
  • 1 contributor

Commits on Dec 20, 2018

  1. ir: allow non-Signals in Instance ports.

    whitequark committed Dec 20, 2018
    Copy the full SHA
    f7fec80 View commit details

Commits on Dec 21, 2018

  1. back.rtlil: fix translation of Cat.

    whitequark committed Dec 21, 2018
    Copy the full SHA
    221f108 View commit details
  2. back.rtlil: explicitly pad constants with zeroes.

    I'm not sure what exactly RTLIL does when a constant isn't as long
    as its bit width, and there's no reason to keep the ambiguity.
    whitequark committed Dec 21, 2018

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    6672ab2 View commit details
Showing with 45 additions and 27 deletions.
  1. +1 −0 examples/inst.py
  2. +6 −9 nmigen/back/rtlil.py
  3. +16 −11 nmigen/hdl/ir.py
  4. +13 −4 nmigen/hdl/xfrm.py
  5. +9 −3 nmigen/test/test_hdl_ir.py
1 change: 1 addition & 0 deletions examples/inst.py
Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@ def get_fragment(self, platform):
i_d_adr =self.adr,
i_d_dat_r=self.dat_r,
o_d_dat_w=self.dat_w,
i_d_we =self.we,
)
return m.lower(platform)

15 changes: 6 additions & 9 deletions nmigen/back/rtlil.py
Original file line number Diff line number Diff line change
@@ -298,7 +298,7 @@ def on_ResetSignal(self, value):
raise NotImplementedError # :nocov:

def on_Cat(self, value):
return "{{ {} }}".format(" ".join(reversed([self(o) for o in value.operands])))
return "{{ {} }}".format(" ".join(reversed([self(o) for o in value.parts])))

def _prepare_value_for_Slice(self, value):
raise NotImplementedError # :nocov:
@@ -353,7 +353,7 @@ def on_Const(self, value):
if isinstance(value.value, str):
return "{}'{}".format(value.nbits, value.value)
else:
return "{}'{:b}".format(value.nbits, value.value)
return "{}'{:0{}b}".format(value.nbits, value.value, value.nbits)

def on_Signal(self, value):
wire_curr, wire_next = self.s.resolve(value)
@@ -567,15 +567,12 @@ def on_statements(self, stmts):


def convert_fragment(builder, fragment, name, top):
if fragment.black_box is not None:
if isinstance(fragment, ir.Instance):
port_map = OrderedDict()
for signal in fragment.ports:
port_map["\\{}".format(fragment.port_names[signal])] = signal
for port_name, value in fragment.named_ports.items():
port_map["\\{}".format(port_name)] = value

return "\\{}".format(fragment.black_box), port_map
else:
assert not fragment.port_names
assert not fragment.parameters
return "\\{}".format(fragment.type), port_map

with builder.module(name or "anonymous", attrs={"top": 1} if top else {}) as module:
compiler_state = _ValueCompilerState(module)
27 changes: 16 additions & 11 deletions nmigen/hdl/ir.py
Original file line number Diff line number Diff line change
@@ -15,10 +15,6 @@ class DriverConflict(UserWarning):

class Fragment:
def __init__(self):
self.black_box = None
self.port_names = SignalDict()
self.parameters = OrderedDict()

self.ports = SignalDict()
self.drivers = OrderedDict()
self.statements = []
@@ -241,8 +237,11 @@ def _lower_domain_signals(self):
def _propagate_ports(self, ports):
# Collect all signals we're driving (on LHS of statements), and signals we're using
# (on RHS of statements, or in clock domains).
self_driven = union(s._lhs_signals() for s in self.statements) or SignalSet()
self_used = union(s._rhs_signals() for s in self.statements) or SignalSet()
self_driven = union((s._lhs_signals() for s in self.statements), start=SignalSet())
self_used = union((s._rhs_signals() for s in self.statements), start=SignalSet())
if isinstance(self, Instance):
self_used |= union((p._rhs_signals() for p in self.named_ports.values()),
start=SignalSet())
for domain, _ in self.iter_sync():
cd = self.domains[domain]
self_used.add(cd.clk)
@@ -296,18 +295,24 @@ def prepare(self, ports=(), ensure_sync_exists=True):
class Instance(Fragment):
def __init__(self, type, **kwargs):
super().__init__()
self.black_box = type

self.type = type
self.parameters = OrderedDict()
self.named_ports = OrderedDict()

for kw, arg in kwargs.items():
if kw.startswith("p_"):
self.parameters[kw[2:]] = arg
elif kw.startswith("i_"):
self.port_names[arg] = kw[2:]
self.add_ports(arg, dir="i")
self.named_ports[kw[2:]] = arg
# Unlike with "o_" and "io_", "i_" ports can be assigned an arbitrary value;
# this includes unresolved ClockSignals etc. We rely on Fragment.prepare to
# populate fragment ports for these named ports.
elif kw.startswith("o_"):
self.port_names[arg] = kw[2:]
self.named_ports[kw[2:]] = arg
self.add_ports(arg, dir="o")
elif kw.startswith("io_"):
self.port_names[arg] = kw[3:]
self.named_ports[kw[3:]] = arg
self.add_ports(arg, dir="io")
else:
raise NameError("Instance argument '{}' does not start with p_, i_, o_, or io_"
17 changes: 13 additions & 4 deletions nmigen/hdl/xfrm.py
Original file line number Diff line number Diff line change
@@ -179,6 +179,13 @@ def map_ports(self, fragment, new_fragment):
for port, dir in fragment.ports.items():
new_fragment.add_ports(port, dir=dir)

def map_named_ports(self, fragment, new_fragment):
if hasattr(self, "on_value"):
for name, value in fragment.named_ports.items():
new_fragment.named_ports[name] = self.on_value(value)
else:
new_fragment.named_ports = OrderedDict(fragment.named_ports.items())

def map_domains(self, fragment, new_fragment):
for domain in fragment.iter_domains():
new_fragment.add_domains(fragment.domains[domain])
@@ -194,10 +201,12 @@ def map_drivers(self, fragment, new_fragment):
new_fragment.add_driver(signal, domain)

def on_fragment(self, fragment):
new_fragment = Fragment()
new_fragment.black_box = fragment.black_box
new_fragment.parameters = OrderedDict(fragment.parameters)
new_fragment.port_names = SignalDict(fragment.port_names.items())
if isinstance(fragment, Instance):
new_fragment = Instance(fragment.type)
new_fragment.parameters = OrderedDict(fragment.parameters)
self.map_named_ports(fragment, new_fragment)
else:
new_fragment = Fragment()
self.map_ports(fragment, new_fragment)
self.map_subfragments(fragment, new_fragment)
self.map_domains(fragment, new_fragment)
12 changes: 9 additions & 3 deletions nmigen/test/test_hdl_ir.py
Original file line number Diff line number Diff line change
@@ -412,11 +412,17 @@ def test_init(self):
rst = Signal()
stb = Signal()
pins = Signal(8)
inst = Instance("cpu", p_RESET=0x1234, i_rst=rst, o_stb=stb, io_pins=pins)
self.assertEqual(inst.black_box, "cpu")
inst = Instance("cpu",
p_RESET=0x1234,
i_clk=ClockSignal(),
i_rst=rst,
o_stb=stb,
io_pins=pins
)
self.assertEqual(inst.type, "cpu")
self.assertEqual(inst.parameters, OrderedDict([("RESET", 0x1234)]))
self.assertEqual(list(inst.named_ports.keys()), ["clk", "rst", "stb", "pins"])
self.assertEqual(inst.ports, SignalDict([
(rst, "i"),
(stb, "o"),
(pins, "io"),
]))