hdl.xfrm: implement SwitchCleaner, for pruning empty switches.
This commit is contained in:
parent
fc0fb9d89f
commit
1c7c75a254
|
@ -620,6 +620,7 @@ def convert_fragment(builder, fragment, name, top):
|
||||||
rhs_compiler = _RHSValueCompiler(compiler_state)
|
rhs_compiler = _RHSValueCompiler(compiler_state)
|
||||||
lhs_compiler = _LHSValueCompiler(compiler_state)
|
lhs_compiler = _LHSValueCompiler(compiler_state)
|
||||||
stmt_compiler = _StatementCompiler(compiler_state, rhs_compiler, lhs_compiler)
|
stmt_compiler = _StatementCompiler(compiler_state, rhs_compiler, lhs_compiler)
|
||||||
|
switch_cleaner = xfrm.SwitchCleaner()
|
||||||
|
|
||||||
verilog_trigger = None
|
verilog_trigger = None
|
||||||
verilog_trigger_sync_emitted = False
|
verilog_trigger_sync_emitted = False
|
||||||
|
@ -720,7 +721,7 @@ def convert_fragment(builder, fragment, name, top):
|
||||||
stmt_compiler._group = group_signals
|
stmt_compiler._group = group_signals
|
||||||
stmt_compiler._case = case
|
stmt_compiler._case = case
|
||||||
stmt_compiler._has_rhs = False
|
stmt_compiler._has_rhs = False
|
||||||
stmt_compiler(fragment.statements)
|
stmt_compiler(switch_cleaner(fragment.statements))
|
||||||
|
|
||||||
# Verilog `always @*` blocks will not run if `*` does not match anythng, i.e.
|
# Verilog `always @*` blocks will not run if `*` does not match anythng, i.e.
|
||||||
# if the implicit sensitivity list is empty. We check this while translating,
|
# if the implicit sensitivity list is empty. We check this while translating,
|
||||||
|
|
|
@ -13,7 +13,7 @@ __all__ = ["ValueVisitor", "ValueTransformer",
|
||||||
"StatementVisitor", "StatementTransformer",
|
"StatementVisitor", "StatementTransformer",
|
||||||
"FragmentTransformer",
|
"FragmentTransformer",
|
||||||
"DomainRenamer", "DomainLowerer",
|
"DomainRenamer", "DomainLowerer",
|
||||||
"LHSGroupAnalyzer",
|
"SwitchCleaner", "LHSGroupAnalyzer",
|
||||||
"ResetInserter", "CEInserter"]
|
"ResetInserter", "CEInserter"]
|
||||||
|
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ class StatementTransformer(StatementVisitor):
|
||||||
return Assign(self.on_value(stmt.lhs), self.on_value(stmt.rhs))
|
return Assign(self.on_value(stmt.lhs), self.on_value(stmt.rhs))
|
||||||
|
|
||||||
def on_Switch(self, stmt):
|
def on_Switch(self, stmt):
|
||||||
cases = OrderedDict((k, self.on_statement(v)) for k, v in stmt.cases.items())
|
cases = OrderedDict((k, self.on_statement(s)) for k, s in stmt.cases.items())
|
||||||
return Switch(self.on_value(stmt.test), cases)
|
return Switch(self.on_value(stmt.test), cases)
|
||||||
|
|
||||||
def on_statements(self, stmts):
|
def on_statements(self, stmts):
|
||||||
|
@ -280,6 +280,20 @@ class DomainLowerer(FragmentTransformer, ValueTransformer, StatementTransformer)
|
||||||
return cd.rst
|
return cd.rst
|
||||||
|
|
||||||
|
|
||||||
|
class SwitchCleaner(StatementVisitor):
|
||||||
|
def on_Assign(self, stmt):
|
||||||
|
return stmt
|
||||||
|
|
||||||
|
def on_Switch(self, stmt):
|
||||||
|
cases = OrderedDict((k, self.on_statement(s)) for k, s in stmt.cases.items())
|
||||||
|
if any(len(s) for s in stmt.cases.values()):
|
||||||
|
return Switch(stmt.test, cases)
|
||||||
|
|
||||||
|
def on_statements(self, stmts):
|
||||||
|
stmts = flatten(self.on_statement(stmt) for stmt in stmts)
|
||||||
|
return _StatementList(stmt for stmt in stmts if stmt is not None)
|
||||||
|
|
||||||
|
|
||||||
class LHSGroupAnalyzer(StatementVisitor):
|
class LHSGroupAnalyzer(StatementVisitor):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.signals = SignalDict()
|
self.signals = SignalDict()
|
||||||
|
|
|
@ -158,6 +158,33 @@ class DomainLowererTestCase(FHDLTestCase):
|
||||||
DomainLowerer({"sync": sync})(f)
|
DomainLowerer({"sync": sync})(f)
|
||||||
|
|
||||||
|
|
||||||
|
class SwitchCleanerTestCase(FHDLTestCase):
|
||||||
|
def test_clean(self):
|
||||||
|
a = Signal()
|
||||||
|
b = Signal()
|
||||||
|
c = Signal()
|
||||||
|
stmts = [
|
||||||
|
Switch(a, {
|
||||||
|
1: a.eq(0),
|
||||||
|
0: [
|
||||||
|
b.eq(1),
|
||||||
|
Switch(b, {1: []})
|
||||||
|
]
|
||||||
|
})
|
||||||
|
]
|
||||||
|
|
||||||
|
self.assertRepr(SwitchCleaner()(stmts), """
|
||||||
|
(
|
||||||
|
(switch (sig a)
|
||||||
|
(case 1
|
||||||
|
(eq (sig a) (const 1'd0)))
|
||||||
|
(case 0
|
||||||
|
(eq (sig b) (const 1'd1)))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
""")
|
||||||
|
|
||||||
|
|
||||||
class LHSGroupAnalyzerTestCase(FHDLTestCase):
|
class LHSGroupAnalyzerTestCase(FHDLTestCase):
|
||||||
def test_no_group_unrelated(self):
|
def test_no_group_unrelated(self):
|
||||||
a = Signal()
|
a = Signal()
|
||||||
|
|
Loading…
Reference in a new issue