-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathmci_boot_seqr.sv
More file actions
296 lines (263 loc) · 8.84 KB
/
mci_boot_seqr.sv
File metadata and controls
296 lines (263 loc) · 8.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
`include "caliptra_prim_assert.sv"
`include "caliptra_sva.svh"
module mci_boot_seqr
import mci_pkg::*;
#(
parameter MIN_MCU_RST_COUNTER_WIDTH = 4 // Determines the minimum time MCU is in reset
)
(
input logic clk,
input logic mci_rst_b,
// DFT
input scan_mode,
// Reset controls
output logic mcu_rst_b,
output logic cptra_rst_b,
// MCU Halt Signals
output logic mcu_cpu_halt_req_o,
input logic mcu_cpu_halt_ack_i,
input logic mcu_cpu_halt_status_i,
// Internal signals
input logic caliptra_boot_go,
input logic mci_bootfsm_go,
input logic mcu_rst_req,
output logic mcu_reset_once, // Has MCU been reset before?
output mci_boot_fsm_state_e boot_fsm,
// SoC signals
input logic mci_boot_seq_brkpoint,
input logic mcu_sram_fw_exec_region_lock,
input logic mcu_no_rom_config, // Determines boot sequencer boot flow
// LCC Signals
input logic lc_done,
output logic lc_init,
// FC Signals
input logic fc_opt_done,
output logic fc_opt_init
// Caliptra signals
);
mci_boot_fsm_state_e boot_fsm_nxt;
mci_boot_fsm_state_e boot_fsm_prev;
logic lc_done_sync;
logic lc_init_nxt;
logic fc_opt_done_sync;
logic fc_opt_init_nxt;
logic mci_boot_seq_brkpoint_sync;
logic mcu_no_rom_config_sync;
logic mcu_rst_b_ff ;
logic cptra_rst_b_ff;
logic mcu_rst_b_nxt;
logic cptra_rst_b_nxt;
logic mcu_reset_once_nxt;
logic mcu_cpu_halt_req_nxt;
logic [MIN_MCU_RST_COUNTER_WIDTH-1:0] min_mcu_rst_count;
logic [MIN_MCU_RST_COUNTER_WIDTH-1:0] min_mcu_rst_count_nxt;
logic min_mcu_rst_count_elapsed;
logic min_mcu_rst_count_elapsed_nxt;
/////////////////////////////////////////////////
// DFT
/////////////////////////////////////////////////
assign mcu_rst_b = scan_mode ? mcu_rst_b : mcu_rst_b_ff;
assign cptra_rst_b = scan_mode ? cptra_rst_b : cptra_rst_b_ff;
/////////////////////////////////////////////////
// Sync signals into local clock domain
/////////////////////////////////////////////////
caliptra_prim_flop_2sync #(
.Width(1)
) u_prim_flop_2sync_lc_done (
.clk_i(clk),
.rst_ni(mci_rst_b),
.d_i(lc_done),
.q_o(lc_done_sync));
caliptra_prim_flop_2sync #(
.Width(1)
) u_prim_flop_2sync_fc_opt_done (
.clk_i(clk),
.rst_ni(mci_rst_b),
.d_i(fc_opt_done),
.q_o(fc_opt_done_sync));
caliptra_prim_flop_2sync #(
.Width(1)
) u_prim_flop_2sync_mci_boot_seq_brkpoint (
.clk_i(clk),
.rst_ni(mci_rst_b),
.d_i(mci_boot_seq_brkpoint),
.q_o(mci_boot_seq_brkpoint_sync));
caliptra_prim_flop_2sync #(
.Width(1)
) u_prim_flop_2sync_mcu_no_rom_config (
.clk_i(clk),
.rst_ni(mci_rst_b),
.d_i(mcu_no_rom_config),
.q_o(mcu_no_rom_config_sync));
/////////////////////////////////////////////////
// Boot FSM
/////////////////////////////////////////////////
always_ff @(posedge clk or negedge mci_rst_b) begin
if(!mci_rst_b) begin
boot_fsm <= BOOT_IDLE;
boot_fsm_prev <= BOOT_IDLE;
fc_opt_init <= '0;
lc_init <= '0;
mcu_rst_b_ff <= '0;
cptra_rst_b_ff <= '0;
mcu_reset_once <= '0;
min_mcu_rst_count_elapsed <= '0;
min_mcu_rst_count <= '0;
end
else begin
boot_fsm <= boot_fsm_nxt;
boot_fsm_prev <= (boot_fsm != boot_fsm_nxt) ? boot_fsm : boot_fsm_prev; // Capture where FSM came from
fc_opt_init <= fc_opt_init_nxt;
lc_init <= lc_init_nxt;
mcu_rst_b_ff <= mcu_rst_b_nxt;
cptra_rst_b_ff <= cptra_rst_b_nxt;
mcu_reset_once <= mcu_reset_once_nxt;
min_mcu_rst_count_elapsed <= min_mcu_rst_count_elapsed_nxt;
min_mcu_rst_count <= min_mcu_rst_count_nxt;
end
end
always_comb begin
boot_fsm_nxt = boot_fsm;
fc_opt_init_nxt = fc_opt_init;
lc_init_nxt = lc_init;
mcu_rst_b_nxt = mcu_rst_b_ff;
cptra_rst_b_nxt = cptra_rst_b_ff;
mcu_reset_once_nxt = mcu_reset_once;
mcu_cpu_halt_req_nxt = 1'b0;
unique case(boot_fsm)
BOOT_IDLE: begin
// Can only transition into IDLE on MCI reset
// If this changes we need to add init signal values
// for FC, LCC, MCU, CPTRA
boot_fsm_nxt = BOOT_OTP_FC;
end
BOOT_OTP_FC: begin
fc_opt_init_nxt = 1'b1;
if (fc_opt_done_sync) begin
boot_fsm_nxt = BOOT_LCC;
end
end
BOOT_LCC: begin
lc_init_nxt = 1'b1;
if(lc_done_sync) begin
boot_fsm_nxt = BOOT_BREAKPOINT_CHECK;
end
end
BOOT_BREAKPOINT_CHECK: begin
if(mci_boot_seq_brkpoint_sync) begin
boot_fsm_nxt = BOOT_BREAKPOINT;
end
else if (mcu_no_rom_config_sync) begin
boot_fsm_nxt = BOOT_WAIT_CPTRA_GO;
end
else begin
boot_fsm_nxt = BOOT_MCU;
end
end
BOOT_BREAKPOINT: begin
if (mci_bootfsm_go) begin
if (mcu_no_rom_config_sync) begin
boot_fsm_nxt = BOOT_WAIT_CPTRA_GO;
end
else begin
boot_fsm_nxt = BOOT_MCU;
end
end
end
BOOT_MCU: begin
if (boot_fsm_prev == BOOT_RST_MCU) begin
boot_fsm_nxt = BOOT_WAIT_MCU_RST_REQ;
end
else begin
boot_fsm_nxt = BOOT_WAIT_CPTRA_GO;
end
mcu_rst_b_nxt = 1'b1;
end
BOOT_WAIT_CPTRA_GO: begin
if(caliptra_boot_go) begin
boot_fsm_nxt = BOOT_CPTRA;
end
end
BOOT_CPTRA: begin
cptra_rst_b_nxt = 1'b1;
boot_fsm_nxt = BOOT_WAIT_MCU_RST_REQ;
end
BOOT_WAIT_MCU_RST_REQ: begin
if(mcu_rst_req) begin
boot_fsm_nxt = BOOT_HALT_MCU;
end
end
BOOT_HALT_MCU: begin
if(mcu_cpu_halt_ack_i) begin
boot_fsm_nxt = BOOT_WAIT_MCU_HALTED;
end
mcu_cpu_halt_req_nxt = 1'b1;
end
BOOT_WAIT_MCU_HALTED: begin
if (mcu_cpu_halt_status_i) begin
boot_fsm_nxt = BOOT_RST_MCU;
end
end
BOOT_RST_MCU: begin
mcu_rst_b_nxt = 1'b0;
mcu_reset_once_nxt = 1'b1;
// Once min time in reset has been reached and
// indication FW image has been loaded into MCU SRAM
// visa the region_lock signal. Bring MCU out of reset
if(min_mcu_rst_count_elapsed && mcu_sram_fw_exec_region_lock) begin
boot_fsm_nxt = BOOT_MCU;
end
end
default: begin
// Unexpected state so set state to X
boot_fsm_nxt = BOOT_UNKNOWN;
end
endcase
end
always_ff@(posedge clk or negedge mci_rst_b) begin
if (!mci_rst_b) begin
mcu_cpu_halt_req_o <= 1'b0;
end
else begin
mcu_cpu_halt_req_o <= mcu_cpu_halt_req_nxt;
end
end
// Min MCU reset count
always_comb begin
min_mcu_rst_count_elapsed_nxt = min_mcu_rst_count_elapsed;
min_mcu_rst_count_nxt = min_mcu_rst_count;
// When entering BOOT_RST_MCU state reset count and flag
if(boot_fsm_nxt == BOOT_RST_MCU && boot_fsm != BOOT_RST_MCU) begin
min_mcu_rst_count_elapsed_nxt = '0;
min_mcu_rst_count_nxt = '0;
end
// While in BOOT_RST_MCU count until we are about to overflow the counter.
else if(boot_fsm == BOOT_RST_MCU && min_mcu_rst_count != '1) begin
min_mcu_rst_count_nxt = min_mcu_rst_count + 1'b1;
end
// Once timeout has been reached set the elapsed timer
else if(boot_fsm == BOOT_RST_MCU && min_mcu_rst_count == '1) begin
min_mcu_rst_count_elapsed_nxt = 1'b1;
end
end
//////////////////////////////////////
// ASSERTIONS
//////////////////////////////////////
// Counter must be a valid width. Meaning greater than 0
`CALIPTRA_ASSERT_INIT(ERR_MIN_MCU_RST_COUNTER_WIDTH, MIN_MCU_RST_COUNTER_WIDTH > 0)
// If falling into default state the boot_fsm will value will be X
`CALIPTRA_ASSERT_KNOWN(ERR_MCI_BOOT_SEQR_VALID_STATE, boot_fsm, clk, !mci_rst_b)
endmodule