// 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;
  import prim_mubi_pkg::mubi4_t;
# (
  parameter int NumDivClks = 1
) (
  input                   clk_i,
  input                   rst_ni,
  // interaction with lc_ctrl
  input  lc_tx_t          en_i,
  input  lc_tx_t          lc_clk_byp_req_i,
  output lc_tx_t          lc_clk_byp_ack_o,
  // interaction with software
  input  mubi4_t          byp_req_i,
  output mubi4_t          byp_ack_o,
  input  mubi4_t          hi_speed_sel_i,
  // interaction with ast
  output mubi4_t          all_clk_byp_req_o,
  input  mubi4_t          all_clk_byp_ack_i,
  output mubi4_t          io_clk_byp_req_o,
  input  mubi4_t          io_clk_byp_ack_i,
  output mubi4_t          hi_speed_sel_o,
  // interaction with dividers
  input  [NumDivClks-1:0] step_down_acks_i
);

  import prim_mubi_pkg::MuBi4Width;
  import prim_mubi_pkg::MuBi4True;
  import prim_mubi_pkg::MuBi4False;
  import prim_mubi_pkg::mubi4_and_hi;
  import prim_mubi_pkg::mubi4_test_true_strict;

  // synchornize incoming lc signals
  lc_tx_t en;
  prim_lc_sync #(
    .NumCopies(1),
    .AsyncOn(1),
    .ResetValueIsOn(0)
  ) u_en_sync (
    .clk_i,
    .rst_ni,
    .lc_en_i(en_i),
    .lc_en_o(en)
  );

  typedef enum logic [1:0] {
    LcClkBypReqIoReq,
    LcClkBypReqLcAck,
    LcClkBypReqLast
  } lc_clk_byp_req_e;

  lc_tx_t [LcClkBypReqLast-1:0] lc_clk_byp_req;
  prim_lc_sync #(
    .NumCopies(int'(LcClkBypReqLast)),
    .AsyncOn(1),
    .ResetValueIsOn(0)
  ) u_lc_byp_req (
    .clk_i,
    .rst_ni,
    .lc_en_i(lc_clk_byp_req_i),
    .lc_en_o(lc_clk_byp_req)
  );

  // synchronize step down acks
  logic [NumDivClks-1:0] step_down_acks_sync;
  prim_flop #(
    .Width(NumDivClks),
    .ResetValue(0)
  ) u_step_down_acks_sync (
    .clk_i,
    .rst_ni,
    .d_i(step_down_acks_i),
    .q_o(step_down_acks_sync)
  );

  // life cycle handling
  mubi4_t io_clk_byp_req_d;
  assign io_clk_byp_req_d = (lc_clk_byp_req[LcClkBypReqIoReq] == lc_ctrl_pkg::On) ?
                            MuBi4True :
                            MuBi4False;

  prim_mubi4_sender #(
    .ResetValue(MuBi4False),
    .EnSecBuf(1)
  ) u_io_byp_req (
    .clk_i,
    .rst_ni,
    .mubi_i(io_clk_byp_req_d),
    .mubi_o(io_clk_byp_req_o)
  );

  // only ack the lc_ctrl if it made a request.
  mubi4_t io_clk_byp_ack;
  prim_lc_sender u_send (
   .clk_i,
   .rst_ni,
   .lc_en_i(&step_down_acks_sync & mubi4_test_true_strict(io_clk_byp_ack) ?
            lc_clk_byp_req[LcClkBypReqLcAck] : lc_ctrl_pkg::Off),
   .lc_en_o(lc_clk_byp_ack_o)
  );

  // software switch request handling
  mubi4_t dft_en;
  assign dft_en = lc_ctrl_pkg::lc_to_mubi4(en);

  mubi4_t all_clk_byp_req_d;
  assign all_clk_byp_req_d = mubi4_and_hi(byp_req_i, dft_en);

  prim_mubi4_sender #(
    .AsyncOn(1),
    .ResetValue(MuBi4False),
    .EnSecBuf(1)
  ) u_all_byp_req (
    .clk_i,
    .rst_ni,
    .mubi_i(all_clk_byp_req_d),
    .mubi_o(all_clk_byp_req_o)
  );

  prim_mubi4_sync #(
    .AsyncOn(1),
    .StabilityCheck(1),
    .ResetValue(MuBi4False)
  ) u_io_ack_sync (
    .clk_i,
    .rst_ni,
    .mubi_i(io_clk_byp_ack_i),
    .mubi_o({io_clk_byp_ack})
  );

  // since div_step_down_req is now directly fed externally, there is no longer
  // a use for the related 'ack' signals
  prim_mubi4_sync #(
    .AsyncOn(1),
    .StabilityCheck(1),
    .ResetValue(MuBi4False)
  ) u_all_ack_sync (
    .clk_i,
    .rst_ni,
    .mubi_i(all_clk_byp_ack_i),
    .mubi_o(byp_ack_o)
  );

  // the software high speed select is valid only when software requests clock
  // bypass
  prim_mubi4_sender #(
    .AsyncOn(1),
    .ResetValue(MuBi4True)
  ) u_hi_speed_sel (
    .clk_i,
    .rst_ni,
    .mubi_i(mubi4_and_hi(all_clk_byp_req_d, hi_speed_sel_i)),
    .mubi_o(hi_speed_sel_o)
  );

endmodule // clkmgr_byp
