Skip to content

Commit e1cdc60

Browse files
committed
[hw,pwrmgr] Ipgen the 'Wait for External Reset' parameter
Signed-off-by: Robert Schilling <[email protected]>
1 parent 753427d commit e1cdc60

File tree

16 files changed

+105
-231
lines changed

16 files changed

+105
-231
lines changed

hw/ip_templates/pwrmgr/data/pwrmgr.hjson.tpl

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,12 +142,14 @@
142142
]
143143

144144
inter_signal_list: [
145+
% if wait_for_external_reset:
145146
{ struct: "pwr_boot_status",
146147
type: "uni",
147148
name: "boot_status",
148149
act: "req",
149150
package: "pwrmgr_pkg",
150151
},
152+
% endif
151153
{ struct: "pwr_ast",
152154
type: "req_rsp",
153155
name: "pwr_ast",
@@ -301,14 +303,6 @@
301303

302304
% endfor
303305

304-
{ name: "PwrFsmWaitForExtRst",
305-
desc: "Wait for external reset to complete",
306-
type: "bit",
307-
default: "0",
308-
local: "false",
309-
expose: "true"
310-
},
311-
312306
{ name: "NumRstReqs",
313307
desc: "Number of peripheral reset requets",
314308
type: "int",

hw/ip_templates/pwrmgr/data/pwrmgr.tpldesc.hjson

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,11 @@
5252
type: "int"
5353
default: "2"
5454
}
55+
{
56+
name: "wait_for_external_reset"
57+
desc: "Wait for external reset requests"
58+
type: "bool"
59+
default: false
60+
}
5561
]
5662
}

hw/ip_templates/pwrmgr/dv/tb.sv renamed to hw/ip_templates/pwrmgr/dv/tb.sv.tpl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ module tb;
1818
wire clk_lc, rst_lc_n;
1919
wire clk_slow, rst_slow_n;
2020
wire [NUM_MAX_INTERRUPTS-1:0] interrupts;
21+
% if wait_for_external_reset:
2122
wire int_reset_req;
23+
% endif
2224

2325
// interfaces
2426
clk_rst_if clk_rst_if (
@@ -48,7 +50,9 @@ module tb;
4850
);
4951

5052
assign interrupts[0] = pwrmgr_if.intr_wakeup;
53+
% if wait_for_external_reset:
5154
assign int_reset_req = tb.dut.internal_reset_req;
55+
% endif
5256

5357
pwrmgr_if pwrmgr_if (
5458
.clk,
@@ -97,8 +101,12 @@ module tb;
97101

98102
.fetch_en_o(pwrmgr_if.fetch_en),
99103
.wakeups_i (pwrmgr_if.wakeups_i),
104+
% if wait_for_external_reset:
100105
// TOOD(#22710): properly cooperate with `pwrmgr_if.rstreqs_i[1]`
101106
.rstreqs_i ({int_reset_req, pwrmgr_if.rstreqs_i[0]}),
107+
% else:
108+
.rstreqs_i (pwrmgr_if.rstreqs_i),
109+
% endif
102110
.ndmreset_req_i(pwrmgr_if.cpu_i.ndmreset_req),
103111

104112
.lc_dft_en_i (pwrmgr_if.lc_dft_en),

hw/ip_templates/pwrmgr/pwrmgr_pkg.core.tpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ filesets:
1111
files_rtl:
1212
depend:
1313
- ${instance_vlnv("lowrisc:ip:pwrmgr_reg")}
14+
% if wait_for_external_reset:
1415
- lowrisc:ip:rom_ctrl_pkg
16+
% endif
1517
files:
1618
- rtl/pwrmgr_pkg.sv
1719
file_type: systemVerilogSource

hw/ip_templates/pwrmgr/rtl/pwrmgr.sv renamed to hw/ip_templates/pwrmgr/rtl/pwrmgr.sv.tpl

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,7 @@ module pwrmgr
1111
import pwrmgr_pkg::*;
1212
import pwrmgr_reg_pkg::*;
1313
#(
14-
parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}},
15-
parameter bit PwrFsmWaitForExtRst = 0
14+
parameter logic [NumAlerts-1:0] AlertAsyncOn = {NumAlerts{1'b1}}
1615
) (
1716
// Clocks and resets
1817
input clk_slow_i,
@@ -62,8 +61,9 @@ module pwrmgr
6261
output lc_ctrl_pkg::lc_tx_t fetch_en_o,
6362
input lc_ctrl_pkg::lc_tx_t lc_hw_debug_en_i,
6463
input lc_ctrl_pkg::lc_tx_t lc_dft_en_i,
65-
64+
% if wait_for_external_reset:
6665
output pwr_boot_status_t boot_status_o,
66+
% endif
6767
// peripherals wakeup and reset requests
6868
input [NumWkups-1:0] wakeups_i,
6969
input [NumRstReqs-1:0] rstreqs_i,
@@ -90,11 +90,6 @@ module pwrmgr
9090
output intr_wakeup_o
9191
9292
);
93-
94-
logic internal_reset_req;
95-
logic strap_sampled;
96-
logic ext_reset_req;
97-
9893
////////////////////////////////////////////////////
9994
// Input handling //
10095
////////////////////////////////////////////////////
@@ -161,25 +156,25 @@ module pwrmgr
161156
// cycles in the fast fsm to generate outputs. However, esc_rst_req_q can be dropped due to
162157
// rst_lc_n, which will cause slow_peri_reqs_masked.rstreqs[ResetEscIdx] to drop.
163158
`ASSERT(PwrmgrSecCmEscToSlowResetReq_A,
164-
esc_rst_req_q |-> ##[1:5] !esc_rst_req_q || slow_peri_reqs_masked.rstreqs[ResetEscIdx],
159+
esc_rst_req_q |-> ${"##"}[1:5] !esc_rst_req_q || slow_peri_reqs_masked.rstreqs[ResetEscIdx],
165160
clk_slow_i, !rst_slow_ni)
166161
`ASSERT(PwrmgrSecCmFsmEscToResetReq_A,
167162
slow_peri_reqs_masked.rstreqs[ResetEscIdx] |->
168-
##[1:4] !slow_peri_reqs_masked.rstreqs[ResetEscIdx] || u_fsm.reset_reqs_i[ResetEscIdx],
163+
${"##"}[1:4] !slow_peri_reqs_masked.rstreqs[ResetEscIdx] || u_fsm.reset_reqs_i[ResetEscIdx],
169164
clk_i, !rst_ni)
170165
`else
171166
`ASSERT(PwrmgrSecCmEscToSlowResetReq_A,
172-
esc_rst_req_d |-> ##[2:3] (
167+
esc_rst_req_d |-> ${"##"}[2:3] (
173168
(!esc_rst_req_d && lc_ctrl_pkg::lc_tx_test_false_loose(fetch_en_o)) ||
174169
slow_peri_reqs_masked.rstreqs[ResetEscIdx]
175170
), clk_slow_i, !rst_slow_ni)
176171
`ASSERT(PwrmgrSlowResetReqToFsmResetReq_A,
177-
slow_peri_reqs_masked.rstreqs[ResetEscIdx] |-> ##1 u_fsm.reset_reqs_i[ResetEscIdx],
172+
slow_peri_reqs_masked.rstreqs[ResetEscIdx] |-> ${"##"}1 u_fsm.reset_reqs_i[ResetEscIdx],
178173
clk_i, !rst_ni)
179174
`endif
180175

181176
`ASSERT(PwrmgrSecCmEscToLCReset_A, u_fsm.reset_reqs_i[ResetEscIdx] &&
182-
u_fsm.state_q == FastPwrStateActive |-> ##4 pwr_rst_o.rst_lc_req == 2'b11,
177+
u_fsm.state_q == FastPwrStateActive |-> ${"##"}4 pwr_rst_o.rst_lc_req == 2'b11,
183178
clk_i, !rst_ni)
184179

185180
always_ff @(posedge clk_lc or negedge rst_lc_n) begin
@@ -515,8 +510,12 @@ module pwrmgr
515510
{NumDebugRstReqs{1'b1}},
516511
{NumIntRstReqs{1'b1}},
517512
slow_reset_en};
518-
513+
% if wait_for_external_reset:
519514
// TODO(#22711): Make this work also when `rstreqs` is structured differently.
515+
logic strap_sampled;
516+
logic internal_reset_req;
517+
logic ext_reset_req;
518+
520519
assign internal_reset_req =|(
521520
slow_peri_reqs.rstreqs &
522521
{{NumSwRstReq{1'b1}}, // SW driven reset
@@ -530,6 +529,7 @@ module pwrmgr
530529
// The MSB of `slow_peri_reqs.rstreqs` is the external reset request. We want it to always
531530
// propagate, in order to continue from the Reset Wait state in the fast FSM.
532531
assign ext_reset_req = slow_peri_reqs.rstreqs[NumRstReqs-1];
532+
% endif
533533
534534
for (genvar i = 0; i < NumWkups; i++) begin : gen_wakeup_status
535535
assign hw2reg.wake_status[i].de = 1'b1;
@@ -602,9 +602,7 @@ module pwrmgr
602602
assign low_power_hint = reg2hw.control.low_power_hint.q == LowPower;
603603
assign low_power_entry = core_sleeping & low_power_hint;
604604

605-
pwrmgr_fsm #(
606-
.PwrFsmWaitForExtRst(PwrFsmWaitForExtRst)
607-
) u_fsm (
605+
pwrmgr_fsm u_fsm (
608606
.clk_i,
609607
.rst_ni,
610608
.clk_slow_i,
@@ -632,8 +630,10 @@ module pwrmgr
632630
.fall_through_o (low_power_fall_through),
633631
.abort_o (low_power_abort),
634632
.clr_hint_o (clr_hint),
633+
% if wait_for_external_reset:
635634
.int_reset_req_i (internal_reset_req),
636635
.ext_reset_req_i (ext_reset_req),
636+
% endif
637637

638638
// rstmgr
639639
.pwr_rst_o (pwr_rst_o),
@@ -667,7 +667,11 @@ module pwrmgr
667667

668668
// pinmux and other peripherals
669669
.strap_o,
670+
% if wait_for_external_reset:
670671
.strap_sampled_o (strap_sampled), // to debug monitoring logic
672+
% else:
673+
.strap_sampled_o (),
674+
% endif
671675
.low_power_o
672676
);
673677

@@ -718,6 +722,7 @@ module pwrmgr
718722
.intr_o (intr_wakeup_o)
719723
);
720724

725+
% if wait_for_external_reset:
721726
////////////////////////////////////////////////////
722727
// Routing sstaus signal outputs for monitoring
723728
////////////////////////////////////////////////////
@@ -728,6 +733,7 @@ module pwrmgr
728733
assign boot_status_o.clk_status = pwr_clk_i;
729734
assign boot_status_o.light_reset_req = internal_reset_req;
730735
assign boot_status_o.strap_sampled = strap_sampled;
736+
% endif
731737

732738
////////////////////////////
733739
/// Assertions

hw/ip_templates/pwrmgr/rtl/pwrmgr_fsm.sv renamed to hw/ip_templates/pwrmgr/rtl/pwrmgr_fsm.sv.tpl

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,7 @@
77

88
`include "prim_assert.sv"
99

10-
module pwrmgr_fsm
11-
import pwrmgr_pkg::*;
12-
import pwrmgr_reg_pkg::*;
13-
#(
14-
parameter bit PwrFsmWaitForExtRst = 0
15-
) (
10+
module pwrmgr_fsm import pwrmgr_pkg::*; import pwrmgr_reg_pkg::*;(
1611
input clk_i,
1712
input rst_ni,
1813
input clk_slow_i,
@@ -38,9 +33,11 @@ module pwrmgr_fsm
3833
output logic abort_o,
3934
output logic clr_hint_o,
4035
output logic clr_cfg_lock_o,
36+
% if wait_for_external_reset:
4137
input logic int_reset_req_i, // internally generated reset request.
4238
// Send to platform to assert reset
4339
input logic ext_reset_req_i, // Internal Req held until ext reset deasserts
40+
% endif
4441

4542
// rstmgr
4643
output pwr_rst_req_t pwr_rst_o,
@@ -126,8 +123,6 @@ module pwrmgr_fsm
126123
logic otp_init;
127124
logic lc_init;
128125
logic low_power_q, low_power_d;
129-
logic ext_rst_req_d, ext_rst_req_q;
130-
logic ext_rst_pending_q;
131126

132127
assign pd_n_rsts_asserted = pwr_rst_i.rst_lc_src_n[PowerDomains-1:OffDomainSelStart] == '0 &
133128
pwr_rst_i.rst_sys_src_n[PowerDomains-1:OffDomainSelStart] == '0;
@@ -162,34 +157,32 @@ module pwrmgr_fsm
162157
// when the reset cause is something else, it is invalid
163158
assign reset_valid = reset_cause_q == LowPwrEntry ? main_pd_ni | pd_n_rsts_asserted :
164159
reset_cause_q == HwReq ? all_rsts_asserted : 1'b0;
160+
% if wait_for_external_reset:
165161

166162
// Provide the ability to control the reset to OpenTitan RoT from an external source. The logic
167163
// below makes sure that when an internal reset request is generated, it is held high until the
168164
// external SoC reset logic asserts and then deasserts deasserts the external reset signal. The
169165
// pwrmgr fast FSM is held in FastPwrStateResetWait state until the external reset deasserts.
170166
// This ensure that the OT reset exit is synchronized with the rest of the SoC & platform.
171-
if (PwrFsmWaitForExtRst) begin : gen_wait2ext_rst
167+
logic ext_rst_req_d, ext_rst_req_q;
168+
logic ext_rst_pending_q;
172169

173-
assign ext_rst_req_d = ext_reset_req_i;
170+
assign ext_rst_req_d = ext_reset_req_i;
174171

175-
always_ff @(posedge clk_i or negedge rst_ni) begin
176-
if (!rst_ni) begin
172+
always_ff @(posedge clk_i or negedge rst_ni) begin
173+
if (!rst_ni) begin
174+
ext_rst_pending_q <= 1'b0;
175+
ext_rst_req_q <= 1'b0;
176+
end else begin
177+
ext_rst_req_q <= ext_rst_req_d;
178+
if (ext_rst_pending_q && !ext_rst_req_d && ext_rst_req_q) begin
177179
ext_rst_pending_q <= 1'b0;
178-
ext_rst_req_q <= 1'b0;
179-
end else begin
180-
ext_rst_req_q <= ext_rst_req_d;
181-
if (ext_rst_pending_q && !ext_rst_req_d && ext_rst_req_q) begin
182-
ext_rst_pending_q <= 1'b0;
183-
end else if (int_reset_req_i) begin
184-
ext_rst_pending_q <= 1'b1;
185-
end
180+
end else if (int_reset_req_i) begin
181+
ext_rst_pending_q <= 1'b1;
186182
end
187183
end
188-
end else begin : gen_no_wait2ext_rst
189-
assign ext_rst_pending_q = 1'b0;
190-
assign ext_rst_req_q = 1'b0;
191-
assign ext_rst_req_d = 1'b0;
192-
end : gen_no_wait2ext_rst
184+
end
185+
% endif
193186

194187
always_ff @(posedge clk_i or negedge rst_ni) begin
195188
if (!rst_ni) begin
@@ -509,9 +502,12 @@ module pwrmgr_fsm
509502
// cleared before proceeding. This also implies if the system is under a persistent
510503
// glitch, or if someone just turned off the power before pwrmgr turns it off itself,
511504
// we will stay stuck here and perpetually hold the system in reset.
505+
% if wait_for_external_reset:
512506
// Need to hold in reset until external reset deasserts (i.e. ext_rst_pending_q goes low)
513-
if (reset_valid && !reset_reqs_i[ResetMainPwrIdx]
514-
&& !ext_rst_pending_q ) begin
507+
if (reset_valid && !reset_reqs_i[ResetMainPwrIdx] && !ext_rst_pending_q) begin
508+
% else:
509+
if (reset_valid && !reset_reqs_i[ResetMainPwrIdx]) begin
510+
% endif
515511
state_d = FastPwrStateLowPower;
516512
end
517513
end

hw/ip_templates/pwrmgr/rtl/pwrmgr_pkg.sv renamed to hw/ip_templates/pwrmgr/rtl/pwrmgr_pkg.sv.tpl

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,16 +154,18 @@ package pwrmgr_pkg;
154154
typedef struct packed {
155155
logic ndmreset_req;
156156
} pwrmgr_cpu_t;
157+
% if wait_for_external_reset:
157158
158159
typedef struct packed {
159-
lc_ctrl_pkg::lc_tx_t cpu_fetch_en;
160-
rom_ctrl_pkg::pwrmgr_data_t [pwrmgr_reg_pkg::NumRomInputs-1:0] rom_ctrl_status;
161-
logic lc_done;
162-
logic otp_done;
163-
logic strap_sampled;
164-
logic light_reset_req;
165-
pwr_clk_rsp_t clk_status;
160+
lc_ctrl_pkg::lc_tx_t cpu_fetch_en;
161+
rom_ctrl_pkg::pwrmgr_data_t [pwrmgr_reg_pkg::NumRomInputs-1:0] rom_ctrl_status;
162+
logic lc_done;
163+
logic otp_done;
164+
logic strap_sampled;
165+
logic light_reset_req;
166+
pwr_clk_rsp_t clk_status;
166167
} pwr_boot_status_t;
168+
% endif
167169
168170
// exported resets
169171
@@ -203,7 +205,7 @@ package pwrmgr_pkg;
203205

204206
// fast fsm state enum
205207
// Encoding generated with:
206-
// $ ./util/design/sparse-fsm-encode.py -d 5 -m 19 -n 12 \
208+
// $ ./util/design/sparse-fsm-encode.py -d 5 -m 19 -n 12 ${"\\"}
207209
// -s 3096160381 --language=sv
208210
//
209211
// Hamming distance histogram:
@@ -251,7 +253,7 @@ package pwrmgr_pkg;
251253
} fast_pwr_state_e;
252254
253255
// Encoding generated with:
254-
// $ ./util/design/sparse-fsm-encode.py -d 5 -m 12 -n 10 \
256+
// $ ./util/design/sparse-fsm-encode.py -d 5 -m 12 -n 10 ${"\\"}
255257
// -s 1726685338 --language=sv
256258
//
257259
// Hamming distance histogram:

0 commit comments

Comments
 (0)