Skip to content

Commit

Permalink
[topgen] Deepcopy parameter when mangeling
Browse files Browse the repository at this point in the history
Otherwise, the same parameter of a difference instance
would be overwritten

Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 committed Dec 18, 2024
1 parent 56f2e95 commit 60f73cd
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
2 changes: 2 additions & 0 deletions util/reggen/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
17 changes: 14 additions & 3 deletions util/topgen/intermodule.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,8 +778,19 @@ 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"]

total_width += width
widths.append(width)

# Type check
# If no package was declared, it is declared with an empty string
Expand Down Expand Up @@ -828,7 +839,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:
Expand Down
8 changes: 8 additions & 0 deletions util/topgen/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down

0 comments on commit 60f73cd

Please sign in to comment.