blob: a97acf1cf3a3d424c858c669210b6d399a68144a [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// This module stretches the POR
//
module rstmgr_por #(
parameter int FilterStages = 3,
parameter int unsigned StretchCount = 32
) (
input clk_i,
input rst_ni,
input scan_rst_ni,
input scanmode_i,
output logic rst_no
);
localparam int CtrWidth = $clog2(StretchCount+1);
logic rst_root_n_pre_mux, rst_root_n;
logic [FilterStages-1:0] rst_filter_n;
logic rst_stable;
logic rst_clean_n;
logic [CtrWidth-1:0] cnt;
logic cnt_en;
// sync the POR
prim_flop_2sync #(
.Width(1),
.ResetValue('0)
) rst_sync (
.clk_i(clk_i),
.rst_ni(rst_ni),
.d_i(1'b1),
.q_o(rst_root_n_pre_mux)
);
prim_clock_mux2 #(
.NoFpgaBufG(1'b1)
) u_rst_root_mux (
.clk0_i(rst_root_n_pre_mux),
.clk1_i(scan_rst_ni),
.sel_i(scanmode_i),
.clk_o(rst_root_n)
);
// filter the POR
always_ff @(posedge clk_i or negedge rst_root_n) begin
if (!rst_root_n) begin
rst_filter_n <= '0;
end else begin
rst_filter_n <= {rst_filter_n[0 +: FilterStages-1], 1'b1};
end
end
// The stable is a vote of all filter stages.
// Only when all the stages agree is the reset considered stable and count allowed.
prim_clock_mux2 #(
.NoFpgaBufG(1'b1)
) u_rst_clean_mux (
.clk0_i(rst_filter_n[FilterStages-1]),
.clk1_i(scan_rst_ni),
.sel_i(scanmode_i),
.clk_o(rst_clean_n)
);
assign rst_stable = &rst_filter_n;
assign cnt_en = rst_stable & !rst_no;
// stretch the POR
logic rst_nd, rst_nq;
assign rst_nd = ~rst_stable ? 1'b0 :
cnt_en & (cnt == StretchCount[CtrWidth-1:0]) ? 1'b1 : rst_nq;
always_ff @(posedge clk_i or negedge rst_clean_n) begin
if (!rst_clean_n) begin
cnt <= '0;
end else if (!rst_stable) begin
cnt <= '0;
end else if (cnt_en) begin
cnt <= cnt + 1'b1;
end
end
prim_flop #(
.Width(1),
.ResetValue('0)
) u_rst_flop (
.clk_i,
.rst_ni(rst_clean_n),
.d_i(rst_nd),
.q_o(rst_nq)
);
prim_clock_mux2 #(
.NoFpgaBufG(1'b1)
) u_rst_out_mux (
.clk0_i(rst_nq),
.clk1_i(scan_rst_ni),
.sel_i(scanmode_i),
.clk_o(rst_no)
);
endmodule // rstmgr_por