[reggen] Pair up clock and reset signals
This commit doesn't really change anything of note (indeed, there are
no changes to the auto-generated SystemVerilog code!), but it changes
the reggen hjson schema so that clocks and resets that belong together
get bundled together.
The idea is that a followup can define idle signals for "hint" clocks
by adding them to the ClockingItems. This is much nicer than depending
on order (it avoids counting, plus not every clock is a "hint" clock,
so not every clock needs an idle signal).
Signed-off-by: Rupert Swarbrick <rswarbrick@lowrisc.org>
diff --git a/doc/rm/comportability_specification/index.md b/doc/rm/comportability_specification/index.md
index 61817a7..c9b315c 100644
--- a/doc/rm/comportability_specification/index.md
+++ b/doc/rm/comportability_specification/index.md
@@ -131,22 +131,26 @@
### Clocking
-Each peripheral must define at least one clock: the primary clock.
-This is defined as `clock_primary` in the configuration file, and must be equal to one of the known clock names.
-This primary clock is defined as the one used to clock any device interfaces, indicating to the top level if asynchronous handling of the bus interface is needed.
+Each peripheral specifies how it is clocked and reset.
+This is done with the `clocking` element, whose value is a nonempty list of dictionaries.
+Each dictionary (called a *clocking item*) defines a clock and reset signal.
+The clock signal is the field called `clock`.
+The reset signal is the field called `reset`.
-Optionally the peripheral can request other clocks that it needs for internal use.
-These would create asynchronous clock domains within the IP that are handled by the design.
-They are defined under `other_clock_list` in the configuration file.
+One of the clocking items is called the *primary clock*.
+If there is just one item, that is the primary clock.
+If there are several, exactly one of the items' dictionaries should also have a boolean field called `primary` set to true.
+This primary clock used to clock any device interfaces, indicating to the top level if asynchronous handling of the bus interface is needed.
-### Reset
-
-At this time, no additional information is required to indicate the reset scheme for the peripheral IP.
-It is assumed that each clock comes with its related reset pins targeted for that clock domain.
Resets within the design are **asynchronous active low** (see below).
Special care will be required for security sensitive storage elements.
Further instructions on the handling of these storage elements will come at a later date.
+For most blocks, each clocking item has one clock and one reset signal.
+However, there are a few blocks where this might not be true (blocks that generate clocks or resets).
+To allow these blocks to be described, the `clock` and `reset` fields of an item are optional.
+However, the primary clock must have both.
+
#### Details and rationale for asynchronous active low reset strategy
Resets within the design are asynchronous active low, where the assertion of the reset is asynchronous to any clock, but deassertion is synchronized to the clock of the associated storage element.
@@ -264,8 +268,11 @@
```hjson
{
name: "uart",
- clock_primary: "clk_fixed", // optional; default "clk"
- other_clock_list: [ "clk", "clk_lowpower" ], // optional; default []
+ clocking: [
+ {clock: "clk_fixed", reset: "rst_fixed_n", primary: true},
+ {clock: "clk", reset: "rst_n"},
+ {clock: "clk_lowpower", reset: "rst_lowpower_n"}
+ ],
bus_interfaces: [
{ protocol: "tlul", direction: "device", name: "regs" }
],
diff --git a/hw/ip/adc_ctrl/data/adc_ctrl.hjson b/hw/ip/adc_ctrl/data/adc_ctrl.hjson
index 1f686fe..98a2c81 100644
--- a/hw/ip/adc_ctrl/data/adc_ctrl.hjson
+++ b/hw/ip/adc_ctrl/data/adc_ctrl.hjson
@@ -2,14 +2,10 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "adc_ctrl",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_aon_i",
- ],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_slow_ni",
- ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_aon_i", reset: "rst_slow_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/aes/data/aes.hjson b/hw/ip/aes/data/aes.hjson
index e215334..39ddbe7 100644
--- a/hw/ip/aes/data/aes.hjson
+++ b/hw/ip/aes/data/aes.hjson
@@ -5,13 +5,9 @@
# AES register template
{
name: "aes",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_edn_i"
- ],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_edn_ni"
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_edn_i", reset: "rst_edn_ni"}
]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
diff --git a/hw/ip/alert_handler/data/alert_handler.hjson b/hw/ip/alert_handler/data/alert_handler.hjson
index 7a65774..c7e116c 100644
--- a/hw/ip/alert_handler/data/alert_handler.hjson
+++ b/hw/ip/alert_handler/data/alert_handler.hjson
@@ -13,10 +13,10 @@
{
name: "ALERT_HANDLER",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_edn_i" ],
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_edn_ni" ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_edn_i", reset: "rst_edn_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/alert_handler/data/alert_handler.hjson.tpl b/hw/ip/alert_handler/data/alert_handler.hjson.tpl
index 94aeb85..df0d07d 100644
--- a/hw/ip/alert_handler/data/alert_handler.hjson.tpl
+++ b/hw/ip/alert_handler/data/alert_handler.hjson.tpl
@@ -16,10 +16,10 @@
%>
{
name: "ALERT_HANDLER",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_edn_i" ],
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_edn_ni" ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_edn_i", reset: "rst_edn_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/aon_timer/data/aon_timer.hjson b/hw/ip/aon_timer/data/aon_timer.hjson
index 87a62dc..50b124d 100644
--- a/hw/ip/aon_timer/data/aon_timer.hjson
+++ b/hw/ip/aon_timer/data/aon_timer.hjson
@@ -4,15 +4,10 @@
//
{
name: "aon_timer",
- clock_primary: "clk_i",
- reset_primary: "rst_ni",
- other_clock_list: [
- "clk_aon_i"
- ],
- other_reset_list:
- [
- "rst_aon_ni"
- ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_aon_i", reset: "rst_aon_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/clkmgr/data/clkmgr.hjson b/hw/ip/clkmgr/data/clkmgr.hjson
index 589375a..14cf745 100644
--- a/hw/ip/clkmgr/data/clkmgr.hjson
+++ b/hw/ip/clkmgr/data/clkmgr.hjson
@@ -10,18 +10,7 @@
#
{
name: "CLKMGR",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_main_i",
- "clk_fixed_i",
- "clk_usb_48mhz_i",
- ],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_main_ni"
- "rst_fixed_ni"
- "rst_usb_48mhz_ni"
- ]
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/clkmgr/data/clkmgr.hjson.tpl b/hw/ip/clkmgr/data/clkmgr.hjson.tpl
index fb818ee..6ffad60 100644
--- a/hw/ip/clkmgr/data/clkmgr.hjson.tpl
+++ b/hw/ip/clkmgr/data/clkmgr.hjson.tpl
@@ -16,17 +16,15 @@
{
name: "CLKMGR",
scan: "true",
- clock_primary: "clk_i",
- other_clock_list: [],
- reset_primary: "rst_ni",
- other_reset_list: [
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
% for src in srcs:
% if src['aon'] == 'no':
- "rst_${src['name']}_ni"
+ {reset: "rst_${src['name']}_ni"},
% endif
% endfor
% for src in div_srcs:
- "rst_${src['name']}_ni"
+ {reset: "rst_${src['name']}_ni"},
% endfor
]
bus_interfaces: [
diff --git a/hw/ip/csrng/data/csrng.hjson b/hw/ip/csrng/data/csrng.hjson
index 2cb30ac..c0751f5 100644
--- a/hw/ip/csrng/data/csrng.hjson
+++ b/hw/ip/csrng/data/csrng.hjson
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "csrng",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/edn/data/edn.hjson b/hw/ip/edn/data/edn.hjson
index 4ab287e..4be6b74 100644
--- a/hw/ip/edn/data/edn.hjson
+++ b/hw/ip/edn/data/edn.hjson
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "edn",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/entropy_src/data/entropy_src.hjson b/hw/ip/entropy_src/data/entropy_src.hjson
index cfbccde..9933e37 100644
--- a/hw/ip/entropy_src/data/entropy_src.hjson
+++ b/hw/ip/entropy_src/data/entropy_src.hjson
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "entropy_src",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/flash_ctrl/data/flash_ctrl.hjson b/hw/ip/flash_ctrl/data/flash_ctrl.hjson
index 7714bc6..5a75fac 100644
--- a/hw/ip/flash_ctrl/data/flash_ctrl.hjson
+++ b/hw/ip/flash_ctrl/data/flash_ctrl.hjson
@@ -5,10 +5,10 @@
{ name: "FLASH_CTRL",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_otp_i" ],
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_otp_ni" ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_otp_i", reset: "rst_otp_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device", name: "core" }
{ protocol: "tlul", direction: "device", name: "prim" }
diff --git a/hw/ip/flash_ctrl/data/flash_ctrl.hjson.tpl b/hw/ip/flash_ctrl/data/flash_ctrl.hjson.tpl
index 1f2d471..57f9728 100644
--- a/hw/ip/flash_ctrl/data/flash_ctrl.hjson.tpl
+++ b/hw/ip/flash_ctrl/data/flash_ctrl.hjson.tpl
@@ -12,10 +12,10 @@
%>
{ name: "FLASH_CTRL",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_otp_i" ],
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_otp_ni" ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_otp_i", reset: "rst_otp_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device", name: "core" }
{ protocol: "tlul", direction: "device", name: "prim" }
diff --git a/hw/ip/gpio/data/gpio.hjson b/hw/ip/gpio/data/gpio.hjson
index c8f39fe..ad5b78e 100644
--- a/hw/ip/gpio/data/gpio.hjson
+++ b/hw/ip/gpio/data/gpio.hjson
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
{
name: "gpio",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/hmac/data/hmac.hjson b/hw/ip/hmac/data/hmac.hjson
index 2310701..dc77a53 100644
--- a/hw/ip/hmac/data/hmac.hjson
+++ b/hw/ip/hmac/data/hmac.hjson
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "hmac",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/i2c/data/i2c.hjson b/hw/ip/i2c/data/i2c.hjson
index a86f890..84eecc9 100644
--- a/hw/ip/i2c/data/i2c.hjson
+++ b/hw/ip/i2c/data/i2c.hjson
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
{ name: "i2c"
- clock_primary: "clk_i"
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/keymgr/data/keymgr.hjson b/hw/ip/keymgr/data/keymgr.hjson
index b2546a6..688ddc3 100644
--- a/hw/ip/keymgr/data/keymgr.hjson
+++ b/hw/ip/keymgr/data/keymgr.hjson
@@ -2,10 +2,10 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "KEYMGR",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_edn_i" ]
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_edn_ni" ]
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_edn_i", reset: "rst_edn_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/kmac/data/kmac.hjson b/hw/ip/kmac/data/kmac.hjson
index 5cad80b..58182ec 100644
--- a/hw/ip/kmac/data/kmac.hjson
+++ b/hw/ip/kmac/data/kmac.hjson
@@ -3,10 +3,10 @@
// SPDX-License-Identifier: Apache-2.0
{ name: "kmac"
- clock_primary: "clk_i"
- other_clock_list: [ "clk_edn_i" ]
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_edn_ni" ]
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_edn_i", reset: "rst_edn_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/lc_ctrl/data/lc_ctrl.hjson b/hw/ip/lc_ctrl/data/lc_ctrl.hjson
index db8a08d..d03547e 100644
--- a/hw/ip/lc_ctrl/data/lc_ctrl.hjson
+++ b/hw/ip/lc_ctrl/data/lc_ctrl.hjson
@@ -2,13 +2,9 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "lc_ctrl",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_kmac_i"
- ],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_kmac_ni"
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_kmac_i", reset: "rst_kmac_ni"}
]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
diff --git a/hw/ip/nmi_gen/data/nmi_gen.hjson b/hw/ip/nmi_gen/data/nmi_gen.hjson
index 0254c35..63b3e2c 100644
--- a/hw/ip/nmi_gen/data/nmi_gen.hjson
+++ b/hw/ip/nmi_gen/data/nmi_gen.hjson
@@ -5,7 +5,7 @@
# NMI_GEN register template
{
name: "NMI_GEN",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/otbn/data/otbn.hjson b/hw/ip/otbn/data/otbn.hjson
index f786869..44dfeda 100644
--- a/hw/ip/otbn/data/otbn.hjson
+++ b/hw/ip/otbn/data/otbn.hjson
@@ -2,16 +2,11 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "otbn"
- clock_primary: "clk_i"
- other_clock_list: [
- "clk_edn_i",
- "clk_otp_i"
- ],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_edn_ni",
- "rst_otp_ni"
- ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_edn_i", reset: "rst_edn_ni"},
+ {clock: "clk_otp_i", reset: "rst_otp_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/otp_ctrl/data/otp_ctrl.hjson b/hw/ip/otp_ctrl/data/otp_ctrl.hjson
index 49fb84d..41f59c1 100644
--- a/hw/ip/otp_ctrl/data/otp_ctrl.hjson
+++ b/hw/ip/otp_ctrl/data/otp_ctrl.hjson
@@ -9,13 +9,9 @@
{ name: "otp_ctrl",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_edn_i"
- ],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_edn_ni"
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_edn_i", reset: "rst_edn_ni"}
]
scan: "true", // Enable `scanmode_i` port
scan_reset: "true", // Enable `scan_rst_ni` port
diff --git a/hw/ip/otp_ctrl/data/otp_ctrl.hjson.tpl b/hw/ip/otp_ctrl/data/otp_ctrl.hjson.tpl
index e62947f..05ad9c7 100644
--- a/hw/ip/otp_ctrl/data/otp_ctrl.hjson.tpl
+++ b/hw/ip/otp_ctrl/data/otp_ctrl.hjson.tpl
@@ -22,13 +22,9 @@
return oup
%>
{ name: "otp_ctrl",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_edn_i"
- ],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_edn_ni"
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_edn_i", reset: "rst_edn_ni"}
]
scan: "true", // Enable `scanmode_i` port
scan_reset: "true", // Enable `scan_rst_ni` port
diff --git a/hw/ip/pattgen/data/pattgen.hjson b/hw/ip/pattgen/data/pattgen.hjson
index aab4123..2a671e2 100644
--- a/hw/ip/pattgen/data/pattgen.hjson
+++ b/hw/ip/pattgen/data/pattgen.hjson
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
{ name: "pattgen",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/pinmux/data/pinmux.hjson b/hw/ip/pinmux/data/pinmux.hjson
index 2d096b7..56135c2 100644
--- a/hw/ip/pinmux/data/pinmux.hjson
+++ b/hw/ip/pinmux/data/pinmux.hjson
@@ -4,15 +4,10 @@
//
{
name: "PINMUX",
- clock_primary: "clk_i",
- reset_primary: "rst_ni",
- other_clock_list: [
- "clk_aon_i",
- ],
- other_reset_list:
- [
- "rst_aon_ni"
- ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_aon_i", reset: "rst_aon_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/pinmux/data/pinmux.hjson.tpl b/hw/ip/pinmux/data/pinmux.hjson.tpl
index fa47788..6c133f4 100644
--- a/hw/ip/pinmux/data/pinmux.hjson.tpl
+++ b/hw/ip/pinmux/data/pinmux.hjson.tpl
@@ -16,15 +16,10 @@
## - attr_dw: Width of wakeup counters
{
name: "PINMUX",
- clock_primary: "clk_i",
- reset_primary: "rst_ni",
- other_clock_list: [
- "clk_aon_i",
- ],
- other_reset_list:
- [
- "rst_aon_ni"
- ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_aon_i", reset: "rst_aon_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/pwm/data/pwm.hjson b/hw/ip/pwm/data/pwm.hjson
index 347352f..906fb22 100644
--- a/hw/ip/pwm/data/pwm.hjson
+++ b/hw/ip/pwm/data/pwm.hjson
@@ -2,10 +2,10 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "pwm",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_core_i" ],
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_core_ni" ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_core_i", reset: "rst_core_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/pwrmgr/data/pwrmgr.hjson b/hw/ip/pwrmgr/data/pwrmgr.hjson
index 396568c..1a1df3b 100644
--- a/hw/ip/pwrmgr/data/pwrmgr.hjson
+++ b/hw/ip/pwrmgr/data/pwrmgr.hjson
@@ -8,10 +8,10 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "PWRMGR",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_slow_i" ]
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_slow_ni" ]
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_slow_i", reset: "rst_slow_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl b/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl
index 1eca205..5285d4e 100644
--- a/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl
+++ b/hw/ip/pwrmgr/data/pwrmgr.hjson.tpl
@@ -2,10 +2,10 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "PWRMGR",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_slow_i" ]
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_slow_ni" ]
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_slow_i", reset: "rst_slow_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/rom_ctrl/data/rom_ctrl.hjson b/hw/ip/rom_ctrl/data/rom_ctrl.hjson
index ab50fdf..17a82a7 100644
--- a/hw/ip/rom_ctrl/data/rom_ctrl.hjson
+++ b/hw/ip/rom_ctrl/data/rom_ctrl.hjson
@@ -3,8 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
{
name: "rom_ctrl"
- clock_primary: "clk_i"
- reset_primary: "rst_ni",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
regwidth: "32"
bus_interfaces: [
{ protocol: "tlul", direction: "device", name: "regs" }
diff --git a/hw/ip/rstmgr/data/rstmgr.hjson b/hw/ip/rstmgr/data/rstmgr.hjson
index 98478e1..f2d33fa 100644
--- a/hw/ip/rstmgr/data/rstmgr.hjson
+++ b/hw/ip/rstmgr/data/rstmgr.hjson
@@ -8,15 +8,15 @@
#
{
name: "RSTMGR",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_aon_i"
- "clk_io_div4_i"
- "clk_main_i"
- "clk_io_i"
- "clk_io_div2_i"
- "clk_usb_i"
- ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_aon_i"}
+ {clock: "clk_io_div4_i"}
+ {clock: "clk_main_i"}
+ {clock: "clk_io_i"}
+ {clock: "clk_io_div2_i"}
+ {clock: "clk_usb_i"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/rstmgr/data/rstmgr.hjson.tpl b/hw/ip/rstmgr/data/rstmgr.hjson.tpl
index 6a65bf3..e9cdbde 100644
--- a/hw/ip/rstmgr/data/rstmgr.hjson.tpl
+++ b/hw/ip/rstmgr/data/rstmgr.hjson.tpl
@@ -10,12 +10,12 @@
#
{
name: "RSTMGR",
- clock_primary: "clk_i",
- other_clock_list: [
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
% for clk in clks:
- "clk_${clk}_i"
+ {clock: "clk_${clk}_i"}
% endfor
- ],
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/rv_core_ibex_peri/data/rv_core_ibex_peri.hjson b/hw/ip/rv_core_ibex_peri/data/rv_core_ibex_peri.hjson
index 4c5d0e2..426e7c6 100644
--- a/hw/ip/rv_core_ibex_peri/data/rv_core_ibex_peri.hjson
+++ b/hw/ip/rv_core_ibex_peri/data/rv_core_ibex_peri.hjson
@@ -2,10 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "RV_CORE_IBEX_PERI",
- clock_primary: "clk_i",
- other_clock_list: [ ]
- reset_primary: "rst_ni",
- other_reset_list: [ ]
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/rv_plic/data/rv_plic.hjson b/hw/ip/rv_plic/data/rv_plic.hjson
index fb4528a..e35d6dd 100644
--- a/hw/ip/rv_plic/data/rv_plic.hjson
+++ b/hw/ip/rv_plic/data/rv_plic.hjson
@@ -10,7 +10,7 @@
# - prio: Max value of interrupt priorities
{
name: "RV_PLIC",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/rv_plic/data/rv_plic.hjson.tpl b/hw/ip/rv_plic/data/rv_plic.hjson.tpl
index 9648015..b8272f1 100644
--- a/hw/ip/rv_plic/data/rv_plic.hjson.tpl
+++ b/hw/ip/rv_plic/data/rv_plic.hjson.tpl
@@ -11,7 +11,7 @@
# - prio: Max value of interrupt priorities
{
name: "RV_PLIC",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/rv_timer/data/rv_timer.hjson b/hw/ip/rv_timer/data/rv_timer.hjson
index 8a41a68..17410b4 100644
--- a/hw/ip/rv_timer/data/rv_timer.hjson
+++ b/hw/ip/rv_timer/data/rv_timer.hjson
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
//
{ name: "rv_timer",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/rv_timer/data/rv_timer.hjson.tpl b/hw/ip/rv_timer/data/rv_timer.hjson.tpl
index 9510f1e..8b2a7eb 100644
--- a/hw/ip/rv_timer/data/rv_timer.hjson.tpl
+++ b/hw/ip/rv_timer/data/rv_timer.hjson.tpl
@@ -6,7 +6,7 @@
## - harts: number of HART in timer module
## - timers: number of timers in each hart
{ name: "rv_timer",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/spi_device/data/spi_device.hjson b/hw/ip/spi_device/data/spi_device.hjson
index 7df5bae..d598b81 100644
--- a/hw/ip/spi_device/data/spi_device.hjson
+++ b/hw/ip/spi_device/data/spi_device.hjson
@@ -2,10 +2,12 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "SPI_DEVICE",
- clock_primary: "clk_i",
- other_clock_list: [
- "scan_clk_i"
- ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ // The scan_rst_ni port isn't listed here because it's generated by the
+ // "scan_reset: true" below.
+ {clock: "scan_clk_i"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/spi_host/data/spi_host.hjson b/hw/ip/spi_host/data/spi_host.hjson
index a6959cc..c77daa3 100644
--- a/hw/ip/spi_host/data/spi_host.hjson
+++ b/hw/ip/spi_host/data/spi_host.hjson
@@ -2,10 +2,10 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "spi_host",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_core_i" ],
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_core_ni" ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_core_i", reset: "rst_core_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/sram_ctrl/data/sram_ctrl.hjson b/hw/ip/sram_ctrl/data/sram_ctrl.hjson
index 233104a..3f8269e 100644
--- a/hw/ip/sram_ctrl/data/sram_ctrl.hjson
+++ b/hw/ip/sram_ctrl/data/sram_ctrl.hjson
@@ -2,13 +2,9 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "sram_ctrl",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_otp_i", // OTP clock
- ],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_otp_ni" // OTP reset
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_otp_i", reset: "rst_otp_ni"}
]
bus_interfaces: [
diff --git a/hw/ip/sysrst_ctrl/data/sysrst_ctrl.hjson b/hw/ip/sysrst_ctrl/data/sysrst_ctrl.hjson
index 4d1eb9c..0bc179b 100644
--- a/hw/ip/sysrst_ctrl/data/sysrst_ctrl.hjson
+++ b/hw/ip/sysrst_ctrl/data/sysrst_ctrl.hjson
@@ -2,17 +2,13 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "sysrst_ctrl",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_aon_i"
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_aon_i", reset: "rst_aon_ni"}
]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_aon_ni"
- ],
interrupt_list: [
{ name: "sysrst_ctrl",
desc: "common interrupt triggered by combo or keyboard actions",
diff --git a/hw/ip/trial1/data/trial1.hjson b/hw/ip/trial1/data/trial1.hjson
index 70b830f..4b7697e 100644
--- a/hw/ip/trial1/data/trial1.hjson
+++ b/hw/ip/trial1/data/trial1.hjson
@@ -3,7 +3,7 @@
// SPDX-License-Identifier: Apache-2.0
{ name: "TRIAL1",
regwidth: 32,
- clock_primary: "clk_fixed",
+ clocking: [{clock: "clk_fixed", reset: "rst_fixed_n"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/uart/data/uart.hjson b/hw/ip/uart/data/uart.hjson
index 53e85c0..f582382 100644
--- a/hw/ip/uart/data/uart.hjson
+++ b/hw/ip/uart/data/uart.hjson
@@ -2,7 +2,7 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "uart",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/usbdev/data/usbdev.hjson b/hw/ip/usbdev/data/usbdev.hjson
index 5461b81..5b5a5fd 100644
--- a/hw/ip/usbdev/data/usbdev.hjson
+++ b/hw/ip/usbdev/data/usbdev.hjson
@@ -2,10 +2,11 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "usbdev",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_aon_i", "clk_usb_48mhz_i" ]
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_aon_ni", "rst_usb_48mhz_ni" ]
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_aon_i", reset: "rst_aon_ni"},
+ {clock: "clk_usb_48mhz_i", reset: "rst_usb_48mhz_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/ip/usbuart/data/usbuart.hjson b/hw/ip/usbuart/data/usbuart.hjson
index 8ffa43a..54e18ed 100644
--- a/hw/ip/usbuart/data/usbuart.hjson
+++ b/hw/ip/usbuart/data/usbuart.hjson
@@ -2,8 +2,10 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "usbuart",
- clock_primary: "clk_fixed",
- other_clock_list: [ "clk_48mhz" ]
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_usb_48mhz_i", reset: "rst_usb_48mhz_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson b/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson
index 75a0c7c..3c9f12d 100644
--- a/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson
+++ b/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson
@@ -21,10 +21,10 @@
{
name: "ALERT_HANDLER",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_edn_i" ],
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_edn_ni" ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_edn_i", reset: "rst_edn_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/top_earlgrey/ip/ast/data/ast.hjson b/hw/top_earlgrey/ip/ast/data/ast.hjson
index 1cb04bb..62f6846 100644
--- a/hw/top_earlgrey/ip/ast/data/ast.hjson
+++ b/hw/top_earlgrey/ip/ast/data/ast.hjson
@@ -6,8 +6,7 @@
// *Module Description: Analog Sensors Top Registers
//#############################################################################
{ name: "ast",
- clock_primary: "clk_i",
- reset_primary: "rst_ni",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson b/hw/top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson
index f1d1da8..d0a2d86 100644
--- a/hw/top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson
+++ b/hw/top_earlgrey/ip/clkmgr/data/autogen/clkmgr.hjson
@@ -17,15 +17,13 @@
{
name: "CLKMGR",
scan: "true",
- clock_primary: "clk_i",
- other_clock_list: [],
- reset_primary: "rst_ni",
- other_reset_list: [
- "rst_main_ni"
- "rst_io_ni"
- "rst_usb_ni"
- "rst_io_div2_ni"
- "rst_io_div4_ni"
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {reset: "rst_main_ni"},
+ {reset: "rst_io_ni"},
+ {reset: "rst_usb_ni"},
+ {reset: "rst_io_div2_ni"},
+ {reset: "rst_io_div4_ni"},
]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
diff --git a/hw/top_earlgrey/ip/flash_ctrl/data/autogen/flash_ctrl.hjson b/hw/top_earlgrey/ip/flash_ctrl/data/autogen/flash_ctrl.hjson
index 4e2d75d..d377053 100644
--- a/hw/top_earlgrey/ip/flash_ctrl/data/autogen/flash_ctrl.hjson
+++ b/hw/top_earlgrey/ip/flash_ctrl/data/autogen/flash_ctrl.hjson
@@ -11,10 +11,10 @@
{ name: "FLASH_CTRL",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_otp_i" ],
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_otp_ni" ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_otp_i", reset: "rst_otp_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device", name: "core" }
{ protocol: "tlul", direction: "device", name: "prim" }
diff --git a/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson b/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson
index 236fa1d..3376298 100644
--- a/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson
+++ b/hw/top_earlgrey/ip/pinmux/data/autogen/pinmux.hjson
@@ -12,15 +12,10 @@
//
{
name: "PINMUX",
- clock_primary: "clk_i",
- reset_primary: "rst_ni",
- other_clock_list: [
- "clk_aon_i",
- ],
- other_reset_list:
- [
- "rst_aon_ni"
- ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_aon_i", reset: "rst_aon_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson b/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson
index 045a028..791be24 100644
--- a/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson
+++ b/hw/top_earlgrey/ip/pwrmgr/data/autogen/pwrmgr.hjson
@@ -8,10 +8,10 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
{ name: "PWRMGR",
- clock_primary: "clk_i",
- other_clock_list: [ "clk_slow_i" ]
- reset_primary: "rst_ni",
- other_reset_list: [ "rst_slow_ni" ]
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_slow_i", reset: "rst_slow_ni"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson b/hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson
index 2a80ccb..0ec9616 100644
--- a/hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson
+++ b/hw/top_earlgrey/ip/rstmgr/data/autogen/rstmgr.hjson
@@ -14,15 +14,15 @@
#
{
name: "RSTMGR",
- clock_primary: "clk_i",
- other_clock_list: [
- "clk_aon_i"
- "clk_io_div4_i"
- "clk_main_i"
- "clk_io_i"
- "clk_io_div2_i"
- "clk_usb_i"
- ],
+ clocking: [
+ {clock: "clk_i", reset: "rst_ni", primary: true},
+ {clock: "clk_aon_i"}
+ {clock: "clk_io_div4_i"}
+ {clock: "clk_main_i"}
+ {clock: "clk_io_i"}
+ {clock: "clk_io_div2_i"}
+ {clock: "clk_usb_i"}
+ ]
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/top_earlgrey/ip/rv_plic/data/autogen/rv_plic.hjson b/hw/top_earlgrey/ip/rv_plic/data/autogen/rv_plic.hjson
index 9703887..d4a7db8 100644
--- a/hw/top_earlgrey/ip/rv_plic/data/autogen/rv_plic.hjson
+++ b/hw/top_earlgrey/ip/rv_plic/data/autogen/rv_plic.hjson
@@ -18,7 +18,7 @@
# - prio: Max value of interrupt priorities
{
name: "RV_PLIC",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/hw/top_earlgrey/ip/sensor_ctrl/data/sensor_ctrl.hjson b/hw/top_earlgrey/ip/sensor_ctrl/data/sensor_ctrl.hjson
index b20536b..c0bbe4d 100644
--- a/hw/top_earlgrey/ip/sensor_ctrl/data/sensor_ctrl.hjson
+++ b/hw/top_earlgrey/ip/sensor_ctrl/data/sensor_ctrl.hjson
@@ -9,7 +9,7 @@
#
{
name: "SENSOR_CTRL",
- clock_primary: "clk_i",
+ clocking: [{clock: "clk_i", reset: "rst_ni"}],
bus_interfaces: [
{ protocol: "tlul", direction: "device" }
],
diff --git a/util/reggen/clocking.py b/util/reggen/clocking.py
new file mode 100644
index 0000000..4c2d31e
--- /dev/null
+++ b/util/reggen/clocking.py
@@ -0,0 +1,94 @@
+# Copyright lowRISC contributors.
+# Licensed under the Apache License, Version 2.0, see LICENSE for details.
+# SPDX-License-Identifier: Apache-2.0
+
+'''Code representing clocking or resets for an IP block'''
+
+from typing import Dict, List, Optional
+
+from .lib import check_keys, check_list, check_bool, check_optional_name
+
+
+class ClockingItem:
+ def __init__(self, clock: Optional[str], reset: Optional[str], primary: bool):
+ if primary:
+ assert clock is not None
+ assert reset is not None
+
+ self.clock = clock
+ self.reset = reset
+ self.primary = primary
+
+ @staticmethod
+ def from_raw(raw: object, only_item: bool, where: str) -> 'ClockingItem':
+ what = f'clocking item at {where}'
+ rd = check_keys(raw, what, [], ['clock', 'reset', 'primary'])
+
+ clock = check_optional_name(rd.get('clock'), 'clock field of ' + what)
+ reset = check_optional_name(rd.get('reset'), 'reset field of ' + what)
+ primary = check_bool(rd.get('primary', only_item),
+ 'primary field of ' + what)
+
+ if primary:
+ if clock is None:
+ raise ValueError('No clock signal for primary '
+ f'clocking item at {what}.')
+ if reset is None:
+ raise ValueError('No reset signal for primary '
+ f'clocking item at {what}.')
+
+ return ClockingItem(clock, reset, primary)
+
+ def _asdict(self) -> Dict[str, object]:
+ ret = {} # type: Dict[str, object]
+ if self.clock is not None:
+ ret['clock'] = self.clock,
+ if self.reset is not None:
+ ret['reset'] = self.reset
+
+ ret['primary'] = self.primary
+ return ret
+
+
+class Clocking:
+ def __init__(self, items: List[ClockingItem], primary: ClockingItem):
+ assert items
+ self.items = items
+ self.primary = primary
+
+ @staticmethod
+ def from_raw(raw: object, where: str) -> 'Clocking':
+ what = f'clocking items at {where}'
+ raw_items = check_list(raw, what)
+ if not raw_items:
+ raise ValueError(f'Empty list of clocking items at {where}.')
+
+ just_one_item = len(raw_items) == 1
+
+ items = []
+ primaries = []
+ for idx, raw_item in enumerate(raw_items):
+ item_where = f'entry {idx} of {what}'
+ item = ClockingItem.from_raw(raw_item, just_one_item, item_where)
+ if item.primary:
+ primaries.append(item)
+ items.append(item)
+
+ if len(primaries) != 1:
+ raise ValueError('There should be exactly one primary clocking '
+ f'item at {where}, but we saw {len(primaries)}.')
+
+ return Clocking(items, primaries[0])
+
+ def other_clocks(self) -> List[str]:
+ ret = []
+ for item in self.items:
+ if not item.primary and item.clock is not None:
+ ret.append(item.clock)
+ return ret
+
+ def clock_signals(self) -> List[str]:
+ return [item.clock for item in self.items if item.clock is not None]
+
+ def reset_signals(self) -> List[str]:
+ return [item.reset for item in self.items if item.reset is not None]
diff --git a/util/reggen/gen_cfg_html.py b/util/reggen/gen_cfg_html.py
index 0bb44d3..ed65fd9 100644
--- a/util/reggen/gen_cfg_html.py
+++ b/util/reggen/gen_cfg_html.py
@@ -43,11 +43,12 @@
# clocks
gen_kv(outfile,
'Primary Clock',
- '<b><code>{}</code></b>'.format(cfgs.clock_signals[0]))
- if len(cfgs.clock_signals) > 1:
- other_clocks = ['<b><code>{}</code></b>'.format(clk)
- for clk in cfgs.clock_signals[1:]]
- gen_kv(outfile, 'Other Clocks', ', '.join(other_clocks))
+ '<b><code>{}</code></b>'.format(cfgs.clocking.primary.clock))
+ other_clocks = cfgs.clocking.other_clocks()
+ if other_clocks:
+ other_clocks_str = ['<b><code>{}</code></b>'.format(clk)
+ for clk in other_clocks]
+ gen_kv(outfile, 'Other Clocks', ', '.join(other_clocks_str))
else:
gen_kv(outfile, 'Other Clocks', '<i>none</i>')
diff --git a/util/reggen/ip_block.py b/util/reggen/ip_block.py
index 197b96d..594e019 100644
--- a/util/reggen/ip_block.py
+++ b/util/reggen/ip_block.py
@@ -10,9 +10,10 @@
from .alert import Alert
from .bus_interfaces import BusInterfaces
+from .clocking import Clocking
from .inter_signal import InterSignal
from .lib import (check_keys, check_name, check_int, check_bool,
- check_list, check_optional_str, check_name_list)
+ check_list, check_optional_str)
from .params import ReggenParams, LocalParam
from .reg_block import RegBlock
from .signal import Signal
@@ -20,7 +21,7 @@
REQUIRED_FIELDS = {
'name': ['s', "name of the component"],
- 'clock_primary': ['s', "name of the primary clock"],
+ 'clocking': ['l', "clocking for the device"],
'bus_interfaces': ['l', "bus interfaces for the device"],
'registers': [
'l',
@@ -53,11 +54,8 @@
"Defaults to true if no interrupt_list is present. "
"Otherwise this defaults to false. "
],
- 'other_clock_list': ['l', "list of other chip clocks needed"],
- 'other_reset_list': ['l', "list of other resets"],
'param_list': ['lp', "list of parameters of the IP"],
'regwidth': ['d', "width of registers in bits (default 32)"],
- 'reset_primary': ['s', "primary reset used by the module"],
'reset_request_list': ['l', 'list of signals requesting reset'],
'scan': ['pb', 'Indicates the module have `scanmode_i`'],
'scan_reset': ['pb', 'Indicates the module have `scan_rst_ni`'],
@@ -86,8 +84,7 @@
inter_signals: List[InterSignal],
bus_interfaces: BusInterfaces,
hier_path: Optional[str],
- clock_signals: List[str],
- reset_signals: List[str],
+ clocking: Clocking,
xputs: Tuple[Sequence[Signal],
Sequence[Signal],
Sequence[Signal]],
@@ -97,8 +94,6 @@
scan_reset: bool,
scan_en: bool):
assert reg_blocks
- assert clock_signals
- assert reset_signals
# Check that register blocks are in bijection with device interfaces
reg_block_names = reg_blocks.keys()
@@ -120,8 +115,7 @@
self.inter_signals = inter_signals
self.bus_interfaces = bus_interfaces
self.hier_path = hier_path
- self.clock_signals = clock_signals
- self.reset_signals = reset_signals
+ self.clocking = clocking
self.xputs = xputs
self.wakeups = wakeups
self.reset_requests = reset_requests
@@ -227,17 +221,8 @@
hier_path = check_optional_str(rd.get('hier_path', None),
'hier_path field of ' + what)
- clock_primary = check_name(rd['clock_primary'],
- 'clock_primary field of ' + what)
- other_clock_list = check_name_list(rd.get('other_clock_list', []),
- 'other_clock_list field of ' + what)
- clock_signals = [clock_primary] + other_clock_list
-
- reset_primary = check_name(rd.get('reset_primary', 'rst_ni'),
- 'reset_primary field of ' + what)
- other_reset_list = check_name_list(rd.get('other_reset_list', []),
- 'other_reset_list field of ' + what)
- reset_signals = [reset_primary] + other_reset_list
+ clocking = Clocking.from_raw(rd['clocking'],
+ 'clocking field of ' + what)
xputs = (
Signal.from_raw_list('available_inout_list for block ' + name,
@@ -277,7 +262,7 @@
return IpBlock(name, regwidth, params, reg_blocks,
interrupts, no_auto_intr, alerts, no_auto_alert,
scan, inter_signals, bus_interfaces,
- hier_path, clock_signals, reset_signals, xputs,
+ hier_path, clocking, xputs,
wakeups, rst_reqs, expose_reg_if, scan_reset, scan_en)
@staticmethod
@@ -320,13 +305,7 @@
if self.hier_path is not None:
ret['hier_path'] = self.hier_path
- ret['clock_primary'] = self.clock_signals[0]
- if len(self.clock_signals) > 1:
- ret['other_clock_list'] = self.clock_signals[1:]
-
- ret['reset_primary'] = self.reset_signals[0]
- if len(self.reset_signals) > 1:
- ret['other_reset_list'] = self.reset_signals[1:]
+ ret['clocking'] = self.clocking.items
inouts, inputs, outputs = self.xputs
if inouts:
diff --git a/util/reggen/lib.py b/util/reggen/lib.py
index d72ef3d..60e3e02 100644
--- a/util/reggen/lib.py
+++ b/util/reggen/lib.py
@@ -189,19 +189,6 @@
return cast(List[str], lst)
-def check_name_list(obj: object, what: str) -> List[str]:
- '''Check that the given object is a list of valid names
-
- If not, raise a ValueError; the what argument names the object.
-
- '''
- lst = check_list(obj, what)
- for idx, elt in enumerate(lst):
- check_name(elt, 'Element {} of {}'.format(idx + 1, what))
-
- return cast(List[str], lst)
-
-
def check_int(obj: object, what: str) -> int:
'''Check that obj is an integer or a string that parses to an integer.
@@ -252,6 +239,11 @@
return None if obj is None else check_str(obj, what)
+def check_optional_name(obj: object, what: str) -> Optional[str]:
+ '''Check that obj is a valid name or None'''
+ return None if obj is None else check_name(obj, what)
+
+
def get_basename(name: str) -> str:
'''Strip trailing _number (used as multireg suffix) from name'''
# TODO: This is a workaround, should solve this as part of parsing a
diff --git a/util/topgen/validate.py b/util/topgen/validate.py
index bd45d57..67a7ab0 100644
--- a/util/topgen/validate.py
+++ b/util/topgen/validate.py
@@ -691,7 +691,7 @@
# (generated by topgen for a crossbar)
if isinstance(inst, IpBlock):
name = inst.name
- reset_signals = inst.reset_signals
+ reset_signals = inst.clocking.reset_signals()
else:
name = inst['name']
reset_signals = ([inst.get('reset_primary', 'rst_ni')] +
@@ -742,7 +742,7 @@
# (generated by topgen for a crossbar)
if isinstance(inst, IpBlock):
name = inst.name
- clock_signals = inst.clock_signals
+ clock_signals = inst.clocking.clock_signals()
else:
name = inst['name']
clock_signals = ([inst.get('clock_primary', 'rst_ni')] +