// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Power Manager CDC handling
//

`include "prim_assert.sv"

module pwrmgr_cdc import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;
(
  // Clocks and resets
  input clk_slow_i,
  input clk_i,
  input rst_slow_ni,
  input rst_ni,

  // slow domain signals,
  input slow_req_pwrup_i,
  input slow_ack_pwrdn_i,
  input slow_pwrup_cause_toggle_i,
  input pwrup_cause_e slow_pwrup_cause_i,
  output logic [NumWkups-1:0] slow_wakeup_en_o,
  output pwrmgr_reg_pkg::pwrmgr_reg2hw_reset_en_reg_t slow_reset_en_o,
  output logic slow_main_pd_no,
  output logic slow_io_clk_en_o,
  output logic slow_core_clk_en_o,
  output logic slow_req_pwrdn_o,
  output logic slow_ack_pwrup_o,
  output pwr_ast_rsp_t slow_ast_o,
  output pwr_peri_t slow_peri_reqs_o,
  input pwr_peri_t slow_peri_reqs_masked_i,

  // fast domain signals
  input req_pwrdn_i,
  input ack_pwrup_i,
  input cfg_cdc_sync_i,
  input [NumWkups-1:0] wakeup_en_i,
  input pwrmgr_reg_pkg::pwrmgr_reg2hw_reset_en_reg_t reset_en_i,
  input main_pd_ni,
  input io_clk_en_i,
  input core_clk_en_i,
  output logic ack_pwrdn_o,
  output logic req_pwrup_o,
  output pwrup_cause_e pwrup_cause_o,
  output pwr_peri_t peri_reqs_o,
  output logic cdc_sync_done_o,

  // peripheral inputs, mixed domains
  input pwr_peri_t peri_i,

  // AST inputs, unknown domain
  input pwr_ast_rsp_t ast_i

);

  ////////////////////////////////
  // Sync from clk_i to clk_slow_i
  ////////////////////////////////

  logic slow_cdc_sync;
  pwr_ast_rsp_t slow_ast_q, slow_ast_q2;

  prim_flop_2sync # (
    .Width(1)
  ) i_req_pwrdn_sync (
    .clk_i(clk_slow_i),
    .rst_ni(rst_slow_ni),
    .d_i(req_pwrdn_i),
    .q_o(slow_req_pwrdn_o)
  );

  prim_flop_2sync # (
    .Width(1)
  ) i_ack_pwrup_sync (
    .clk_i(clk_slow_i),
    .rst_ni(rst_slow_ni),
    .d_i(ack_pwrup_i),
    .q_o(slow_ack_pwrup_o)
  );

  prim_pulse_sync i_slow_cdc_sync (
    .clk_src_i(clk_i),
    .rst_src_ni(rst_ni),
    .src_pulse_i(cfg_cdc_sync_i),
    .clk_dst_i(clk_slow_i),
    .rst_dst_ni(rst_slow_ni),
    .dst_pulse_o(slow_cdc_sync)
  );

  // Even though this is multi-bit, the bits are individual request lines.
  // So there is no general concern about recombining as there is
  // no intent to use them in a related manner.
  prim_flop_2sync # (
    .Width(HwRstReqs + NumWkups)
  ) i_slow_ext_req_sync (
    .clk_i  (clk_slow_i),
    .rst_ni (rst_slow_ni),
    .d_i    (peri_i),
    .q_o    (slow_peri_reqs_o)
  );


  // Some of the AST signals are multi-bits themselves (such as clk_val)
  // thus they need to be delayed one more stage to check for stability
  prim_flop_2sync # (
    .Width($bits(pwr_ast_rsp_t)),
    .ResetValue(PWR_AST_RSP_SYNC_DEFAULT)
  ) i_ast_sync (
    .clk_i  (clk_slow_i),
    .rst_ni (rst_slow_ni),
    .d_i    (ast_i),
    .q_o    (slow_ast_q)
  );

  always_ff @(posedge clk_slow_i or negedge rst_slow_ni) begin
    if (!rst_slow_ni) begin
      slow_ast_q2 <= PWR_AST_RSP_SYNC_DEFAULT;
    end else begin
      slow_ast_q2 <= slow_ast_q;
    end
  end

  // if possible, we should simulate below with random delays through
  // flop_2sync
  always_ff @(posedge clk_slow_i or negedge rst_slow_ni) begin
    if (!rst_slow_ni) begin
      slow_ast_o <= PWR_AST_RSP_SYNC_DEFAULT;
    end else if (slow_ast_q2 == slow_ast_q) begin
      // Output only updates whenever sync and delayed outputs both agree.
      // If there are delays in sync, this will result in a 1 cycle difference
      // and the output will hold the previous value
      slow_ast_o <= slow_ast_q2;
    end
  end

  // only register configurations can be sync'd using slow_cdc_sync
  always_ff @(posedge clk_slow_i or negedge rst_slow_ni) begin
    if (!rst_slow_ni) begin
      slow_wakeup_en_o <= '0;
      slow_reset_en_o <= '0;
      slow_main_pd_no <= '0;
      slow_io_clk_en_o <= '0;
      slow_core_clk_en_o <= '0;
    end else if (slow_cdc_sync) begin
      slow_wakeup_en_o <= wakeup_en_i;
      slow_reset_en_o <= reset_en_i;
      slow_main_pd_no <= main_pd_ni;
      slow_io_clk_en_o <= io_clk_en_i;
      slow_core_clk_en_o <= core_clk_en_i;
    end
  end

  ////////////////////////////////
  // Sync from clk_slow_i to clk_i
  ////////////////////////////////

  logic pwrup_cause_toggle_q, pwrup_cause_toggle_q2;
  logic pwrup_cause_chg;

  prim_flop_2sync # (
    .Width(1)
  ) i_req_pwrup_sync (
    .clk_i,
    .rst_ni,
    .d_i(slow_req_pwrup_i),
    .q_o(req_pwrup_o)
  );

  prim_flop_2sync # (
    .Width(1)
  ) i_ack_pwrdn_sync (
    .clk_i,
    .rst_ni,
    .d_i(slow_ack_pwrdn_i),
    .q_o(ack_pwrdn_o)
  );

  prim_flop_2sync # (
    .Width(1)
  ) i_pwrup_chg_sync (
    .clk_i,
    .rst_ni,
    .d_i(slow_pwrup_cause_toggle_i),
    .q_o(pwrup_cause_toggle_q)
  );

  prim_pulse_sync i_scdc_sync (
    .clk_src_i(clk_slow_i),
    .rst_src_ni(rst_slow_ni),
    .src_pulse_i(slow_cdc_sync),
    .clk_dst_i(clk_i),
    .rst_dst_ni(rst_ni),
    .dst_pulse_o(cdc_sync_done_o)
  );

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      pwrup_cause_toggle_q2 <= 1'b0;
    end else begin
      pwrup_cause_toggle_q2 <= pwrup_cause_toggle_q;
    end
  end

  assign pwrup_cause_chg = pwrup_cause_toggle_q2 ^ pwrup_cause_toggle_q;

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      pwrup_cause_o <= Por;
    end else if (pwrup_cause_chg) begin
      pwrup_cause_o <= slow_pwrup_cause_i;
    end
  end

  prim_flop_2sync # (
    .Width(HwRstReqs + NumWkups)
  ) i_ext_req_sync (
    .clk_i,
    .rst_ni,
    .d_i(slow_peri_reqs_masked_i),
    .q_o(peri_reqs_o)
  );


endmodule


// An alternative solution relying on finding slow clock edges
// Keep it around just in case

/*
  // finds a clk_slow edge in clk domain to know when it is safe to sync over
  // this signal is only safe to use within the pwrmgr module when the source
  // and destination clock domains are both clear
  logic cdc_safe;

  // pwrup is synced directly as it acts as a start signal to the pulse module
  prim_flop_2sync # (
    .Width(1)
  ) i_pwrup_sync (
    .clk_i,
    .rst_ni,
    .d_i(slow_req_pwrup),
    .q_o(req_pwrup)
  );

  pwrmgr_cdc_pulse i_cdc_pulse (
    .clk_slow_i,
    .clk_i,
    .rst_ni,
    .start_i(req_pwrup),
    .stop_i(req_pwrdn),
    .pulse_o(cdc_safe)
  );

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      ack_pwrdn   <= '0;
      pwrup_cause <= Por;
    end else if (cdc_safe) begin
      ack_pwrdn   <= slow_ack_pwrdn;
      pwrup_cause <= slow_pwrup_cause;
    end
  end

  ////////////////////////////
  ///  cdc handling - clk_slow_i
  ////////////////////////////

  always_ff @(posedge clk_i or negedge rst_ni) begin
    if (!rst_ni) begin
      slow_wakeup_en <= '0;
      slow_reset_en  <= '0;
      slow_main_pdb  <= '0;
      slow_io_clk_en <= '0;
      slow_core_clk_en <= '0;
      slow_ack_pwrup <= '0;
      slow_req_pwrdn <= '0;
    end else if (cdc_safe) begin
      slow_wakeup_en <= reg2hw.wakeup_en.q;
      slow_reset_en  <= reg2hw.reset_en.q;
      slow_main_pdb  <= reg2hw.control.main_pdb.q;
      slow_io_clk_en <= reg2hw.control.io_clk_en.q;
      slow_core_clk_en <= reg2hw.control.core_clk_en.q;
      slow_ack_pwrup <= ack_pwrup;
      slow_req_pwrdn <= req_pwrdn;
    end
  end

  // TODO
  // Need to vote on the differential signals to ensure they are stable
  prim_flop_2sync # (
    .Width($bits(pwr_ast_rsp_t))
  ) i_pok_sync (
    .clk_i  (clk_slow_i),
    .rst_ni (rst_slow_ni),
    .d_i    (pwr_ast_i),
    .q_o    (slow_ast_q)
  );
*/
