// 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,
  input  mubi4_t          low_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,
  // interaction with dividers
  input  [NumDivClks-1:0] step_down_acks_i,
  output logic            step_down_req_o
);

  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_or_hi;
  import prim_mubi_pkg::mubi4_test_false_strict;
  import prim_mubi_pkg::mubi4_test_true_strict;

  // life cycle handling
  mubi4_t io_clk_byp_req_d;
  assign io_clk_byp_req_d = (lc_clk_byp_req_i == lc_ctrl_pkg::On) ?
                            MuBi4True :
                            MuBi4False;

  prim_mubi4_sender #(
    .ResetValue(MuBi4False)
  ) 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.
  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)
  );

  // software switch request handling
  mubi4_t dft_en;
  assign dft_en = (en_i == lc_ctrl_pkg::On) ? MuBi4True : MuBi4False;

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

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

  // divider step down handling
  mubi4_t io_clk_byp_ack;
  mubi4_t all_clk_byp_ack;

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

  prim_mubi4_sync #(
    .AsyncOn(1),
    .ResetValue(MuBi4False)
  ) u_all_ack_sync (
    .clk_i,
    .rst_ni,
    .mubi_i(all_clk_byp_ack_i),
    .mubi_o(all_clk_byp_ack)
  );

  // create individual requests
  mubi4_t lc_step_down_req;
  assign lc_step_down_req = mubi4_and_hi(io_clk_byp_req_o, io_clk_byp_ack);

  // When requesting a switch, the low speed indication is used to determine step down.
  // Once switched, the low speed indication is not looked at again until software request
  // is de-asserted.
  mubi4_t sw_step_down_en;
  mubi4_t sw_step_down_req;
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      sw_step_down_en <= MuBi4False;
    end else if (mubi4_test_true_strict(all_clk_byp_req_o) &&
                 mubi4_test_true_strict(all_clk_byp_ack)) begin
      sw_step_down_en <= MuBi4True;
    end else if (
      mubi4_test_true_strict(sw_step_down_en) &&
      mubi4_test_false_strict(all_clk_byp_req_o) &&
      mubi4_test_false_strict(all_clk_byp_ack)) begin
      sw_step_down_en <= MuBi4False;
    end
  end
  // when in external clock state, allow low speed select to directly control
  // clock divider.
  assign sw_step_down_req = mubi4_and_hi(sw_step_down_en, low_speed_sel_i);

  // combine requests
  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      step_down_req_o <= '0;
    end else begin
      step_down_req_o <=
        mubi4_test_true_strict(mubi4_or_hi(lc_step_down_req, sw_step_down_req));
    end
  end


endmodule // clkmgr_byp
