../src/lowrisc_ip_rstmgr_0.1/rtl/rstmgr_ctrl.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 implements generic reset controls
6: //
7:
8: `include "prim_assert.sv"
9:
10: module rstmgr_ctrl import rstmgr_pkg::*; #(
11: parameter int PowerDomains = 2,
12: localparam int OffDomains = PowerDomains - 1
13: ) (
14: input clk_i,
15: input rst_ni,
16: input [PowerDomains-1:0] rst_req_i,
17: input [PowerDomains-1:0] rst_parent_ni, // parent reset
18: output logic [PowerDomains-1:0] rst_no
19: );
20:
21: // The code below always assumes the always on domain is index 0
22: `ASSERT_INIT(AlwaysOnIndex_A, ALWAYS_ON_SEL == 0)
23:
24: // when there are multiple on domains, the latter 1 should become another parameter
25: localparam int OffDomainSelStart = ALWAYS_ON_SEL + 1;
26:
27: // the always on root reset
28: logic rst_aon_n;
29:
30: // the remaining resets
31: logic [OffDomains-1:0] rst_pd_n;
32:
33: // Parent resets may assert asynchronously, so we need to sync before using it as part
34: // of the control path
35: logic [PowerDomains-1:0] rst_parent_synced;
36: prim_flop_2sync #(
37: .Width(PowerDomains),
38: .ResetValue(0)
39: ) u_lc (
40: .clk_i(clk_i),
41: .rst_ni(rst_ni),
42: .d(rst_parent_ni),
43: .q(rst_parent_synced)
44: );
45:
46: // always on handling
47: always_ff @(posedge clk_i or negedge rst_ni) begin
48: if (!rst_ni) begin
49: rst_aon_n <= '0;
50: end else begin
51: // if the parent is in reset, OR there's an always on reset request
52: // reset this node
53: rst_aon_n <= ~rst_req_i[ALWAYS_ON_SEL] & rst_parent_synced[ALWAYS_ON_SEL];
54: end
55: end
56:
57: // the non-always-on domains
58: // These reset whenever the always on domain reset, to ensure power definition consistency.
59: // By extension, they also reset whenever the root (rst_ni) resets
60: always_ff @(posedge clk_i or negedge rst_aon_n) begin
61: if (!rst_aon_n) begin
62: rst_pd_n <= '0;
63: end else begin
64: rst_pd_n <= ~rst_req_i[OffDomainSelStart +: OffDomains] &
65: rst_parent_synced[OffDomainSelStart +: OffDomains];
66: end
67: end
68:
69: assign rst_no = {rst_pd_n, rst_aon_n};
70:
71: endmodule // rstmgr_ctrl
72: