../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: