// 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"

<%
clks_attr = cfg['clocks']
srcs = clks_attr['srcs']
%>

module clkmgr import clkmgr_pkg::*; (
  // 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 srcs:
  input clk_${src['name']}_i,
  % if src['aon'] == 'no':
  input rst_${src['name']}_ni,
  % endif
% endfor

  // Resets for derived clocks
  // clocks are derived locally
% for src in div_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,

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

  // dft interface
  input scanmode_i,

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

  // clock bypass control
  input lc_ctrl_pkg::lc_tx_t ast_clk_bypass_ack_i,
  output lc_ctrl_pkg::lc_tx_t lc_clk_bypass_ack_o,

  // clock output interface
% for intf in export_clks:
  output clkmgr_${intf}_out_t clocks_${intf}_o,
% endfor
  output clkmgr_out_t clocks_o

);

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

  clkmgr_reg_pkg::clkmgr_reg2hw_t reg2hw;
  clkmgr_reg_pkg::clkmgr_hw2reg_t hw2reg;

  clkmgr_reg_top u_reg (
    .clk_i,
    .rst_ni,
    .tl_i,
    .tl_o,
    .reg2hw,
    .hw2reg,
    .devmode_i(1'b1)
  );

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

  lc_ctrl_pkg::lc_tx_t step_down_req;
  logic [${len(div_srcs)-1}:0] step_down_acks;

  prim_lc_sync u_rcv (
    .clk_i,
    .rst_ni,
    .lc_en_i(ast_clk_bypass_ack_i),
    .lc_en_o(step_down_req)
  );

% for src in div_srcs:
  logic clk_${src['name']}_i;
% endfor

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

  prim_lc_sender u_send (
   .clk_i,
   .rst_ni,
   .lc_en_i(&step_down_acks ? lc_ctrl_pkg::On : lc_ctrl_pkg::Off),
   .lc_en_o(lc_clk_bypass_ack_o)
  );

  ////////////////////////////////////////////////////
  // 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 ft_clks.items():
  prim_clock_buf u_${k}_buf (
    .clk_i(clk_${v}_i),
    .clk_o(clocks_o.${k})
  );
% 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 rg_srcs:
  logic clk_${src}_root;
  logic clk_${src}_en;
% endfor

% for src in rg_srcs:
  prim_clock_gating_sync u_${src}_cg (
    .clk_i(clk_${src}_i),
    .rst_ni(rst_${src}_ni),
    .test_en_i(scanmode_i),
    .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 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 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;

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

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

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

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

  prim_clock_gating #(
    .NoFpgaGate(1'b1)
  ) u_${k}_cg (
    .clk_i(clk_${v}_root),
    .en_i(${k}_sw_en & clk_${v}_en),
    .test_en_i(scanmode_i),
    .clk_o(clocks_o.${k})
  );

% endfor

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

% for k in hint_clks:
  logic ${k}_hint;
  logic ${k}_en;
% endfor

% for k,v in hint_clks.items():
  assign ${k}_en = ${k}_hint | ~idle_i[${v["name"].capitalize()}];

  prim_flop_2sync #(
    .Width(1)
  ) u_${k}_hint_sync (
    .clk_i(clk_${v["src"]}_i),
    .rst_ni(rst_${v["src"]}_ni),
    .d_i(reg2hw.clk_hints.${k}_hint.q),
    .q_o(${k}_hint)
  );

  prim_clock_gating #(
    .NoFpgaGate(1'b1)
  ) u_${k}_cg (
    .clk_i(clk_${v["src"]}_root),
    .en_i(${k}_en & clk_${v["src"]}_en),
    .test_en_i(scanmode_i),
    .clk_o(clocks_o.${k})
  );

% endfor

  // state readback
% for k,v in hint_clks.items():
  assign hw2reg.clk_hints_status.${k}_val.de = 1'b1;
  assign hw2reg.clk_hints_status.${k}_val.d = ${k}_en;
% endfor

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

% for intf, eps in export_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)
% for intf in export_clks:
  `ASSERT_KNOWN(ExportClocksKownO_A, clocks_${intf}_o)
% endfor
  `ASSERT_KNOWN(ClocksKownO_A, clocks_o)

endmodule // clkmgr
