Emit error if field that is asynchronously reset uses a dynamic reset value. #129

This commit is contained in:
Alex Mykyta
2025-03-07 19:20:44 -08:00
parent d3cd51f500
commit 6430dd4914
4 changed files with 63 additions and 0 deletions

View File

@@ -19,6 +19,7 @@ class DesignValidator(RDLListener):
""" """
def __init__(self, exp:'RegblockExporter') -> None: def __init__(self, exp:'RegblockExporter') -> None:
self.exp = exp self.exp = exp
self.ds = exp.ds
self.msg = self.top_node.env.msg self.msg = self.top_node.env.msg
self._contains_external_block_stack = [] # type: List[bool] self._contains_external_block_stack = [] # type: List[bool]
@@ -152,6 +153,23 @@ class DesignValidator(RDLListener):
node.inst.inst_src_ref node.inst.inst_src_ref
) )
# Check for unsynthesizable reset
reset = node.get_property("reset")
if not (reset is None or isinstance(reset, int)):
# Has reset that is not a constant value
resetsignal = node.get_property("resetsignal")
if resetsignal:
is_async_reset = resetsignal.get_property("async")
else:
is_async_reset = self.ds.default_reset_async
if is_async_reset:
self.msg.error(
"A field that uses an asynchronous reset cannot use a dynamic reset value. This is not synthesizable.",
node.inst.inst_src_ref
)
def exit_AddressableComponent(self, node: AddressableNode) -> None: def exit_AddressableComponent(self, node: AddressableNode) -> None:
if not isinstance(node, RegNode): if not isinstance(node, RegNode):
# Exiting block-like node # Exiting block-like node

View File

@@ -76,3 +76,16 @@ class TestValidationErrors(BaseTestCase):
"multiple_unconditional_assigns.rdl", "multiple_unconditional_assigns.rdl",
"Field has multiple conflicting properties that unconditionally set its state", "Field has multiple conflicting properties that unconditionally set its state",
) )
def test_unsynth_reset1(self) -> None:
self.assert_validate_error(
"unsynth_reset1.rdl",
"A field that uses an asynchronous reset cannot use a dynamic reset value. This is not synthesizable.",
)
def test_unsynth_reset2(self) -> None:
self.default_reset_async = True
self.assert_validate_error(
"unsynth_reset2.rdl",
"A field that uses an asynchronous reset cannot use a dynamic reset value. This is not synthesizable.",
)

View File

@@ -0,0 +1,19 @@
signal {
field_reset;
async;
activehigh;
} foo;
addrmap top {
reg {
field {
sw=rw; hw=na;
} f1;
field {
sw=rw; hw=na;
} f2;
f1->reset = f2;
} x;
};

View File

@@ -0,0 +1,13 @@
addrmap top {
reg {
field {
sw=rw; hw=na;
} f1;
field {
sw=rw; hw=na;
} f2;
f1->reset = f2;
} x;
};