../src/lowrisc_ip_rstmgr_0.1/rtl/rstmgr_por.sv Cov: 100%
1: // Copyright lowRISC contributors.
2: // Licensed under the Apache License, Version 2.0, see LICENSE for details.
3: // SPDX-License-Identifier: Apache-2.0
4: //
5: // This module stretches the POR
6: //
7:
8: `include "prim_assert.sv"
9:
10: module rstmgr_por #(
11: parameter int FilterStages = 3,
12: parameter int StretchCount = 32
13: ) (
14: input clk_i,
15: input rst_ni,
16: input pok_i, // TODO: This should not be an actual separate port but the POR itself
17: // However, this cannot be done until AST integration is done.
18: output logic rst_no
19: );
20: localparam int CtrWidth = $clog2(StretchCount+1);
21:
22: logic rst_root_n;
23: logic [FilterStages-1:0] rst_filter_n;
24: logic rst_stable;
25: logic rst_clean_n;
26: logic [CtrWidth-1:0] cnt;
27: logic cnt_en;
28:
29: // sync the POR
30: prim_flop_2sync #(
31: .Width(1),
32: .ResetValue(0)
33: ) rst_sync (
34: .clk_i(clk_i),
35: .rst_ni(rst_ni),
36: .d(1'b1),
37: .q(rst_root_n)
38: );
39:
40: // filter the POR
41: always_ff @(posedge clk_i or negedge rst_root_n) begin
42: if (!rst_root_n) begin
43: rst_filter_n <= '0;
44: end else if (pok_i) begin // once AST is in, this conditional should not be here.
45: rst_filter_n <= {rst_filter_n[0 +: FilterStages-1], 1'b1};
46: end
47: end
48:
49: // The stable is a vote of all filter stages.
50: // Only when all the stages agree is the reset considered stable and count allowed.
51: assign rst_clean_n = rst_filter_n[FilterStages-1];
52: assign rst_stable = &rst_filter_n;
53: assign cnt_en = rst_stable & !rst_no;
54:
55: // stretch the POR
56: always_ff @(posedge clk_i or negedge rst_clean_n) begin
57: if (!rst_clean_n) begin
58: cnt <= '0;
59: rst_no <= '0;
60: end else if (!rst_stable) begin
61: cnt <= '0;
62: rst_no <= '0;
63: end else if (cnt_en && cnt == StretchCount) begin
64: rst_no <= 1'b1;
65: end else if (cnt_en) begin
66: cnt <= cnt + 1'b1;
67: end
68: end
69:
70: endmodule // rstmgr_por
71: