diff --git a/util/reggen/params.py b/util/reggen/params.py index a790370fc0566..bd006224296d4 100644 --- a/util/reggen/params.py +++ b/util/reggen/params.py @@ -96,12 +96,14 @@ def __init__(self, self.default = default self.local = local self.expose = expose + self.name_top = None def as_dict(self) -> Dict[str, object]: rd = super().as_dict() rd['default'] = self.default rd['local'] = 'true' if self.local else 'false' rd['expose'] = 'true' if self.expose else 'false' + rd['name_top'] = self.name_top return rd diff --git a/util/topgen/intermodule.py b/util/topgen/intermodule.py index 6bcc339e163f1..6ea2211ad1602 100644 --- a/util/topgen/intermodule.py +++ b/util/topgen/intermodule.py @@ -778,8 +778,20 @@ def check_intermodule(topcfg: Dict, prefix: str) -> int: err, rsp_struct = check_intermodule_field(rsp_struct) error += err - total_width += rsp_struct["width"] - widths.append(rsp_struct["width"]) + if isinstance(rsp_struct["width"], Parameter): + param = rsp_struct["width"] + if param.expose: + # If it's a top-level exposed parameter, we need to find definition from there + module = lib.get_module_by_name(topcfg, req_m) + width = int(module['param_decl'].get(param.name, param.default)) + else: + width = int(rsp_struct["width"].default) + else: + width = rsp_struct["width"] + assert isinstance(rsp_struct["width"], int) + + total_width += width + widths.append(width) # Type check # If no package was declared, it is declared with an empty string @@ -828,7 +840,7 @@ def check_intermodule(topcfg: Dict, prefix: str) -> int: if param.expose: # If it's a top-level exposed parameter, we need to find definition from there module = lib.get_module_by_name(topcfg, req_m) - width = int(module['param_decl'].get(param.name, req_struct["width"].default)) + width = int(module['param_decl'].get(param.name, param.default)) else: width = int(req_struct["width"].default) else: diff --git a/util/topgen/merge.py b/util/topgen/merge.py index ca8d087a17713..6ddabcc20b900 100644 --- a/util/topgen/merge.py +++ b/util/topgen/merge.py @@ -173,6 +173,14 @@ def elaborate_instance(instance, block: IpBlock): if isinstance(s['width'], Parameter): for p in instance["param_list"]: if p['name'] == s['width'].name: + # When mangling the name, we first need to deep copy the param. Parameters in + # signals have a reference to a parameter. If we have multiple instances of the + # same IP, then their signals would reference the same single parameter. If we + # would mangle that directly, we all signals of all IPs would reference to that + # single mangled paramter. Since parameters are instance dependent, that would + # fail. Therefore, copy the parameter first to have a unique paramter for that + # particular signal and instance, which is safe to mangle. + s['width'] = deepcopy(s['width']) s['width'].name_top = p['name_top'] # An instance must either have a 'base_addr' address or a 'base_addrs'