Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 1 | // Copyright lowRISC contributors. |
| 2 | // Licensed under the Apache License, Version 2.0, see LICENSE for details. |
| 3 | // SPDX-License-Identifier: Apache-2.0 |
| 4 | // |
| 5 | // The overall clock manager |
| 6 | |
| 7 | `include "prim_assert.sv" |
| 8 | |
| 9 | <% |
| 10 | clks_attr = cfg['clocks'] |
| 11 | srcs = clks_attr['srcs'] |
| 12 | %> |
| 13 | |
| 14 | module clkmgr import clkmgr_pkg::*; ( |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 15 | // Primary module control clocks and resets |
| 16 | // This drives the register interface |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 17 | input clk_i, |
| 18 | input rst_ni, |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 19 | |
| 20 | // System clocks and resets |
| 21 | // These are the source clocks for the system |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 22 | % for src in srcs: |
| 23 | input clk_${src['name']}_i, |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 24 | % if src['aon'] == 'no': |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 25 | input rst_${src['name']}_ni, |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 26 | % endif |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 27 | % endfor |
| 28 | |
Timothy Chen | b63f3b8 | 2020-06-30 17:10:57 -0700 | [diff] [blame] | 29 | // Resets for derived clocks |
| 30 | // clocks are derived locally |
| 31 | % for src in div_srcs: |
| 32 | input rst_${src['name']}_ni, |
| 33 | % endfor |
| 34 | |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 35 | // Bus Interface |
| 36 | input tlul_pkg::tl_h2d_t tl_i, |
| 37 | output tlul_pkg::tl_d2h_t tl_o, |
| 38 | |
| 39 | // pwrmgr interface |
| 40 | input pwrmgr_pkg::pwr_clk_req_t pwr_i, |
| 41 | output pwrmgr_pkg::pwr_clk_rsp_t pwr_o, |
| 42 | |
| 43 | // dft interface |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 44 | input lc_ctrl_pkg::lc_tx_t scanmode_i, |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 45 | |
| 46 | // idle hints |
Timothy Chen | c8f3004 | 2020-09-25 16:59:47 -0700 | [diff] [blame] | 47 | input [${len(hint_clks)-1}:0] idle_i, |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 48 | |
Timothy Chen | 33c9078 | 2021-01-06 17:38:48 -0800 | [diff] [blame] | 49 | // clock bypass control |
| 50 | input lc_ctrl_pkg::lc_tx_t ast_clk_bypass_ack_i, |
| 51 | output lc_ctrl_pkg::lc_tx_t lc_clk_bypass_ack_o, |
| 52 | |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 53 | // jittery enable |
| 54 | output logic jitter_en_o, |
| 55 | |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 56 | // clock output interface |
Timothy Chen | 4c8905e | 2020-08-26 10:34:33 -0700 | [diff] [blame] | 57 | % for intf in export_clks: |
| 58 | output clkmgr_${intf}_out_t clocks_${intf}_o, |
| 59 | % endfor |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 60 | output clkmgr_out_t clocks_o |
| 61 | |
| 62 | ); |
| 63 | |
| 64 | //////////////////////////////////////////////////// |
| 65 | // Register Interface |
| 66 | //////////////////////////////////////////////////// |
| 67 | |
| 68 | clkmgr_reg_pkg::clkmgr_reg2hw_t reg2hw; |
| 69 | clkmgr_reg_pkg::clkmgr_hw2reg_t hw2reg; |
| 70 | |
Weicai Yang | 9f6311f | 2020-06-09 16:04:35 -0700 | [diff] [blame] | 71 | clkmgr_reg_top u_reg ( |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 72 | .clk_i, |
| 73 | .rst_ni, |
| 74 | .tl_i, |
| 75 | .tl_o, |
| 76 | .reg2hw, |
| 77 | .hw2reg, |
Timothy Chen | 8ec347f | 2021-03-02 11:52:17 -0800 | [diff] [blame] | 78 | .intg_err_o(), |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 79 | .devmode_i(1'b1) |
| 80 | ); |
| 81 | |
Timothy Chen | b63f3b8 | 2020-06-30 17:10:57 -0700 | [diff] [blame] | 82 | //////////////////////////////////////////////////// |
| 83 | // Divided clocks |
| 84 | //////////////////////////////////////////////////// |
Timothy Chen | 33c9078 | 2021-01-06 17:38:48 -0800 | [diff] [blame] | 85 | |
| 86 | lc_ctrl_pkg::lc_tx_t step_down_req; |
| 87 | logic [${len(div_srcs)-1}:0] step_down_acks; |
| 88 | |
| 89 | prim_lc_sync u_rcv ( |
| 90 | .clk_i, |
| 91 | .rst_ni, |
| 92 | .lc_en_i(ast_clk_bypass_ack_i), |
| 93 | .lc_en_o(step_down_req) |
| 94 | ); |
| 95 | |
Timothy Chen | b63f3b8 | 2020-06-30 17:10:57 -0700 | [diff] [blame] | 96 | % for src in div_srcs: |
| 97 | logic clk_${src['name']}_i; |
| 98 | % endfor |
| 99 | |
| 100 | % for src in div_srcs: |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 101 | |
| 102 | lc_ctrl_pkg::lc_tx_t ${src['name']}_div_scanmode; |
| 103 | prim_lc_sync #( |
| 104 | .NumCopies(1), |
| 105 | .AsyncOn(0) |
| 106 | ) u_${src['name']}_div_scanmode_sync ( |
Timothy Chen | 7a0289c | 2021-02-19 16:33:44 -0800 | [diff] [blame] | 107 | .clk_i(1'b0), //unused |
| 108 | .rst_ni(1'b1), //unused |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 109 | .lc_en_i(scanmode_i), |
| 110 | .lc_en_o(${src['name']}_div_scanmode) |
| 111 | ); |
| 112 | |
Timothy Chen | ced60b2 | 2020-08-20 10:35:00 -0700 | [diff] [blame] | 113 | prim_clock_div #( |
| 114 | .Divisor(${src['div']}) |
Timothy Chen | a1af4ec | 2021-03-05 13:57:00 -0800 | [diff] [blame^] | 115 | ) u_no_scan_${src['name']}_div ( |
Timothy Chen | ced60b2 | 2020-08-20 10:35:00 -0700 | [diff] [blame] | 116 | .clk_i(clk_${src['src']}_i), |
| 117 | .rst_ni(rst_${src['src']}_ni), |
Timothy Chen | 33c9078 | 2021-01-06 17:38:48 -0800 | [diff] [blame] | 118 | .step_down_req_i(step_down_req == lc_ctrl_pkg::On), |
| 119 | .step_down_ack_o(step_down_acks[${loop.index}]), |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 120 | .test_en_i(${src['name']}_div_scanmode == lc_ctrl_pkg::On), |
Timothy Chen | ced60b2 | 2020-08-20 10:35:00 -0700 | [diff] [blame] | 121 | .clk_o(clk_${src['name']}_i) |
| 122 | ); |
Timothy Chen | b63f3b8 | 2020-06-30 17:10:57 -0700 | [diff] [blame] | 123 | % endfor |
| 124 | |
Timothy Chen | 33c9078 | 2021-01-06 17:38:48 -0800 | [diff] [blame] | 125 | prim_lc_sender u_send ( |
| 126 | .clk_i, |
| 127 | .rst_ni, |
| 128 | .lc_en_i(&step_down_acks ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off), |
| 129 | .lc_en_o(lc_clk_bypass_ack_o) |
| 130 | ); |
Timothy Chen | b63f3b8 | 2020-06-30 17:10:57 -0700 | [diff] [blame] | 131 | |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 132 | //////////////////////////////////////////////////// |
Timothy Chen | 00cad63 | 2020-06-29 15:29:42 -0700 | [diff] [blame] | 133 | // Feed through clocks |
| 134 | // Feed through clocks do not actually need to be in clkmgr, as they are |
| 135 | // completely untouched. The only reason they are here is for easier |
| 136 | // bundling management purposes through clocks_o |
| 137 | //////////////////////////////////////////////////// |
| 138 | % for k,v in ft_clks.items(): |
Timothy Chen | 11c848e | 2020-11-03 12:03:28 -0800 | [diff] [blame] | 139 | prim_clock_buf u_${k}_buf ( |
| 140 | .clk_i(clk_${v}_i), |
| 141 | .clk_o(clocks_o.${k}) |
| 142 | ); |
Timothy Chen | 00cad63 | 2020-06-29 15:29:42 -0700 | [diff] [blame] | 143 | % endfor |
| 144 | |
Timothy Chen | 00cad63 | 2020-06-29 15:29:42 -0700 | [diff] [blame] | 145 | //////////////////////////////////////////////////// |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 146 | // Root gating |
| 147 | //////////////////////////////////////////////////// |
| 148 | |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 149 | logic wait_enable; |
| 150 | logic wait_disable; |
| 151 | logic en_status_d; |
| 152 | logic dis_status_d; |
| 153 | logic [1:0] en_status_q; |
| 154 | logic [1:0] dis_status_q; |
| 155 | logic clk_status; |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 156 | % for src in rg_srcs: |
| 157 | logic clk_${src}_root; |
| 158 | logic clk_${src}_en; |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 159 | % endfor |
| 160 | |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 161 | % for src in rg_srcs: |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 162 | lc_ctrl_pkg::lc_tx_t ${src}_scanmode; |
| 163 | prim_lc_sync #( |
| 164 | .NumCopies(1), |
| 165 | .AsyncOn(0) |
| 166 | ) u_${src}_scanmode_sync ( |
Timothy Chen | 7a0289c | 2021-02-19 16:33:44 -0800 | [diff] [blame] | 167 | .clk_i(1'b0), //unused |
| 168 | .rst_ni(1'b1), //unused |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 169 | .lc_en_i(scanmode_i), |
| 170 | .lc_en_o(${src}_scanmode) |
| 171 | ); |
| 172 | |
Timothy Chen | ced60b2 | 2020-08-20 10:35:00 -0700 | [diff] [blame] | 173 | prim_clock_gating_sync u_${src}_cg ( |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 174 | .clk_i(clk_${src}_i), |
| 175 | .rst_ni(rst_${src}_ni), |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 176 | .test_en_i(${src}_scanmode == lc_ctrl_pkg::On), |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 177 | .async_en_i(pwr_i.ip_clk_en), |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 178 | .en_o(clk_${src}_en), |
| 179 | .clk_o(clk_${src}_root) |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 180 | ); |
| 181 | % endfor |
| 182 | |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 183 | // an async AND of all the synchronized enables |
| 184 | // return feedback to pwrmgr only when all clocks are enabled |
| 185 | assign wait_enable = |
| 186 | % for src in rg_srcs: |
| 187 | % if loop.last: |
| 188 | clk_${src}_en; |
| 189 | % else: |
| 190 | clk_${src}_en & |
| 191 | % endif |
| 192 | % endfor |
| 193 | |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 194 | // an async OR of all the synchronized enables |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 195 | // return feedback to pwrmgr only when all clocks are disabled |
| 196 | assign wait_disable = |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 197 | % for src in rg_srcs: |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 198 | % if loop.last: |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 199 | clk_${src}_en; |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 200 | % else: |
Timothy Chen | 33b3b9d | 2020-05-08 10:14:17 -0700 | [diff] [blame] | 201 | clk_${src}_en | |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 202 | % endif |
| 203 | % endfor |
| 204 | |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 205 | // Sync clkmgr domain for feedback to pwrmgr. |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 206 | // Since the signal is combo / converged on the other side, de-bounce |
| 207 | // the signal prior to output |
| 208 | prim_flop_2sync #( |
| 209 | .Width(1) |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 210 | ) u_roots_en_status_sync ( |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 211 | .clk_i, |
| 212 | .rst_ni, |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 213 | .d_i(wait_enable), |
| 214 | .q_o(en_status_d) |
| 215 | ); |
| 216 | |
| 217 | prim_flop_2sync #( |
| 218 | .Width(1) |
| 219 | ) u_roots_or_sync ( |
| 220 | .clk_i, |
| 221 | .rst_ni, |
| 222 | .d_i(wait_disable), |
| 223 | .q_o(dis_status_d) |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 224 | ); |
| 225 | |
| 226 | always_ff @(posedge clk_i or negedge rst_ni) begin |
| 227 | if (!rst_ni) begin |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 228 | en_status_q <= '0; |
| 229 | dis_status_q <= '0; |
| 230 | clk_status <= '0; |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 231 | end else begin |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 232 | en_status_q <= {en_status_q[0], en_status_d}; |
| 233 | dis_status_q <= {dis_status_q[0], dis_status_d}; |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 234 | |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 235 | if (&en_status_q) begin |
| 236 | clk_status <= 1'b1; |
| 237 | end else if (|dis_status_q == '0) begin |
| 238 | clk_status <= 1'b0; |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 239 | end |
| 240 | end |
| 241 | end |
| 242 | |
Timothy Chen | a5f9e42 | 2020-09-01 18:05:03 -0700 | [diff] [blame] | 243 | assign pwr_o.clk_status = clk_status; |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 244 | |
| 245 | //////////////////////////////////////////////////// |
| 246 | // Clocks with only root gate |
| 247 | //////////////////////////////////////////////////// |
| 248 | % for k,v in rg_clks.items(): |
| 249 | assign clocks_o.${k} = clk_${v}_root; |
| 250 | % endfor |
| 251 | |
| 252 | //////////////////////////////////////////////////// |
| 253 | // Software direct control group |
| 254 | //////////////////////////////////////////////////// |
| 255 | |
Timothy Chen | 110fa29 | 2020-04-28 17:00:15 -0700 | [diff] [blame] | 256 | % for k in sw_clks: |
| 257 | logic ${k}_sw_en; |
| 258 | % endfor |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 259 | |
| 260 | % for k,v in sw_clks.items(): |
Timothy Chen | 110fa29 | 2020-04-28 17:00:15 -0700 | [diff] [blame] | 261 | prim_flop_2sync #( |
| 262 | .Width(1) |
Timothy Chen | ced60b2 | 2020-08-20 10:35:00 -0700 | [diff] [blame] | 263 | ) u_${k}_sw_en_sync ( |
Timothy Chen | 110fa29 | 2020-04-28 17:00:15 -0700 | [diff] [blame] | 264 | .clk_i(clk_${v}_i), |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 265 | .rst_ni(rst_${v}_ni), |
Scott Johnson | 204d98d | 2020-07-17 12:06:05 -0700 | [diff] [blame] | 266 | .d_i(reg2hw.clk_enables.${k}_en.q), |
| 267 | .q_o(${k}_sw_en) |
Timothy Chen | 110fa29 | 2020-04-28 17:00:15 -0700 | [diff] [blame] | 268 | ); |
| 269 | |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 270 | lc_ctrl_pkg::lc_tx_t ${k}_scanmode; |
| 271 | prim_lc_sync #( |
| 272 | .NumCopies(1), |
| 273 | .AsyncOn(0) |
| 274 | ) u_${k}_scanmode_sync ( |
Timothy Chen | 7a0289c | 2021-02-19 16:33:44 -0800 | [diff] [blame] | 275 | .clk_i(1'b0), //unused |
| 276 | .rst_ni(1'b1), //unused |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 277 | .lc_en_i(scanmode_i), |
| 278 | .lc_en_o(${k}_scanmode) |
| 279 | ); |
| 280 | |
Timothy Chen | 11c848e | 2020-11-03 12:03:28 -0800 | [diff] [blame] | 281 | prim_clock_gating #( |
| 282 | .NoFpgaGate(1'b1) |
| 283 | ) u_${k}_cg ( |
Timothy Chen | 1366af7 | 2020-11-03 09:53:03 -0800 | [diff] [blame] | 284 | .clk_i(clk_${v}_root), |
Timothy Chen | 110fa29 | 2020-04-28 17:00:15 -0700 | [diff] [blame] | 285 | .en_i(${k}_sw_en & clk_${v}_en), |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 286 | .test_en_i(${k}_scanmode == lc_ctrl_pkg::On), |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 287 | .clk_o(clocks_o.${k}) |
| 288 | ); |
Timothy Chen | 110fa29 | 2020-04-28 17:00:15 -0700 | [diff] [blame] | 289 | |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 290 | % endfor |
| 291 | |
| 292 | //////////////////////////////////////////////////// |
| 293 | // Software hint group |
| 294 | // The idle hint feedback is assumed to be synchronous to the |
| 295 | // clock target |
| 296 | //////////////////////////////////////////////////// |
| 297 | |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 298 | % for k in hint_clks: |
| 299 | logic ${k}_hint; |
| 300 | logic ${k}_en; |
| 301 | % endfor |
| 302 | |
| 303 | % for k,v in hint_clks.items(): |
Timothy Chen | c8f3004 | 2020-09-25 16:59:47 -0700 | [diff] [blame] | 304 | assign ${k}_en = ${k}_hint | ~idle_i[${v["name"].capitalize()}]; |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 305 | |
| 306 | prim_flop_2sync #( |
| 307 | .Width(1) |
Timothy Chen | ced60b2 | 2020-08-20 10:35:00 -0700 | [diff] [blame] | 308 | ) u_${k}_hint_sync ( |
Timothy Chen | c8f3004 | 2020-09-25 16:59:47 -0700 | [diff] [blame] | 309 | .clk_i(clk_${v["src"]}_i), |
| 310 | .rst_ni(rst_${v["src"]}_ni), |
Scott Johnson | 204d98d | 2020-07-17 12:06:05 -0700 | [diff] [blame] | 311 | .d_i(reg2hw.clk_hints.${k}_hint.q), |
| 312 | .q_o(${k}_hint) |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 313 | ); |
| 314 | |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 315 | lc_ctrl_pkg::lc_tx_t ${k}_scanmode; |
| 316 | prim_lc_sync #( |
| 317 | .NumCopies(1), |
| 318 | .AsyncOn(0) |
| 319 | ) u_${k}_scanmode_sync ( |
Timothy Chen | 7a0289c | 2021-02-19 16:33:44 -0800 | [diff] [blame] | 320 | .clk_i(1'b0), //unused |
| 321 | .rst_ni(1'b1), //unused |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 322 | .lc_en_i(scanmode_i), |
| 323 | .lc_en_o(${k}_scanmode) |
| 324 | ); |
| 325 | |
Timothy Chen | 11c848e | 2020-11-03 12:03:28 -0800 | [diff] [blame] | 326 | prim_clock_gating #( |
| 327 | .NoFpgaGate(1'b1) |
| 328 | ) u_${k}_cg ( |
Timothy Chen | 1366af7 | 2020-11-03 09:53:03 -0800 | [diff] [blame] | 329 | .clk_i(clk_${v["src"]}_root), |
Timothy Chen | c8f3004 | 2020-09-25 16:59:47 -0700 | [diff] [blame] | 330 | .en_i(${k}_en & clk_${v["src"]}_en), |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 331 | .test_en_i(${k}_scanmode == lc_ctrl_pkg::On), |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 332 | .clk_o(clocks_o.${k}) |
| 333 | ); |
| 334 | |
| 335 | % endfor |
| 336 | |
| 337 | // state readback |
| 338 | % for k,v in hint_clks.items(): |
| 339 | assign hw2reg.clk_hints_status.${k}_val.de = 1'b1; |
| 340 | assign hw2reg.clk_hints_status.${k}_val.d = ${k}_en; |
| 341 | % endfor |
| 342 | |
Timothy Chen | 5649c2a | 2021-02-08 18:32:22 -0800 | [diff] [blame] | 343 | assign jitter_en_o = reg2hw.jitter_enable.q; |
| 344 | |
Timothy Chen | 4c8905e | 2020-08-26 10:34:33 -0700 | [diff] [blame] | 345 | //////////////////////////////////////////////////// |
| 346 | // Exported clocks |
| 347 | //////////////////////////////////////////////////// |
| 348 | |
| 349 | % for intf, eps in export_clks.items(): |
| 350 | % for ep, clks in eps.items(): |
| 351 | % for clk in clks: |
| 352 | assign clocks_${intf}_o.clk_${intf}_${ep}_${clk} = clocks_o.clk_${clk}; |
| 353 | % endfor |
| 354 | % endfor |
| 355 | % endfor |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 356 | |
| 357 | //////////////////////////////////////////////////// |
| 358 | // Assertions |
| 359 | //////////////////////////////////////////////////// |
| 360 | |
Timothy Chen | 8be9186 | 2020-11-02 13:40:09 -0800 | [diff] [blame] | 361 | `ASSERT_KNOWN(TlDValidKnownO_A, tl_o.d_valid) |
| 362 | `ASSERT_KNOWN(TlAReadyKnownO_A, tl_o.a_ready) |
| 363 | % for intf in export_clks: |
| 364 | `ASSERT_KNOWN(ExportClocksKownO_A, clocks_${intf}_o) |
| 365 | % endfor |
| 366 | `ASSERT_KNOWN(ClocksKownO_A, clocks_o) |
Timothy Chen | 3525aa8 | 2020-04-23 23:23:18 -0700 | [diff] [blame] | 367 | |
Timothy Chen | ced60b2 | 2020-08-20 10:35:00 -0700 | [diff] [blame] | 368 | endmodule // clkmgr |