// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// The overall clock manager

`include "prim_assert.sv"

  module clkmgr
    import clkmgr_pkg::*;
    import clkmgr_reg_pkg::*;
    import lc_ctrl_pkg::lc_tx_t;
#(
  parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}
) (
  // Primary module control clocks and resets
  // This drives the register interface
  input clk_i,
  input rst_ni,

  // System clocks and resets
  // These are the source clocks for the system
% for src in clocks.srcs.values():
  input clk_${src.name}_i,
  input rst_${src.name}_ni,
% endfor

  // Resets for derived clocks
  // clocks are derived locally
% for src_name in clocks.derived_srcs:
  input rst_${src_name}_ni,
% endfor

  // Bus Interface
  input tlul_pkg::tl_h2d_t tl_i,
  output tlul_pkg::tl_d2h_t tl_o,

  // Alerts
  input  prim_alert_pkg::alert_rx_t [NumAlerts-1:0] alert_rx_i,
  output prim_alert_pkg::alert_tx_t [NumAlerts-1:0] alert_tx_o,

  // pwrmgr interface
  input pwrmgr_pkg::pwr_clk_req_t pwr_i,
  output pwrmgr_pkg::pwr_clk_rsp_t pwr_o,

  // dft interface
  input lc_tx_t scanmode_i,

  // idle hints
  input [${len(typed_clocks.hint_clks)-1}:0] idle_i,

  // life cycle state output
  input lc_tx_t lc_dft_en_i,

  // clock bypass control
  input lc_tx_t lc_clk_byp_req_i,
  output lc_tx_t ast_clk_byp_req_o,
  input lc_tx_t ast_clk_byp_ack_i,
  output lc_tx_t lc_clk_byp_ack_o,

  // jittery enable
  output logic jitter_en_o,

  // clock gated indications going to alert handlers
  output clkmgr_cg_en_t cg_en_o,

  // clock output interface
% for intf in cfg['exported_clks']:
  output clkmgr_${intf}_out_t clocks_${intf}_o,
% endfor
  output clkmgr_out_t clocks_o

);

  ////////////////////////////////////////////////////
  // Divided clocks
  ////////////////////////////////////////////////////

  lc_tx_t step_down_req;
  logic [${len(clocks.derived_srcs)-1}:0] step_down_acks;

% for src_name in clocks.derived_srcs:
  logic clk_${src_name}_i;
% endfor

% for src in clocks.derived_srcs.values():

  lc_tx_t ${src.name}_div_scanmode;
  prim_lc_sync #(
    .NumCopies(1),
    .AsyncOn(0)
  ) u_${src.name}_div_scanmode_sync  (
    .clk_i(1'b0),  //unused
    .rst_ni(1'b1), //unused
    .lc_en_i(scanmode_i),
    .lc_en_o(${src.name}_div_scanmode)
  );

  prim_clock_div #(
    .Divisor(${src.div})
  ) u_no_scan_${src.name}_div (
    .clk_i(clk_${src.src.name}_i),
    .rst_ni(rst_${src.src.name}_ni),
    .step_down_req_i(step_down_req == lc_ctrl_pkg::On),
    .step_down_ack_o(step_down_acks[${loop.index}]),
    .test_en_i(${src.name}_div_scanmode == lc_ctrl_pkg::On),
    .clk_o(clk_${src.name}_i)
  );
% endfor

  ////////////////////////////////////////////////////
  // Register Interface
  ////////////////////////////////////////////////////

  logic [NumAlerts-1:0] alert_test, alerts;
  clkmgr_reg_pkg::clkmgr_reg2hw_t reg2hw;
  clkmgr_reg_pkg::clkmgr_hw2reg_t hw2reg;

  clkmgr_reg_top u_reg (
    .clk_i,
    .rst_ni,
% for src in typed_clocks.rg_srcs:
    .clk_${src}_i,
    .rst_${src}_ni,
% endfor
    .tl_i,
    .tl_o,
    .reg2hw,
    .hw2reg,
    .intg_err_o(hw2reg.fatal_err_code.de),
    .devmode_i(1'b1)
  );
  assign hw2reg.fatal_err_code.d = 1'b1;


  ////////////////////////////////////////////////////
  // Alerts
  ////////////////////////////////////////////////////

  assign alert_test = {
    reg2hw.alert_test.fatal_fault.q & reg2hw.alert_test.fatal_fault.qe,
    reg2hw.alert_test.recov_fault.q & reg2hw.alert_test.recov_fault.qe
  };

  assign alerts = {
    |reg2hw.fatal_err_code,
    |reg2hw.recov_err_code
  };

  localparam logic [NumAlerts-1:0] AlertFatal = {1'b1, 1'b0};

  for (genvar i = 0; i < NumAlerts; i++) begin : gen_alert_tx
    prim_alert_sender #(
      .AsyncOn(AlertAsyncOn[i]),
      .IsFatal(AlertFatal[i])
    ) u_prim_alert_sender (
      .clk_i,
      .rst_ni,
      .alert_test_i  ( alert_test[i] ),
      .alert_req_i   ( alerts[i]     ),
      .alert_ack_o   (               ),
      .alert_state_o (               ),
      .alert_rx_i    ( alert_rx_i[i] ),
      .alert_tx_o    ( alert_tx_o[i] )
    );
  end

  ////////////////////////////////////////////////////
  // Clock bypass request
  ////////////////////////////////////////////////////

  clkmgr_byp #(
    .NumDivClks(${len(clocks.derived_srcs)})
  ) u_clkmgr_byp (
    .clk_i,
    .rst_ni,
    .en_i(lc_dft_en_i),
    .byp_req_i(lc_tx_t'(reg2hw.extclk_ctrl.sel.q)),
    .step_down_req_i(lc_tx_t'(reg2hw.extclk_ctrl.step_down.q)),
    .ast_clk_byp_req_o,
    .ast_clk_byp_ack_i,
    .lc_clk_byp_req_i,
    .lc_clk_byp_ack_o,
    .step_down_acks_i(step_down_acks),
    .step_down_req_o(step_down_req)
  );

  ////////////////////////////////////////////////////
  // Feed through clocks
  // Feed through clocks do not actually need to be in clkmgr, as they are
  // completely untouched. The only reason they are here is for easier
  // bundling management purposes through clocks_o
  ////////////////////////////////////////////////////
% for k,v in typed_clocks.ft_clks.items():
  prim_clock_buf u_${k}_buf (
    .clk_i(clk_${v.src.name}_i),
    .clk_o(clocks_o.${k})
  );

  // clock gated indication for alert handler: these clocks are never gated.
  assign cg_en_o.${k.split('clk_')[-1]} = lc_ctrl_pkg::Off;
% endfor

  ////////////////////////////////////////////////////
  // Root gating
  ////////////////////////////////////////////////////

  logic wait_enable;
  logic wait_disable;
  logic en_status_d;
  logic dis_status_d;
  logic [1:0] en_status_q;
  logic [1:0] dis_status_q;
  logic clk_status;
% for src in typed_clocks.rg_srcs:
  logic clk_${src}_root;
  logic clk_${src}_en;
% endfor

% for src in typed_clocks.rg_srcs:
  lc_tx_t ${src}_scanmode;
  prim_lc_sync #(
    .NumCopies(1),
    .AsyncOn(0)
  ) u_${src}_scanmode_sync  (
    .clk_i(1'b0),  //unused
    .rst_ni(1'b1), //unused
    .lc_en_i(scanmode_i),
    .lc_en_o(${src}_scanmode)
  );

  prim_clock_gating_sync u_${src}_cg (
    .clk_i(clk_${src}_i),
    .rst_ni(rst_${src}_ni),
    .test_en_i(${src}_scanmode == lc_ctrl_pkg::On),
    .async_en_i(pwr_i.ip_clk_en),
    .en_o(clk_${src}_en),
    .clk_o(clk_${src}_root)
  );

% endfor
  // an async AND of all the synchronized enables
  // return feedback to pwrmgr only when all clocks are enabled
  assign wait_enable =
% for src in typed_clocks.rg_srcs:
    % if loop.last:
    clk_${src}_en;
    % else:
    clk_${src}_en &
    % endif
% endfor

  // an async OR of all the synchronized enables
  // return feedback to pwrmgr only when all clocks are disabled
  assign wait_disable =
% for src in typed_clocks.rg_srcs:
    % if loop.last:
    clk_${src}_en;
    % else:
    clk_${src}_en |
    % endif
% endfor

  // Sync clkmgr domain for feedback to pwrmgr.
  // Since the signal is combo / converged on the other side, de-bounce
  // the signal prior to output
  prim_flop_2sync #(
    .Width(1)
  ) u_roots_en_status_sync (
    .clk_i,
    .rst_ni,
    .d_i(wait_enable),
    .q_o(en_status_d)
  );

  prim_flop_2sync #(
    .Width(1)
  ) u_roots_or_sync (
    .clk_i,
    .rst_ni,
    .d_i(wait_disable),
    .q_o(dis_status_d)
  );

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      en_status_q <= '0;
      dis_status_q <= '0;
      clk_status <= '0;
    end else begin
      en_status_q <= {en_status_q[0], en_status_d};
      dis_status_q <= {dis_status_q[0], dis_status_d};

      if (&en_status_q) begin
        clk_status <= 1'b1;
      end else if (|dis_status_q == '0) begin
        clk_status <= 1'b0;
      end
    end
  end

  assign pwr_o.clk_status = clk_status;

  ////////////////////////////////////////////////////
  // Clock Measurement for the roots
  ////////////////////////////////////////////////////

<% aon_freq = clocks.all_srcs['aon'].freq %>\
% for src in typed_clocks.rg_srcs:
  logic ${src}_fast_err;
  logic ${src}_slow_err;
  <%
   freq = clocks.all_srcs[src].freq
   cnt = int(freq*2 / aon_freq)
  %>\
  prim_clock_meas #(
    .Cnt(${cnt}),
    .RefCnt(1)
  ) u_${src}_meas (
    .clk_i(clk_${src}_i),
    .rst_ni(rst_${src}_ni),
    .clk_ref_i(clk_aon_i),
    .rst_ref_ni(rst_aon_ni),
    .en_i(clk_${src}_en & reg2hw.${src}_measure_ctrl.en.q),
    .max_cnt(reg2hw.${src}_measure_ctrl.max_thresh.q),
    .min_cnt(reg2hw.${src}_measure_ctrl.min_thresh.q),
    .valid_o(),
    .fast_o(${src}_fast_err),
    .slow_o(${src}_slow_err)
  );

  logic synced_${src}_err;
  prim_pulse_sync u_${src}_err_sync (
    .clk_src_i(clk_${src}_i),
    .rst_src_ni(rst_${src}_ni),
    .src_pulse_i(${src}_fast_err | ${src}_slow_err),
    .clk_dst_i(clk_i),
    .rst_dst_ni(rst_ni),
    .dst_pulse_o(synced_${src}_err)
  );

  assign hw2reg.recov_err_code.${src}_measure_err.d = 1'b1;
  assign hw2reg.recov_err_code.${src}_measure_err.de = synced_${src}_err;

% endfor

  ////////////////////////////////////////////////////
  // Clocks with only root gate
  ////////////////////////////////////////////////////
% for k,v in typed_clocks.rg_clks.items():
  assign clocks_o.${k} = clk_${v.src.name}_root;

  // clock gated indication for alert handler
  prim_lc_sender u_prim_lc_sender_${k} (
    .clk_i(clk_${v.src.name}_i),
    .rst_ni(rst_${v.src.name}_ni),
    .lc_en_i(((clk_${v.src.name}_en) ? lc_ctrl_pkg::Off : lc_ctrl_pkg::On)),
    .lc_en_o(cg_en_o.${k.split('clk_')[-1]})
  );
% endfor

  ////////////////////////////////////////////////////
  // Software direct control group
  ////////////////////////////////////////////////////

% for k in typed_clocks.sw_clks:
  logic ${k}_sw_en;
% endfor

% for k,v in typed_clocks.sw_clks.items():
  prim_flop_2sync #(
    .Width(1)
  ) u_${k}_sw_en_sync (
    .clk_i(clk_${v.src.name}_i),
    .rst_ni(rst_${v.src.name}_ni),
    .d_i(reg2hw.clk_enables.${k}_en.q),
    .q_o(${k}_sw_en)
  );

  lc_tx_t ${k}_scanmode;
  prim_lc_sync #(
    .NumCopies(1),
    .AsyncOn(0)
  ) u_${k}_scanmode_sync  (
    .clk_i(1'b0),  //unused
    .rst_ni(1'b1), //unused
    .lc_en_i(scanmode_i),
    .lc_en_o(${k}_scanmode)
  );

  logic ${k}_combined_en;
  assign ${k}_combined_en = ${k}_sw_en & clk_${v.src.name}_en;
  prim_clock_gating #(
    .FpgaBufGlobal(1'b1) // This clock spans across multiple clock regions.
  ) u_${k}_cg (
    .clk_i(clk_${v.src.name}_root),
    .en_i(${k}_combined_en),
    .test_en_i(${k}_scanmode == lc_ctrl_pkg::On),
    .clk_o(clocks_o.${k})
  );

  // clock gated indication for alert handler
  prim_lc_sender #(
    .ResetValueIsOn(1)
  ) u_prim_lc_sender_${k} (
    .clk_i(clk_${v.src.name}_i),
    .rst_ni(rst_${v.src.name}_ni),
    .lc_en_i(((${k}_combined_en) ? lc_ctrl_pkg::Off : lc_ctrl_pkg::On)),
    .lc_en_o(cg_en_o.${k.split('clk_')[-1]})
  );

% endfor

  ////////////////////////////////////////////////////
  // Software hint group
  // The idle hint feedback is assumed to be synchronous to the
  // clock target
  ////////////////////////////////////////////////////

% for clk in typed_clocks.hint_clks.keys():
  logic ${clk}_hint;
  logic ${clk}_en;
% endfor

% for clk, sig in typed_clocks.hint_clks.items():
  assign ${clk}_en = ${clk}_hint | ~idle_i[${hint_names[clk]}];

  prim_flop_2sync #(
    .Width(1)
  ) u_${clk}_hint_sync (
    .clk_i(clk_${sig.src.name}_i),
    .rst_ni(rst_${sig.src.name}_ni),
    .d_i(reg2hw.clk_hints.${clk}_hint.q),
    .q_o(${clk}_hint)
  );

  lc_tx_t ${clk}_scanmode;
  prim_lc_sync #(
    .NumCopies(1),
    .AsyncOn(0)
  ) u_${clk}_scanmode_sync  (
    .clk_i(1'b0),  //unused
    .rst_ni(1'b1), //unused
    .lc_en_i(scanmode_i),
    .lc_en_o(${clk}_scanmode)
  );

  // Add a prim buf here to make sure the CG and the lc sender inputs
  // are derived from the same physical signal.
  logic ${clk}_combined_en;
  prim_buf u_prim_buf_${clk}_en (
    .in_i(${clk}_en & clk_${sig.src.name}_en),
    .out_o(${clk}_combined_en)
  );

  prim_clock_gating #(
    .FpgaBufGlobal(1'b0) // This clock is used primarily locally.
  ) u_${clk}_cg (
    .clk_i(clk_${sig.src.name}_root),
    .en_i(${clk}_combined_en),
    .test_en_i(${clk}_scanmode == lc_ctrl_pkg::On),
    .clk_o(clocks_o.${clk})
  );

  // clock gated indication for alert handler
  prim_lc_sender #(
    .ResetValueIsOn(1)
  ) u_prim_lc_sender_${clk} (
    .clk_i(clk_${sig.src.name}_i),
    .rst_ni(rst_${sig.src.name}_ni),
    .lc_en_i(((${clk}_combined_en) ? lc_ctrl_pkg::Off : lc_ctrl_pkg::On)),
    .lc_en_o(cg_en_o.${clk.split('clk_')[-1]})
  );

% endfor

  // state readback
% for clk in typed_clocks.hint_clks.keys():
  assign hw2reg.clk_hints_status.${clk}_val.de = 1'b1;
  assign hw2reg.clk_hints_status.${clk}_val.d = ${clk}_en;
% endfor

  assign jitter_en_o = reg2hw.jitter_enable.q;

  ////////////////////////////////////////////////////
  // Exported clocks
  ////////////////////////////////////////////////////

% for intf, eps in cfg['exported_clks'].items():
  % for ep, clks in eps.items():
    % for clk in clks:
  assign clocks_${intf}_o.clk_${intf}_${ep}_${clk} = clocks_o.clk_${clk};
    % endfor
  % endfor
% endfor

  ////////////////////////////////////////////////////
  // Assertions
  ////////////////////////////////////////////////////

  `ASSERT_KNOWN(TlDValidKnownO_A, tl_o.d_valid)
  `ASSERT_KNOWN(TlAReadyKnownO_A, tl_o.a_ready)
  `ASSERT_KNOWN(AlertsKnownO_A,   alert_tx_o)
  `ASSERT_KNOWN(PwrMgrKnownO_A, pwr_o)
  `ASSERT_KNOWN(AstClkBypReqKnownO_A, ast_clk_byp_req_o)
  `ASSERT_KNOWN(LcCtrlClkBypAckKnownO_A, lc_clk_byp_ack_o)
  `ASSERT_KNOWN(JitterEnableKnownO_A, jitter_en_o)
% for intf in cfg['exported_clks']:
  `ASSERT_KNOWN(ExportClocksKownO_A, clocks_${intf}_o)
% endfor
  `ASSERT_KNOWN(ClocksKownO_A, clocks_o)
  `ASSERT_KNOWN(CgEnKnownO_A, cg_en_o)

endmodule // clkmgr
