Skip to content

Commit

Permalink
[pwrmgr] Insert Interlock between External SoC Reset and Pwrmgr FSM
Browse files Browse the repository at this point in the history
1. Internally generated reset request passed to SoC.
2. Create a sticky assertion internally to log request.
   Sticky flag cleared only upon external reset deassertion
3. SoC transfer this request to platform to assert external reset
4. External SoC reset deasserts after some time
5. Pwrmgr stays in FastPwrStateRstWait state until the external SoC reset deasserts.
6. Boot / reset sequence continues
7. Also fixes the external reset signal glitch filter to use the por reset,
   This is required to make sure that the external reset state does not
   self-reset once asserted & faithfully forwards that state to pwrmgr
8. Added some debug visibility signals for pwrmgr
9. Added temporary reset loop back path in pwrmgr tb to
   translate internal reset req from OT --> ext reset from SoC to OT.
   Needs a proper fix in testbench

Signed-off-by: Neeraj Upasani <[email protected]>
  • Loading branch information
Neeraj Upasani committed Apr 16, 2024
1 parent e65178a commit 0258b20
Show file tree
Hide file tree
Showing 17 changed files with 212 additions and 53 deletions.
6 changes: 6 additions & 0 deletions hw/ip/pwrmgr/data/pwrmgr.hjson.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@
],

