[clkmgr] - Minor clock and power updates/fixes to enable integration
Signed-off-by: Timothy Chen <timothytim@google.com>
[clkmgr] - Flatten the hierarchical clock gating since this makes FPGA unhappy.
- I personally prefer hierarhical gating, but it is not absolutely critical here.
Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/clkmgr/data/clkmgr.hjson b/hw/ip/clkmgr/data/clkmgr.hjson
index f91901d..73dee81 100644
--- a/hw/ip/clkmgr/data/clkmgr.hjson
+++ b/hw/ip/clkmgr/data/clkmgr.hjson
@@ -16,6 +16,12 @@
"clk_fixed_i",
"clk_usb_48mhz_i",
],
+ reset_primary: "rst_ni",
+ other_reset_list: [
+ "rst_main_ni"
+ "rst_fixed_ni"
+ "rst_usb_48mhz_ni"
+ ]
bus_device: "tlul",
regwidth: "32",
param_list: [
@@ -36,6 +42,12 @@
package: "clkmgr_pkg",
},
+ { struct: "pwr_clk",
+ type: "req_rsp",
+ name: "pwr",
+ act: "rsp",
+ },
+
{ struct: "clk_dft",
type: "uni",
name: "dft",
diff --git a/hw/ip/clkmgr/data/clkmgr.hjson.tpl b/hw/ip/clkmgr/data/clkmgr.hjson.tpl
index 7028d6c..70af9b0 100644
--- a/hw/ip/clkmgr/data/clkmgr.hjson.tpl
+++ b/hw/ip/clkmgr/data/clkmgr.hjson.tpl
@@ -21,6 +21,12 @@
"clk_${src['name']}_i",
% endfor
],
+ reset_primary: "rst_ni",
+ other_reset_list: [
+% for src in srcs:
+ "rst_${src['name']}_ni"
+% endfor
+ ]
bus_device: "tlul",
regwidth: "32",
param_list: [
@@ -41,6 +47,12 @@
package: "clkmgr_pkg",
},
+ { struct: "pwr_clk",
+ type: "req_rsp",
+ name: "pwr",
+ act: "rsp",
+ },
+
{ struct: "clk_dft",
type: "uni",
name: "dft",
diff --git a/hw/ip/clkmgr/data/clkmgr.sv.tpl b/hw/ip/clkmgr/data/clkmgr.sv.tpl
index 5582288..0dcff9c 100644
--- a/hw/ip/clkmgr/data/clkmgr.sv.tpl
+++ b/hw/ip/clkmgr/data/clkmgr.sv.tpl
@@ -56,15 +56,6 @@
.devmode_i(1'b1)
);
- ////////////////////////////////////////////////////
- // Power up group - feedthrough
- ////////////////////////////////////////////////////
- ## This group is hardcoded right now because it is the only one.
- ## In the future if there are more, feedthrough should be converted to an attribute
-
-% for k,v in ft_clks.items():
- assign clocks_o.${k} = clk_${v}_i;
-% endfor
////////////////////////////////////////////////////
// Root gating
@@ -82,7 +73,7 @@
% endfor
% for src in srcs:
- prim_clock_gating_sync i_${src['name']}_sync (
+ prim_clock_gating_sync i_${src['name']}_cg (
.clk_i(clk_${src['name']}_i),
.rst_ni(rst_${src['name']}_ni),
.test_en_i(dft_i.test_en),
@@ -143,16 +134,27 @@
// the rst_ni connection below is incorrect, need to find a proper reset in the sequence to use
// if the clkmgr is always on, can use por synced directly
// if not, then need to generate something ahead of lc/sys
+% for k in sw_clks:
+ logic ${k}_sw_en;
+% endfor
% for k,v in sw_clks.items():
- prim_clock_gating_sync i_${k}_sync (
- .clk_i(clk_${v}_root),
+ prim_flop_2sync #(
+ .Width(1)
+ ) i_${k}_sw_en_sync (
+ .clk_i(clk_${v}_i),
.rst_ni(rst_${v}_ni),
+ .d(reg2hw.clk_enables.${k}_en.q),
+ .q(${k}_sw_en)
+ );
+
+ prim_clock_gating i_${k}_cg (
+ .clk_i(clk_${v}_i),
+ .en_i(${k}_sw_en & clk_${v}_en),
.test_en_i(dft_i.test_en),
- .async_en_i(reg2hw.clk_enables.${k}_en.q),
- .en_o(), // should this be fedback for software?
.clk_o(clocks_o.${k})
);
+
% endfor
////////////////////////////////////////////////////
@@ -176,15 +178,15 @@
prim_flop_2sync #(
.Width(1)
) i_${k}_hint_sync (
- .clk_i(clk_${v}_root),
+ .clk_i(clk_${v}_i),
.rst_ni(rst_${v}_ni),
.d(reg2hw.clk_hints.${k}_hint.q),
.q(${k}_hint)
);
- prim_clock_gating i_${k}_sync (
- .clk_i(clk_${v}_root),
- .en_i(${k}_en),
+ prim_clock_gating i_${k}_cg (
+ .clk_i(clk_${v}_i),
+ .en_i(${k}_en & clk_${v}_en),
.test_en_i(dft_i.test_en),
.clk_o(clocks_o.${k})
);
diff --git a/hw/ip/clkmgr/rtl/clkmgr.sv b/hw/ip/clkmgr/rtl/clkmgr.sv
index 0e8d705..f143e3e 100644
--- a/hw/ip/clkmgr/rtl/clkmgr.sv
+++ b/hw/ip/clkmgr/rtl/clkmgr.sv
@@ -55,13 +55,6 @@
.devmode_i(1'b1)
);
- ////////////////////////////////////////////////////
- // Power up group - feedthrough
- ////////////////////////////////////////////////////
-
- assign clocks_o.clk_fixed_powerup = clk_fixed_i;
- assign clocks_o.clk_main_powerup = clk_main_i;
- assign clocks_o.clk_usb_48mhz_powerup = clk_usb_48mhz_i;
////////////////////////////////////////////////////
// Root gating
@@ -80,7 +73,7 @@
logic clk_usb_48mhz_root;
logic clk_usb_48mhz_en;
- prim_clock_gating_sync i_main_sync (
+ prim_clock_gating_sync i_main_cg (
.clk_i(clk_main_i),
.rst_ni(rst_main_ni),
.test_en_i(dft_i.test_en),
@@ -88,7 +81,7 @@
.en_o(clk_main_en),
.clk_o(clk_main_root)
);
- prim_clock_gating_sync i_fixed_sync (
+ prim_clock_gating_sync i_fixed_cg (
.clk_i(clk_fixed_i),
.rst_ni(rst_fixed_ni),
.test_en_i(dft_i.test_en),
@@ -96,7 +89,7 @@
.en_o(clk_fixed_en),
.clk_o(clk_fixed_root)
);
- prim_clock_gating_sync i_usb_48mhz_sync (
+ prim_clock_gating_sync i_usb_48mhz_cg (
.clk_i(clk_usb_48mhz_i),
.rst_ni(rst_usb_48mhz_ni),
.test_en_i(dft_i.test_en),
@@ -155,24 +148,42 @@
// the rst_ni connection below is incorrect, need to find a proper reset in the sequence to use
// if the clkmgr is always on, can use por synced directly
// if not, then need to generate something ahead of lc/sys
+ logic clk_fixed_peri_sw_en;
+ logic clk_usb_48mhz_peri_sw_en;
- prim_clock_gating_sync i_clk_fixed_peri_sync (
- .clk_i(clk_fixed_root),
+ prim_flop_2sync #(
+ .Width(1)
+ ) i_clk_fixed_peri_sw_en_sync (
+ .clk_i(clk_fixed_i),
.rst_ni(rst_fixed_ni),
+ .d(reg2hw.clk_enables.clk_fixed_peri_en.q),
+ .q(clk_fixed_peri_sw_en)
+ );
+
+ prim_clock_gating i_clk_fixed_peri_cg (
+ .clk_i(clk_fixed_i),
+ .en_i(clk_fixed_peri_sw_en & clk_fixed_en),
.test_en_i(dft_i.test_en),
- .async_en_i(reg2hw.clk_enables.clk_fixed_peri_en.q),
- .en_o(), // should this be fedback for software?
.clk_o(clocks_o.clk_fixed_peri)
);
- prim_clock_gating_sync i_clk_usb_48mhz_peri_sync (
- .clk_i(clk_usb_48mhz_root),
+
+ prim_flop_2sync #(
+ .Width(1)
+ ) i_clk_usb_48mhz_peri_sw_en_sync (
+ .clk_i(clk_usb_48mhz_i),
.rst_ni(rst_usb_48mhz_ni),
+ .d(reg2hw.clk_enables.clk_usb_48mhz_peri_en.q),
+ .q(clk_usb_48mhz_peri_sw_en)
+ );
+
+ prim_clock_gating i_clk_usb_48mhz_peri_cg (
+ .clk_i(clk_usb_48mhz_i),
+ .en_i(clk_usb_48mhz_peri_sw_en & clk_usb_48mhz_en),
.test_en_i(dft_i.test_en),
- .async_en_i(reg2hw.clk_enables.clk_usb_48mhz_peri_en.q),
- .en_o(), // should this be fedback for software?
.clk_o(clocks_o.clk_usb_48mhz_peri)
);
+
////////////////////////////////////////////////////
// Software hint group
// The idle hint feedback is assumed to be synchronous to the
@@ -193,15 +204,15 @@
prim_flop_2sync #(
.Width(1)
) i_clk_main_aes_hint_sync (
- .clk_i(clk_main_root),
+ .clk_i(clk_main_i),
.rst_ni(rst_main_ni),
.d(reg2hw.clk_hints.clk_main_aes_hint.q),
.q(clk_main_aes_hint)
);
- prim_clock_gating i_clk_main_aes_sync (
- .clk_i(clk_main_root),
- .en_i(clk_main_aes_en),
+ prim_clock_gating i_clk_main_aes_cg (
+ .clk_i(clk_main_i),
+ .en_i(clk_main_aes_en & clk_main_en),
.test_en_i(dft_i.test_en),
.clk_o(clocks_o.clk_main_aes)
);
@@ -211,15 +222,15 @@
prim_flop_2sync #(
.Width(1)
) i_clk_main_hmac_hint_sync (
- .clk_i(clk_main_root),
+ .clk_i(clk_main_i),
.rst_ni(rst_main_ni),
.d(reg2hw.clk_hints.clk_main_hmac_hint.q),
.q(clk_main_hmac_hint)
);
- prim_clock_gating i_clk_main_hmac_sync (
- .clk_i(clk_main_root),
- .en_i(clk_main_hmac_en),
+ prim_clock_gating i_clk_main_hmac_cg (
+ .clk_i(clk_main_i),
+ .en_i(clk_main_hmac_en & clk_main_en),
.test_en_i(dft_i.test_en),
.clk_o(clocks_o.clk_main_hmac)
);
diff --git a/hw/ip/pwrmgr/data/pwrmgr.hjson b/hw/ip/pwrmgr/data/pwrmgr.hjson
index 589c07d..668e142 100644
--- a/hw/ip/pwrmgr/data/pwrmgr.hjson
+++ b/hw/ip/pwrmgr/data/pwrmgr.hjson
@@ -28,7 +28,7 @@
},
{ struct: "pwr_clk",
- type: "uni",
+ type: "req_rsp",
name: "pwr_clk",
act: "req",
package: "pwrmgr_pkg",
diff --git a/hw/ip/pwrmgr/rtl/pwrmgr.sv b/hw/ip/pwrmgr/rtl/pwrmgr.sv
index 8e0b808..2edd8e7 100644
--- a/hw/ip/pwrmgr/rtl/pwrmgr.sv
+++ b/hw/ip/pwrmgr/rtl/pwrmgr.sv
@@ -29,6 +29,7 @@
// clkmgr interface
output pwr_clk_req_t pwr_clk_o,
+ input pwr_clk_rsp_t pwr_clk_i,
// otp interface
input pwr_otp_rsp_t pwr_otp_i,