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: 0a603b3844b8
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: ee03eab52fbc
Choose a head ref
  • 1 commit
  • 1 file changed
  • 1 contributor

Commits on Aug 3, 2019

  1. back.rtlil: fix sim-synth mismatch with assigns following switches.

    Closes #155.
    whitequark committed Aug 3, 2019
    Copy the full SHA
    ee03eab View commit details
Showing with 15 additions and 1 deletion.
  1. +15 −1 nmigen/back/rtlil.py
16 changes: 15 additions & 1 deletion nmigen/back/rtlil.py
Original file line number Diff line number Diff line change
@@ -605,6 +605,7 @@ def __init__(self, state, rhs_compiler, lhs_compiler):
self._case = None
self._test_cache = {}
self._has_rhs = False
self._wrap_assign = False

@contextmanager
def case(self, switch, values, attrs={}, src=""):
@@ -630,7 +631,15 @@ def on_Assign(self, stmt):
# In RTLIL, LHS and RHS of assignment must have exactly same width.
rhs_sigspec = self.rhs_compiler.match_shape(
stmt.rhs, lhs_bits, lhs_sign)
self._case.assign(self.lhs_compiler(stmt.lhs), rhs_sigspec)
if self._wrap_assign:
# In RTLIL, all assigns are logically sequenced before all switches, even if they are
# interleaved in the source. In nMigen, the source ordering is used. To handle this
# mismatch, we wrap all assigns following a switch in a dummy switch.
with self._case.switch("{ }") as wrap_switch:
with wrap_switch.case() as wrap_case:
wrap_case.assign(self.lhs_compiler(stmt.lhs), rhs_sigspec)
else:
self._case.assign(self.lhs_compiler(stmt.lhs), rhs_sigspec)

def on_Assert(self, stmt):
self(stmt._check.eq(stmt.test))
@@ -675,7 +684,9 @@ def on_Switch(self, stmt):
decoded_values.append(stmt.test.decoder(int(value, 2)))
case_attrs["nmigen.decoding"] = "|".join(decoded_values)
with self.case(switch, values, attrs=case_attrs):
self._wrap_assign = False
self.on_statements(stmts)
self._wrap_assign = True

def on_statement(self, stmt):
try:
@@ -688,9 +699,11 @@ def on_statement(self, stmt):
tests[-1] = "-" * bits
for branch, test in zip(legalize.branches, tests):
with self.case(switch, (test,)):
self._wrap_assign = False
branch_value = ast.Const(branch, (bits, sign))
with self.state.expand_to(legalize.value, branch_value):
super().on_statement(stmt)
self._wrap_assign = True

def on_statements(self, stmts):
for stmt in stmts:
@@ -827,6 +840,7 @@ def convert_fragment(builder, fragment, hierarchy):
# Convert statements into decision trees.
stmt_compiler._case = case
stmt_compiler._has_rhs = False
stmt_compiler._wrap_assign = False
stmt_compiler(group_stmts)

# Verilog `always @*` blocks will not run if `*` does not match anything, i.e.