Skip to content

Commit

Permalink
[topgen] Better handling of clock-gate inputs
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 committed Nov 29, 2024
1 parent 6e2cee8 commit 3c881a2
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 18 deletions.
13 changes: 5 additions & 8 deletions hw/top_darjeeling/templates/toplevel.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
15 changes: 6 additions & 9 deletions hw/top_earlgrey/templates/toplevel.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down
10 changes: 9 additions & 1 deletion util/topgen/clocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
}


Expand Down Expand Up @@ -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.'''
Expand Down
10 changes: 10 additions & 0 deletions util/topgen/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 3c881a2

Please sign in to comment.