Skip to content

Commit

Permalink
Implement proper check for illegal component references embedded in a…
Browse files Browse the repository at this point in the history
…ggregate datatypes in parameters. #114
  • Loading branch information
amykyta3 committed Apr 9, 2023
1 parent 4df2382 commit b7f80e5
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 3 deletions.
12 changes: 10 additions & 2 deletions systemrdl/core/elaborate.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from ..ast import ASTNode
from .helpers import is_pow2, roundup_pow2, roundup_to
from .value_normalization import normalize
from .value_normalization import normalize, RefInParameterError

from .. import component as comp
from .. import walker
Expand Down Expand Up @@ -608,7 +608,15 @@ def exit_Component(self, node: Node) -> None:
orig_param_value = node.inst.original_def.parameters[i].get_value()
new_param_value = inst_parameter.get_value()
if new_param_value != orig_param_value:
extra_type_name_segments.append(inst_parameter.get_normalized_parameter())
try:
segment = inst_parameter.get_normalized_parameter()
extra_type_name_segments.append(segment)
except RefInParameterError:
self.msg.error(
"Parameter '%s' contains a reference. SystemRDL does not allow component references inside parameter values."
% inst_parameter.name,
node.inst.inst_src_ref
)

# Further augment type name as per extended type generation from DPAs
if self.env.use_extended_type_name_gen:
Expand Down
12 changes: 11 additions & 1 deletion systemrdl/core/value_normalization.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
from .. import rdltypes
from .. import node

class RefInParameterError(Exception):
pass

def normalize(value: Any, owner_node: Optional[node.Node]=None) -> str:
"""
Flatten an RDL value into a unique string that is used for type
Expand Down Expand Up @@ -31,9 +34,16 @@ def normalize(value: Any, owner_node: Optional[node.Node]=None) -> str:
elif value is rdltypes.NoValue:
# this only happens if a UDP is assigned with no value
return "NaN"
elif isinstance(value, rdltypes.references.ComponentRef) and owner_node is None:
# This only happens if a parameter contains a struct that wraps a reference
# datatype. # Since the parameter's value doesnt bother getting resolved,
# It shows up as a ComponentRef object here.
# SystemRDL spec does not allow references in parameters, so this ends up
# being an odd, but convenient place to catch this.
raise RefInParameterError
else:
# Should never get here
raise RuntimeError(value)
raise RuntimeError(value, owner_node)


def normalize_scalar(value: int) -> str:
Expand Down
24 changes: 24 additions & 0 deletions test/rdl_err_src/err_ref_in_parameter.rdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
signal {} my_signal1;
signal {} my_signal2;

struct my_struct {
signal my_ref;
};

reg myReg #(
my_struct PARAM = my_struct'{my_ref: my_signal1}
) {
field {
next = PARAM.my_ref;
} data[0:0] = 0;
};

addrmap parameters1 {
myReg reg0;
};

addrmap parameters2 {
myReg #(
.PARAM(my_struct'{my_ref: my_signal2})
) reg0;
};
13 changes: 13 additions & 0 deletions test/test_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,16 @@ def test_param_scope(self):
self.assertEqual(ffX.width, 2)
self.assertEqual(ffY.width, 3)
self.assertEqual(ffZ.width, 1)

def test_err_ref_in_parameter(self):
self.assertRDLCompileError(
["rdl_err_src/err_ref_in_parameter.rdl"],
"parameters1",
r"Parameter 'PARAM' contains a reference. SystemRDL does not allow component references inside parameter values."
)

self.assertRDLCompileError(
["rdl_err_src/err_ref_in_parameter.rdl"],
"parameters2",
r"Parameter 'PARAM' contains a reference. SystemRDL does not allow component references inside parameter values."
)

0 comments on commit b7f80e5

Please sign in to comment.