Implement RFC 39: Change semantics of no-argument m.Case().

This commit is contained in:
Wanda 2024-01-13 12:35:52 +01:00 committed by Catherine
parent eb1c55859e
commit 86d14f584e
5 changed files with 25 additions and 8 deletions

View file

@ -542,7 +542,7 @@ class Value(metaclass=ABCMeta):
continue
matches.append(self == pattern)
if not matches:
return Const(1)
return Const(0)
elif len(matches) == 1:
return matches[0]
else:

View file

@ -343,19 +343,31 @@ class Module(_ModuleBuilderRoot, Elaboratable):
yield
self._flush_ctrl()
# If none of the provided cases can possibly be true, omit this branch completely.
# This needs to be differentiated from no cases being provided in the first place,
# which means the branch will always match.
# Likewise, omit this branch if another branch with this exact set of patterns already
# exists (since otherwise we'd overwrite the previous branch's slot in the dict).
if not (patterns and not new_patterns) and new_patterns not in switch_data["cases"]:
if new_patterns and new_patterns not in switch_data["cases"]:
switch_data["cases"][new_patterns] = self._statements
switch_data["case_src_locs"][new_patterns] = src_loc
finally:
self._ctrl_context = "Switch"
self._statements = _outer_case
@contextmanager
def Default(self):
return self.Case()
self._check_context("Default", context="Switch")
src_loc = tracer.get_src_loc(src_loc_at=1)
switch_data = self._get_ctrl("Switch")
try:
_outer_case, self._statements = self._statements, []
self._ctrl_context = None
yield
self._flush_ctrl()
if () not in switch_data["cases"]:
switch_data["cases"][()] = self._statements
switch_data["case_src_locs"][()] = src_loc
finally:
self._ctrl_context = "Switch"
self._statements = _outer_case
@contextmanager
def FSM(self, reset=None, domain="sync", name="fsm"):