blob: 07a73106bf30d52b43ae067ba277e68fbfb8bea1 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Power Manager module to find slow clock edges
// The clock is not used directly to avoid STA issues, instead a toggle
// pulse is used.
`include "prim_assert.sv"
module pwrmgr_cdc_pulse (
input clk_slow_i,
input clk_i,
input rst_ni,
input rst_slow_ni,
input start_i,
input stop_i,
output logic pulse_o
);
logic slow_toggle_pq, slow_toggle_nq;
logic clk_slow_pq, clk_slow_nq;
logic clk_slow_pq2, clk_slow_nq2;
logic toggle;
logic valid;
// toggle pulse generated on positive edge
always_ff @(posedge clk_slow_i or negedge rst_slow_ni) begin
if (!rst_slow_ni) begin
slow_toggle_pq <= 1'b0;
end else begin
slow_toggle_pq <= ~slow_toggle_pq;
end
end
// toggle pulse generated on negative edge
always_ff @(negedge clk_slow_i or negedge rst_slow_ni) begin
if (!rst_slow_ni) begin
slow_toggle_nq <= 1'b0;
end else begin
slow_toggle_nq <= ~slow_toggle_nq;
end
end
prim_flop_2sync # (
.Width(1)
) i_pos_sync (
.clk_i,
.rst_ni,
.d_i(slow_toggle_pq),
.q_o(clk_slow_pq)
);
prim_flop_2sync # (
.Width(1)
) i_neg_sync (
.clk_i,
.rst_ni,
.d_i(slow_toggle_nq),
.q_o(clk_slow_nq)
);
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
clk_slow_pq2 <= 1'b0;
clk_slow_nq2 <= 1'b0;
end else begin
clk_slow_pq2 <= clk_slow_pq;
clk_slow_nq2 <= clk_slow_nq;
end
end
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
valid <= 1'b0;
end else if (valid && stop_i) begin
valid <= 1'b0;
end else if (!valid && toggle && start_i) begin
valid <= 1'b1;
end
end
// toggle is found on either positive and negative edges of clk_slow_i
assign toggle = clk_slow_pq2 ^ clk_slow_pq | clk_slow_nq2 ^ clk_slow_nq;
assign pulse_o = valid & toggle;
endmodule // pwrmgr