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

module clkmgr_byp import clkmgr_pkg::*; import lc_ctrl_pkg::lc_tx_t; # (
  parameter int NumDivClks = 1
) (
  input                   clk_i,
  input                   rst_ni,
  input  lc_tx_t          en_i,
  input  lc_tx_t          byp_req_i,
  input  lc_tx_t          step_down_req_i,
  output lc_tx_t          ast_clk_byp_req_o,
  input  lc_tx_t          ast_clk_byp_ack_i,
  input  lc_tx_t          lc_clk_byp_req_i,
  output lc_tx_t          lc_clk_byp_ack_o,
  input  [NumDivClks-1:0] step_down_acks_i,
  output lc_tx_t          step_down_req_o
);

  lc_tx_t reg_clk_byp_req;
  lc_tx_t on_val;
  assign on_val = lc_ctrl_pkg::On;

  // Generate qualified reg clk bypass request
  for (genvar i = 0; i < $bits(lc_tx_t); i++) begin : gen_clk_byp
    prim_buf u_buf (
      .in_i(on_val[i] ? byp_req_i[i] & en_i[i] : byp_req_i[i] | en_i[i]),
      .out_o(reg_clk_byp_req[i])
    );
  end

  lc_tx_t ast_clk_byp_req;
  always_comb begin
    ast_clk_byp_req = lc_ctrl_pkg::Off;
    if (lc_clk_byp_req_i == lc_ctrl_pkg::On) begin
      ast_clk_byp_req = lc_ctrl_pkg::On;
    end else if (reg_clk_byp_req == lc_ctrl_pkg::On) begin
      ast_clk_byp_req = lc_ctrl_pkg::On;
    end
  end

  prim_lc_sender u_clk_byp_req (
   .clk_i,
   .rst_ni,
   .lc_en_i(ast_clk_byp_req),
   .lc_en_o(ast_clk_byp_req_o)
  );

  lc_tx_t ast_clk_byp_ack;
  prim_lc_sync u_rcv (
    .clk_i,
    .rst_ni,
    .lc_en_i(ast_clk_byp_ack_i),
    .lc_en_o(ast_clk_byp_ack)
  );

  // if switch request came from software, let software dictate whether to step down
  assign step_down_req_o =
    lc_clk_byp_req_i == lc_ctrl_pkg::On ? ast_clk_byp_ack :
    reg_clk_byp_req == lc_ctrl_pkg::On  ? ast_clk_byp_ack & step_down_req_i :
                                          lc_ctrl_pkg::Off;

  // only ack the lc_ctrl if it made a request.
  prim_lc_sender u_send (
   .clk_i,
   .rst_ni,
   .lc_en_i((&step_down_acks_i) ? lc_clk_byp_req_i : lc_ctrl_pkg::Off),
   .lc_en_o(lc_clk_byp_ack_o)
  );


endmodule // clkmgr_byp
