[util, reggen] Support standardized cdc handling for regfile
- Support two asynchronous schemes on regfile
- Fully asynchronous - a tlul_fifo_async directly instantiated in regfile
- Mixed asynchronous - allow user to selectively mark registers as async
- These two schemes are mutually exclusive
- Add an 'async' key for bus interfaces to indicate the reg block is fully asynchornous
- Add an 'async' key per register to indicate register clock domain
- Add extra clock/reset ports to reg module
- Add prim_subreg_cdc to handle regiser domain clock crossing
Signed-off-by: Timothy Chen <timothytim@google.com>
[aon_timer] Updates to aon_timer to experiment with new cdc scheme
Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/util/reggen/clocking.py b/util/reggen/clocking.py
index 41108fd..b2330c4 100644
--- a/util/reggen/clocking.py
+++ b/util/reggen/clocking.py
@@ -7,6 +7,7 @@
from typing import Dict, List, Optional
from .lib import check_keys, check_list, check_bool, check_optional_name
+import re
class ClockingItem:
@@ -14,12 +15,14 @@
clock: Optional[str],
reset: Optional[str],
idle: Optional[str],
- primary: bool):
+ primary: bool,
+ clock_base_name: Optional[str]):
if primary:
assert clock is not None
assert reset is not None
self.clock = clock
+ self.clock_base_name = clock_base_name
self.reset = reset
self.primary = primary
self.idle = idle
@@ -35,6 +38,15 @@
primary = check_bool(rd.get('primary', only_item),
'primary field of ' + what)
+ match = re.match(r'^clk_([A-Za-z0-9_]+)_i', str(clock))
+ if not clock or clock in ['clk_i', 'scan_clk_i']:
+ clock_base_name = ""
+ elif match:
+ clock_base_name = match.group(1)
+ else:
+ raise ValueError(f'clock name must be of the form clk_*_i or clk_i. '
+ f'{clock} is illegal.')
+
if primary:
if clock is None:
raise ValueError('No clock signal for primary '
@@ -43,7 +55,7 @@
raise ValueError('No reset signal for primary '
f'clocking item at {what}.')
- return ClockingItem(clock, reset, idle, primary)
+ return ClockingItem(clock, reset, idle, primary, clock_base_name)
def _asdict(self) -> Dict[str, object]:
ret = {} # type: Dict[str, object]
@@ -100,3 +112,15 @@
def reset_signals(self) -> List[str]:
return [item.reset for item in self.items if item.reset is not None]
+
+ def get_by_clock(self, name: Optional[str]) -> ClockingItem:
+ ret = None
+ for item in self.items:
+ if name == item.clock:
+ ret = item
+ break
+
+ if ret is None:
+ raise ValueError(f'The requested clock {name} does not exist.')
+ else:
+ return ret