From 68c922cf80e02a5945d2dd4f462809cc3a80b250 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Mon, 27 Sep 2021 19:18:16 +0100 Subject: [PATCH] add redirection of __Switch__ to allow overrides for advanced behaviour without changing fundamental language characteristics or semantics in nmigen https://bugs.libre-soc.org/show_bug.cgi?id=458 --- nmigen/compat/fhdl/structure.py | 4 ++-- nmigen/hdl/ast.py | 13 ++++++++++++- nmigen/hdl/xfrm.py | 5 +++-- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/nmigen/compat/fhdl/structure.py b/nmigen/compat/fhdl/structure.py index d450e45..68ddc49 100644 --- a/nmigen/compat/fhdl/structure.py +++ b/nmigen/compat/fhdl/structure.py @@ -119,7 +119,7 @@ def choices(self): return self.elems -class If(ast.Switch): +class If(ast._InternalSwitch): @deprecated("instead of `If(cond, ...)`, use `with m.If(cond): ...`") def __init__(self, cond, *stmts): cond = Value.cast(cond) @@ -143,7 +143,7 @@ class If(ast.Switch): return self -class Case(ast.Switch): +class Case(ast._InternalSwitch): @deprecated("instead of `Case(test, { value: stmts })`, use `with m.Switch(test):` and " "`with m.Case(value): stmts`; instead of `\"default\": stmts`, use " "`with m.Case(): stmts`") diff --git a/nmigen/hdl/ast.py b/nmigen/hdl/ast.py index a2af8c7..d6944d2 100644 --- a/nmigen/hdl/ast.py +++ b/nmigen/hdl/ast.py @@ -15,6 +15,7 @@ __all__ = [ "Shape", "signed", "unsigned", "Value", "Const", "C", "AnyConst", "AnySeq", "Operator", "Mux", "Part", "Slice", "Cat", "Repl", "Array", "ArrayProxy", + "_InternalSwitch", "Signal", "ClockSignal", "ResetSignal", "UserValue", "ValueCastable", "Sample", "Past", "Stable", "Rose", "Fell", "Initial", @@ -153,6 +154,11 @@ class Value(metaclass=ABCMeta): def __Mux__(self, val1, val0): return _InternalMux(self, val1, val0) + def __Switch__(self, cases, *, src_loc=None, src_loc_at=0, case_src_locs={}): + return _InternalSwitch(self, cases, src_loc=src_loc, + src_loc_at=src_loc_at, + case_src_locs=case_src_locs) + def __bool__(self): raise TypeError("Attempted to convert nMigen value to Python boolean") @@ -1485,7 +1491,12 @@ class Cover(Property): # @final -class Switch(Statement): +def Switch(test, cases, *, src_loc=None, src_loc_at=0, case_src_locs={}): + return test.__Switch__(cases, src_loc=src_loc, src_loc_at=src_loc_at, + case_src_locs=case_src_locs) + + +class _InternalSwitch(Statement): def __init__(self, test, cases, *, src_loc=None, src_loc_at=0, case_src_locs={}): if src_loc is None: super().__init__(src_loc_at=src_loc_at) diff --git a/nmigen/hdl/xfrm.py b/nmigen/hdl/xfrm.py index 97f8c53..7cf142a 100644 --- a/nmigen/hdl/xfrm.py +++ b/nmigen/hdl/xfrm.py @@ -213,7 +213,7 @@ class StatementVisitor(metaclass=ABCMeta): new_stmt = self.on_Assume(stmt) elif type(stmt) is Cover: new_stmt = self.on_Cover(stmt) - elif isinstance(stmt, Switch): + elif isinstance(stmt, _InternalSwitch): # Uses `isinstance()` and not `type() is` because nmigen.compat requires it. new_stmt = self.on_Switch(stmt) elif isinstance(stmt, Iterable): @@ -222,7 +222,8 @@ class StatementVisitor(metaclass=ABCMeta): new_stmt = self.on_unknown_statement(stmt) if isinstance(new_stmt, Statement) and self.replace_statement_src_loc(stmt, new_stmt): new_stmt.src_loc = stmt.src_loc - if isinstance(new_stmt, Switch) and isinstance(stmt, Switch): + if (isinstance(new_stmt, _InternalSwitch) and + isinstance(stmt, _InternalSwitch)): new_stmt.case_src_locs = stmt.case_src_locs if isinstance(new_stmt, Property): new_stmt._MustUse__used = True -- 2.30.2