inter_signal_list: [
{ struct: "pwr_boot_status",
type: "uni",
name: "boot_status",
act: "req",
package: "pwrmgr_pkg",
},
{ struct: "pwr_ast",
type: "req_rsp",
name: "pwr_ast",
Expand Down
4 changes: 3 additions & 1 deletion hw/ip/pwrmgr/dv/tb.sv
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module tb;
wire clk_slow, rst_slow_n;
wire devmode;
wire [NUM_MAX_INTERRUPTS-1:0] interrupts;
wire int_reset_req;

// interfaces
clk_rst_if clk_rst_if (
Expand Down Expand Up @@ -49,6 +50,7 @@ module tb;
);

assign interrupts[0] = pwrmgr_if.intr_wakeup;
assign int_reset_req = tb.dut.light_reset_req ;

pwrmgr_if pwrmgr_if (
.clk,
Expand Down Expand Up @@ -97,7 +99,7 @@ module tb;

.fetch_en_o(pwrmgr_if.fetch_en),
.wakeups_i (pwrmgr_if.wakeups_i),
.rstreqs_i (pwrmgr_if.rstreqs_i),
.rstreqs_i ({int_reset_req,pwrmgr_if.rstreqs_i[0]}),
.ndmreset_req_i(pwrmgr_if.cpu_i.ndmreset_req),

.lc_dft_en_i (pwrmgr_if.lc_dft_en),
Expand Down
40 changes: 36 additions & 4 deletions hw/ip/pwrmgr/rtl/pwrmgr.sv
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,13 @@ module pwrmgr
input pwr_cpu_t pwr_cpu_i,
// SEC_CM: LC_CTRL.INTERSIG.MUBI
output lc_ctrl_pkg::lc_tx_t fetch_en_o,
input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i,
input lc_ctrl_pkg::lc_tx_t lc_dft_en_i,
input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i,
input lc_ctrl_pkg::lc_tx_t lc_dft_en_i,

output pwr_boot_status_t boot_status_o,
// peripherals wakeup and reset requests
input [NumWkups-1:0] wakeups_i,
input [NumRstReqs-1:0] rstreqs_i,
input [NumWkups-1:0] wakeups_i,
input [NumRstReqs-1:0] rstreqs_i,

// cpu related inputs
input ndmreset_req_i,
Expand All @@ -88,6 +89,11 @@ module pwrmgr
output intr_wakeup_o

);

logic internal_reset_req;
logic strap_sampled;
logic ext_reset_req;

////////////////////////////////////////////////////
// Input handling //
////////////////////////////////////////////////////
Expand Down Expand Up @@ -504,6 +510,19 @@ module pwrmgr
{NumIntRstReqs{1'b1}},
slow_reset_en};

assign internal_reset_req =|(
slow_peri_reqs.rstreqs &
{{NumSwRstReq{1'b1}}, // SW driven reset
{NumDebugRstReqs{1'b1}}, // debugger reset
{NumIntRstReqs{1'b1}}, // {ESC reset, slow_fsm}
// exclude the external async reset
{1'b0,slow_reset_en[0]}
}
);
assign ext_reset_req = slow_peri_reqs.rstreqs[NumRstReqs-1] ; // bit1 is ext rst
// Do not mask.
// Always want to propagate

for (genvar i = 0; i < NumWkups; i++) begin : gen_wakeup_status
assign hw2reg.wake_status[i].de = 1'b1;
assign hw2reg.wake_status[i].d = peri_reqs_masked.wakeups[i];
Expand Down Expand Up @@ -602,6 +621,8 @@ module pwrmgr
.fall_through_o (low_power_fall_through),
.abort_o (low_power_abort),
.clr_hint_o (clr_hint),
.light_rst_req_i (internal_reset_req),
.ext_reset_req_i (ext_reset_req),

// rstmgr
.pwr_rst_o (pwr_rst_o),
Expand Down Expand Up @@ -635,6 +656,7 @@ module pwrmgr

// pinmux and other peripherals
.strap_o,
.strap_sampled_o (strap_sampled), // to debug monitoring logic
.low_power_o
);

Expand Down Expand Up @@ -685,6 +707,16 @@ module pwrmgr
.intr_o (intr_wakeup_o)
);

////////////////////////////////////////////////////
// Routing sstaus signal outputs for monitoring
////////////////////////////////////////////////////
assign boot_status_o.cpu_fetch_en = fetch_en_o;
assign boot_status_o.rom_ctrl_status = rom_ctrl_i;
assign boot_status_o.lc_done = pwr_lc_i.lc_done;
assign boot_status_o.otp_done = otp_rsp.otp_done;
assign boot_status_o.clk_status = pwr_clk_i;
assign boot_status_o.light_reset_req = internal_reset_req;
assign boot_status_o.strapSampled = strap_sampled;

////////////////////////////
/// Assertions
Expand Down
39 changes: 33 additions & 6 deletions hw/ip/pwrmgr/rtl/pwrmgr_fsm.sv
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;(
output logic abort_o,
output logic clr_hint_o,
output logic clr_cfg_lock_o,
input logic light_rst_req_i, // internally generated reset request.
// Send to platform to assert reset
input logic ext_reset_req_i, // Internal Req held until ext reset deasserts

// rstmgr
output pwr_rst_req_t pwr_rst_o,
Expand Down Expand Up @@ -63,6 +66,7 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;(

// pinmux
output logic strap_o,
output logic strap_sampled_o,
output logic low_power_o,

// processing elements
Expand Down Expand Up @@ -103,7 +107,7 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;(

// strap sample should only happen on cold boot or when the
// the system goes through a reset cycle
logic strap_sampled;
// [output] logic strap_sampled;

// disable processing element fetching
lc_ctrl_pkg::lc_tx_t fetch_en_q, fetch_en_d;
Expand All @@ -118,6 +122,8 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;(
logic otp_init;
logic lc_init;
logic low_power_q, low_power_d;
logic ext_rst_req_d, ext_rst_req_q;
logic light_rst_req_q;

assign pd_n_rsts_asserted = pwr_rst_i.rst_lc_src_n[PowerDomains-1:OffDomainSelStart] == '0 &
pwr_rst_i.rst_sys_src_n[PowerDomains-1:OffDomainSelStart] == '0;
Expand Down Expand Up @@ -153,6 +159,24 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;(
assign reset_valid = reset_cause_q == LowPwrEntry ? main_pd_ni | pd_n_rsts_asserted :
reset_cause_q == HwReq ? all_rsts_asserted : 1'b0;

assign ext_rst_req_d = ext_reset_req_i;


always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
light_rst_req_q <= 0;
ext_rst_req_q <= 0;
end else begin
ext_rst_req_q <= ext_rst_req_d;
if(light_rst_req_q && !ext_rst_req_d && ext_rst_req_q) begin
light_rst_req_q <= '0;
end else if (light_rst_req_i) begin
light_rst_req_q <= 1'b1;
end
end
end


always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
ack_pwrup_q <= 1'b0;
Expand Down Expand Up @@ -180,11 +204,11 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;(

always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
strap_sampled <= 1'b0;
strap_sampled_o <= 1'b0;
end else if (&rst_sys_req_q) begin
strap_sampled <= 1'b0;
strap_sampled_o <= 1'b0;
end else if (strap_o) begin
strap_sampled <= 1'b1;
strap_sampled_o <= 1'b1;
end
end

Expand Down Expand Up @@ -338,7 +362,7 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;(
end

FastPwrStateStrap: begin
strap_o = ~strap_sampled;
strap_o = ~strap_sampled_o;
state_d = FastPwrStateRomCheckDone;
end

Expand Down Expand Up @@ -471,7 +495,10 @@ module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;(
// cleared before proceeding. This also implies if the system is under a persistent
// glitch, or if someone just turned off the power before pwrmgr turns it off itself,
// we will stay stuck here and perpetually hold the system in reset.
if (reset_valid && !reset_reqs_i[ResetMainPwrIdx]) begin
// NumRstReqs-1 is the External SoC reset request.
// Need to hold in reset until external reset deasserts (i.e. light_rst_req_q goes low)
if (reset_valid && !reset_reqs_i[ResetMainPwrIdx]
&& !light_rst_req_q ) begin
state_d = FastPwrStateLowPower;
end
end
Expand Down
10 changes: 10 additions & 0 deletions hw/ip/pwrmgr/rtl/pwrmgr_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,16 @@ package pwrmgr_pkg;
logic ndmreset_req;
} pwrmgr_cpu_t;

typedef struct packed {
lc_ctrl_pkg::lc_tx_t cpu_fetch_en;
rom_ctrl_pkg::pwrmgr_data_t [pwrmgr_reg_pkg::NumRomInputs-1:0] rom_ctrl_status;
logic lc_done;
logic otp_done;
logic strapSampled;
logic light_reset_req;
pwr_clk_rsp_t clk_status;
} pwr_boot_status_t;

// exported resets

// default value for pwrmgr_ast_rsp_t (for dangling ports)
Expand Down
47 changes: 44 additions & 3 deletions hw/top_darjeeling/data/autogen/top_darjeeling.gen.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,7 @@
domains:
[
Aon
"0"
]
shadowed: false
sw: false
Expand Down Expand Up @@ -310,7 +311,6 @@
domains:
[
Aon
"0"
]
shadowed: false
sw: false
Expand Down Expand Up @@ -2112,6 +2112,20 @@
param_list: []
inter_signal_list:
[
{
name: boot_status
struct: pwr_boot_status
package: pwrmgr_pkg
type: uni
act: req
width: 1
inst_name: pwrmgr_aon
default: ""
external: true
top_signame: pwrmgr_boot_status
conn_type: false
index: -1
}
{
name: pwr_ast
struct: pwr_ast
Expand Down Expand Up @@ -3687,9 +3701,9 @@
name: lc
domain: "0"
}
rst_aon_ni:
rst_por_ni:
{
name: lc_aon
name: por_io_div4
domain: "0"
}
}
Expand Down Expand Up @@ -9604,6 +9618,7 @@
ast.ram_1p_cfg: ram_1p_cfg
ast.spi_ram_2p_cfg: spi_ram_2p_cfg
ast.rom_cfg: rom_cfg
pwrmgr_aon.boot_status: pwrmgr_boot_status
clkmgr_aon.jitter_en: clk_main_jitter_en
clkmgr_aon.io_clk_byp_req: io_clk_byp_req
clkmgr_aon.io_clk_byp_ack: io_clk_byp_ack
Expand Down Expand Up @@ -18416,6 +18431,20 @@
top_signame: spi_host0_tl
index: -1
}
{
name: boot_status
struct: pwr_boot_status
package: pwrmgr_pkg
type: uni
act: req
width: 1
inst_name: pwrmgr_aon
default: ""
external: true
top_signame: pwrmgr_boot_status
conn_type: false
index: -1
}
{
name: pwr_ast
struct: pwr_ast
Expand Down Expand Up @@ -23530,6 +23559,18 @@
index: -1
netname: ast_rom_cfg
}
{
package: pwrmgr_pkg
struct: pwr_boot_status
signame: pwrmgr_boot_status_o
width: 1
type: uni
default: ""
direction: out
conn_type: false
index: -1
netname: pwrmgr_boot_status
}
{
package: prim_mubi_pkg
struct: mubi4
Expand Down
8 changes: 7 additions & 1 deletion hw/top_darjeeling/data/top_darjeeling.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -510,7 +510,12 @@
type: "soc_proxy",
clock_srcs: {clk_i: "main", clk_aon_i: "aon"},
clock_group: "infra",
reset_connections: {rst_ni: "lc", rst_aon_ni: "lc_aon"},
reset_connections: {
rst_ni: "lc",
rst_por_ni: "por_io_div4" //{
// name: "por_io_div4"
// },
}
base_addrs: {
core: {hart: "0x22030000"},
ctn: {hart: "0x40000000"},
Expand Down Expand Up @@ -1214,6 +1219,7 @@
'ast.ram_1p_cfg' : 'ram_1p_cfg',
'ast.spi_ram_2p_cfg' : 'spi_ram_2p_cfg',
'ast.rom_cfg' : 'rom_cfg',
'pwrmgr_aon.boot_status' : 'pwrmgr_boot_status',
'clkmgr_aon.jitter_en' : 'clk_main_jitter_en',
'clkmgr_aon.io_clk_byp_req' : 'io_clk_byp_req',
'clkmgr_aon.io_clk_byp_ack' : 'io_clk_byp_ack',
Expand Down
2 changes: 1 addition & 1 deletion hw/top_darjeeling/dv/autogen/rstmgr_tgl_excl.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_n[1]
-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_io_n[1]
-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_io_div2_n[1]
-node tb.dut*.u_rstmgr_aon.resets_o.rst_por_io_div4_n[1]
-node tb.dut*.u_rstmgr_aon.resets_o.rst_lc_aon_n[1]
-node tb.dut*.u_rstmgr_aon.resets_o.rst_lc_io_div2_n[1]
-node tb.dut*.u_rstmgr_aon.resets_o.rst_sys_n[0]
-node tb.dut*.u_rstmgr_aon.resets_o.rst_sys_io_div4_n[1]
Expand Down
6 changes: 6 additions & 0 deletions hw/top_darjeeling/ip/pwrmgr/data/autogen/pwrmgr.hjson
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,12 @@
],

inter_signal_list: [
{ struct: "pwr_boot_status",
type: "uni",
name: "boot_status",
act: "req",
package: "pwrmgr_pkg",
},
{ struct: "pwr_ast",
type: "req_rsp",
name: "pwr_ast",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ package rstmgr_env_pkg;
"u_daon_por_io",
"u_daon_por_io_div2",
"u_daon_por_io_div4",
"u_d0_por_io_div4",
"u_daon_por_usb",
"u_d0_por_usb",
"u_d0_lc",
"u_d0_lc_shadowed",
"u_daon_lc",
"u_daon_lc_shadowed",
"u_daon_lc_aon",
"u_d0_lc_aon",
"u_daon_lc_io",
"u_d0_lc_io",
"u_daon_lc_io_div2",
Expand Down
Loading

0 comments on commit 0258b20

Please sign in to comment.