diff --git a/hw/top_darjeeling/templates/toplevel.sv.tpl b/hw/top_darjeeling/templates/toplevel.sv.tpl index e623dbaa47e4f..344b90bcd3670 100644 --- a/hw/top_darjeeling/templates/toplevel.sv.tpl +++ b/hw/top_darjeeling/templates/toplevel.sv.tpl @@ -127,8 +127,8 @@ module top_${top["name"]} #( // Unmanaged external clocks % for clk in top['unmanaged_clocks']._asdict().values(): - input clk_${clk.name}_i, - input prim_mubi_pkg::mubi4_t cg_${clk.name}_i, + input ${clk.signal_name}, + input prim_mubi_pkg::mubi4_t ${clk.cg_en_signal}, % endfor % endif % if len(top['unmanaged_resets']._asdict().values()) > 0: @@ -377,7 +377,7 @@ assert isinstance(clocks, Clocks) typed_clocks = clocks.typed_clocks() known_clocks = {} for clk in typed_clocks.all_clocks(): - known_clocks.update({top['clocks'].hier_paths['lpg'] + clk.split('clk_')[-1]: 1}) + known_clocks.update({lib.get_clock_lpg_path(top, clk): 1}) # get all known resets and add them to a dict # this is used to generate the tie-off assignments further below @@ -401,10 +401,7 @@ for rst in output_rsts: % for k, lpg in enumerate(top['alert_lpgs']): // ${lpg['name']} <% - if lpg['unmanaged_clock']: - cg_en = 'cg_' + lpg['clock_connection'].split('clk_')[-1] - else: - cg_en = top['clocks'].hier_paths['lpg'] + lpg['clock_connection'].split('.clk_')[-1] + cg_en = lib.get_clock_lpg_path(top, lpg['clock_connection'], lpg['unmanaged_clock']) rst_en = lib.get_reset_lpg_path(top, lpg['reset_connection'], False, None, lpg['unmanaged_reset']) known_clocks[cg_en] = 0 known_resets[rst_en] = 0 @@ -418,7 +415,7 @@ for rst in output_rsts: % for k, lpg in enumerate(lpgs): // ${lpg['name']} <% - cg_en = top['clocks'].hier_paths['lpg'] + lpg['clock_connection'].split('.clk_')[-1] + cg_en = lib.get_clock_lpg_path(top, lpg['clock_connection'], lpg['unmanaged_clock']) rst_en = lib.get_reset_lpg_path(top, lpg['reset_connection'], False, None, lpg['unmanaged_reset']) known_clocks[cg_en] = 0 known_resets[rst_en] = 0 diff --git a/hw/top_earlgrey/templates/toplevel.sv.tpl b/hw/top_earlgrey/templates/toplevel.sv.tpl index 98dd6e9a2acfb..39f71c44af8a9 100644 --- a/hw/top_earlgrey/templates/toplevel.sv.tpl +++ b/hw/top_earlgrey/templates/toplevel.sv.tpl @@ -145,8 +145,8 @@ module top_${top["name"]} #( // Unmanaged external clocks % for clk in top['unmanaged_clocks']._asdict().values(): - input clk_${clk.name}_i, - input prim_mubi_pkg::mubi4_t cg_${clk.name}_i, + input ${clk.signal_name}, + input prim_mubi_pkg::mubi4_t ${clk.cg_en_signal}, % endfor % endif % if len(top['unmanaged_resets']._asdict().values()) > 0: @@ -404,7 +404,7 @@ assert isinstance(clocks, Clocks) typed_clocks = clocks.typed_clocks() known_clocks = {} for clk in typed_clocks.all_clocks(): - known_clocks.update({top['clocks'].hier_paths['lpg'] + clk.split('clk_')[-1]: 1}) + known_clocks.update({lib.get_clock_lpg_path(top, clk): 1}) # get all known resets and add them to a dict # this is used to generate the tie-off assignments further below @@ -427,11 +427,8 @@ for rst in output_rsts: % for k, lpg in enumerate(top['alert_lpgs']): // ${lpg['name']} -<% - if lpg['unmanaged_clock']: - cg_en = 'cg_' + lpg['clock_connection'].split('clk_')[-1] - else: - cg_en = top['clocks'].hier_paths['lpg'] + lpg['clock_connection'].split('.clk_')[-1] +<% + cg_en = lib.get_clock_lpg_path(top, lpg['clock_connection'], lpg['unmanaged_clock']) rst_en = lib.get_reset_lpg_path(top, lpg['reset_connection'], False, None, lpg['unmanaged_reset']) known_clocks[cg_en] = 0 known_resets[rst_en] = 0 @@ -445,7 +442,7 @@ for rst in output_rsts: % for k, lpg in enumerate(lpgs): // ${lpg['name']} <% - cg_en = top['clocks'].hier_paths['lpg'] + lpg['clock_connection'].split('.clk_')[-1] + cg_en = lib.get_clock_lpg_path(top, lpg['clock_connection'], lpg['unmanaged_clock']) rst_en = lib.get_reset_lpg_path(top, lpg['reset_connection'], False, None, lpg['unmanaged_reset']) known_clocks[cg_en] = 0 known_resets[rst_en] = 0 diff --git a/util/topgen/clocks.py b/util/topgen/clocks.py index 73d736b9f921e..01ce81c589055 100644 --- a/util/topgen/clocks.py +++ b/util/topgen/clocks.py @@ -39,11 +39,13 @@ class UnmanagedClock: def __init__(self, raw: Dict[str, object]): self.name = str(raw['name']) self.signal_name = f'clk_{self.name}_i' + self.cg_en_signal = f'cg_en_{self.name}_i' def _asdict(self) -> Dict[str, object]: return { 'name': self.name, - 'signal_name': self.signal_name + 'signal_name': self.signal_name, + 'cg_en_signal': self.cg_en_signal } @@ -225,6 +227,12 @@ def __init__(self, raw: List[object]): def _asdict(self) -> Dict[str, object]: return self.clks + def get_clock_by_signal_name(self, signal_name: str) -> UnmanagedClock: + for clock in self.clks.values(): + if clock.signal_name == signal_name: + return clock + raise ValueError(f"No clock defined with signal name {signal_name}") from None + class Clocks: '''Clock connections for the chip.''' diff --git a/util/topgen/lib.py b/util/topgen/lib.py index 4cecdd88a8ce5..76434e0f2fa87 100644 --- a/util/topgen/lib.py +++ b/util/topgen/lib.py @@ -586,6 +586,16 @@ def shadow_name(name: str) -> str: return 'rst_shadowed_ni' +def get_clock_lpg_path(top: object, clk_name: str, unmanaged_clock: bool = False): + """Return the appropriate LPG clock path given name + """ + if unmanaged_clock: + return top['unmanaged_clocks'].get_clock_by_signal_name(clk_name).cg_en_signal + else: + clk_name = clk_name.split('clk_')[-1] + return top['clocks'].hier_paths['lpg'] + clk_name + + def get_reset_path(top: object, reset: Union[str, object], shadow_sel: bool = False, unmanaged_reset: bool = False): """Return the appropriate reset path given name