Skip to content

Commit

Permalink
[topgen] Support for unmanaged external clocks
Browse files Browse the repository at this point in the history
Signed-off-by: Robert Schilling <[email protected]>
  • Loading branch information
Razer6 authored and andreaskurth committed Nov 19, 2024
1 parent 77c14f7 commit 4ab9c0e
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 46 deletions.
13 changes: 12 additions & 1 deletion hw/top_darjeeling/templates/toplevel.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,14 @@ module top_${top["name"]} #(
% for clk in top['clocks'].typed_clocks().ast_clks:
input ${clk},
% endfor
% if len(top['unmanaged_clocks']._asdict().values()) > 0:

// 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,
% endfor
% endif

// All clocks forwarded to ast
output clkmgr_pkg::clkmgr_out_t clks_ast_o,
Expand Down Expand Up @@ -376,7 +384,10 @@ for rst in output_rsts:
% for k, lpg in enumerate(top['alert_lpgs']):
// ${lpg['name']}
<%
cg_en = top['clocks'].hier_paths['lpg'] + lpg['clock_connection'].split('.clk_')[-1]
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]
rst_en = lib.get_reset_lpg_path(top, lpg['reset_connection'])
known_clocks[cg_en] = 0
known_resets[rst_en] = 0
Expand Down
25 changes: 25 additions & 0 deletions hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
default: "0"
wait_for_external_reset: false
}
unmanaged_clocks: {}
clocks:
{
hier_paths:
Expand Down Expand Up @@ -16273,6 +16274,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
unmanaged_clock: false
reset_connection:
{
name: lc_io_div4
Expand All @@ -16297,6 +16299,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
unmanaged_clock: false
reset_connection:
{
name: spi_device
Expand All @@ -16321,6 +16324,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
unmanaged_clock: false
reset_connection:
{
name: i2c0
Expand All @@ -16345,6 +16349,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
unmanaged_clock: false
reset_connection:
{
name: i2c1
Expand All @@ -16369,6 +16374,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
unmanaged_clock: false
reset_connection:
{
name: i2c2
Expand All @@ -16390,6 +16396,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_timers
unmanaged_clock: false
reset_connection:
{
name: lc_io_div4
Expand All @@ -16412,6 +16419,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_secure
unmanaged_clock: false
reset_connection:
{
name: lc_io_div4
Expand All @@ -16436,6 +16444,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_peri
unmanaged_clock: false
reset_connection:
{
name: spi_host0
Expand All @@ -16460,6 +16469,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div2_peri
unmanaged_clock: false
reset_connection:
{
name: spi_host1
Expand All @@ -16484,6 +16494,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_usb_peri
unmanaged_clock: false
reset_connection:
{
name: usb
Expand All @@ -16509,6 +16520,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_powerup
unmanaged_clock: false
reset_connection:
{
name: por_io_div4
Expand All @@ -16534,6 +16546,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_powerup
unmanaged_clock: false
reset_connection:
{
name: lc_io_div4
Expand All @@ -16556,6 +16569,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_secure
unmanaged_clock: false
reset_connection:
{
name: lc_io_div4
Expand All @@ -16580,6 +16594,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
unmanaged_clock: false
reset_connection:
{
name: lc_io_div4
Expand All @@ -16601,6 +16616,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_timers
unmanaged_clock: false
reset_connection:
{
name: lc_io_div4
Expand All @@ -16625,6 +16641,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_infra
unmanaged_clock: false
reset_connection:
{
name: lc_io_div4
Expand All @@ -16649,6 +16666,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_io_div4_infra
unmanaged_clock: false
reset_connection:
{
name: lc_io_div4
Expand All @@ -16673,6 +16691,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_main_infra
unmanaged_clock: false
reset_connection:
{
name: lc
Expand All @@ -16697,6 +16716,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_main_infra
unmanaged_clock: false
reset_connection:
{
name: sys
Expand All @@ -16719,6 +16739,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_main_secure
unmanaged_clock: false
reset_connection:
{
name: lc
Expand All @@ -16742,6 +16763,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_main_aes
unmanaged_clock: false
reset_connection:
{
name: lc
Expand All @@ -16765,6 +16787,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_main_hmac
unmanaged_clock: false
reset_connection:
{
name: lc
Expand All @@ -16788,6 +16811,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_main_kmac
unmanaged_clock: false
reset_connection:
{
name: lc
Expand All @@ -16811,6 +16835,7 @@
}
}
clock_connection: clkmgr_aon_clocks.clk_main_otbn
unmanaged_clock: false
reset_connection:
{
name: lc
Expand Down
5 changes: 5 additions & 0 deletions hw/top_earlgrey/data/top_earlgrey.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
wait_for_external_reset: false
},

// List of unmanaged external clocks
unmanaged_clocks: [
// { name: "my_ext" }
]

// This is the clock data structure of the design.
// The hier path refers to the clock reference path (struct / port)
// - The top/ext designation follows the same scheme as inter-module
Expand Down
13 changes: 12 additions & 1 deletion hw/top_earlgrey/templates/toplevel.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,14 @@ module top_${top["name"]} #(
// All clocks forwarded to ast
output clkmgr_pkg::clkmgr_out_t clks_ast_o,
output rstmgr_pkg::rstmgr_out_t rsts_ast_o,
% if len(top['unmanaged_clocks']._asdict().values()) > 0:

// 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,
% endfor
% endif

input scan_rst_ni, // reset used for test mode
input scan_en_i,
Expand Down Expand Up @@ -394,7 +402,10 @@ for rst in output_rsts:
% for k, lpg in enumerate(top['alert_lpgs']):
// ${lpg['name']}
<%
cg_en = top['clocks'].hier_paths['lpg'] + lpg['clock_connection'].split('.clk_')[-1]
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]
rst_en = lib.get_reset_lpg_path(top, lpg['reset_connection'])
known_clocks[cg_en] = 0
known_resets[rst_en] = 0
Expand Down
5 changes: 5 additions & 0 deletions hw/top_englishbreakfast/data/top_englishbreakfast.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@
wait_for_external_reset: false
},

// List of unmanaged external clocks
unmanaged_clocks: [
// { name: "my_ext" }
]

// This is the clock data structure of the design.
// The hier path refers to the clock reference path (struct / port)
// - The top/ext desgination follows the same scheme as inter-module
Expand Down
3 changes: 2 additions & 1 deletion util/topgen.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
from topgen import lib as lib
from topgen import merge_top, search_ips, secure_prng, validate_top
from topgen.c_test import TopGenCTest
from topgen.clocks import Clocks, ClockSignal
from topgen.clocks import Clocks, ClockSignal, UnmanagedClocks
from topgen.gen_dv import gen_dv
from topgen.gen_top_docs import gen_top_docs
from topgen.merge import connect_clocks, create_alert_lpgs, extract_clocks
Expand Down Expand Up @@ -654,6 +654,7 @@ def _process_top(
# ip.hjson information. All the information is embedded within
# the top hjson file
topcfg["clocks"] = Clocks(topcfg["clocks"])
topcfg['unmanaged_clocks'] = UnmanagedClocks(topcfg['unmanaged_clocks'])
extract_clocks(topcfg)
generate_clkmgr(topcfg, out_path)

Expand Down
26 changes: 25 additions & 1 deletion util/topgen/clocks.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,20 @@ def _check_choices(val: str, what: str, choices: List[str]) -> str:
f'{what} is {val!r}, which is none of the expected values: {choices}.')


class UnmanagedClock:
'''An unmanaged clock (input to the top-level).'''

def __init__(self, raw: Dict[str, object]):
self.name = str(raw['name'])
self.signal_name = f'clk_{self.name}_i'

def _asdict(self) -> Dict[str, object]:
return {
'name': self.name,
'signal_name': self.signal_name
}


class SourceClock:
'''A clock source (input to the top-level).'''

Expand Down Expand Up @@ -73,7 +87,7 @@ class ClockSignal:
def __init__(self, name: str, src: SourceClock):
self.name = name
self.src = src
self.endpoints = [] # type: List[Tuple[str, str]]
self.endpoints: List[Tuple[str, str]] = []

def add_endpoint(self, ep_name: str, ep_port: str) -> None:
self.endpoints.append((ep_name, ep_port))
Expand Down Expand Up @@ -202,6 +216,16 @@ def hint_names(self) -> Dict[str, str]:
return hint_names


class UnmanagedClocks:
'''Unmanaged clock connections for the chip.'''

def __init__(self, raw: List[object]):
self.clks = {clk['name']: UnmanagedClock(clk) for clk in raw}

def _asdict(self) -> Dict[str, object]:
return self.clks


class Clocks:
'''Clock connections for the chip.'''

Expand Down
Loading

0 comments on commit 4ab9c0e

Please sign in to comment.