Go
back
120 assign hw2reg.alert_cause[k].d = 1'b1;
121 65/65 assign hw2reg.alert_cause[k].de = reg2hw.alert_cause[k].q |
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
122 hw2reg_wrap.alert_cause[k];
123 end
124
125 // if a local alert is enabled and it fires,
126 // we have to set the corresponding cause bit
127 for (genvar k = 0; k < N_LOC_ALERT; k++) begin : gen_loc_alert_cause
128 assign hw2reg.loc_alert_cause[k].d = 1'b1;
129 7/7 assign hw2reg.loc_alert_cause[k].de = reg2hw.loc_alert_cause[k].q |
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
130 hw2reg_wrap.loc_alert_cause[k];
131 end
132
133 // ping timeout in cycles
134 // autolock can clear these regs automatically upon entering escalation
135 // note: the class must be activated for this to occur
136 assign { hw2reg.classd_clr_regwen.d,
137 hw2reg.classc_clr_regwen.d,
138 hw2reg.classb_clr_regwen.d,
139 hw2reg.classa_clr_regwen.d } = '0;
140
141 1/1 assign { hw2reg.classd_clr_regwen.de,
Tests: T1 T2 T3
142 hw2reg.classc_clr_regwen.de,
143 hw2reg.classb_clr_regwen.de,
144 hw2reg.classa_clr_regwen.de } = hw2reg_wrap.class_esc_trig &
145 class_autolock_en &
146 reg2hw_wrap.class_en;
147
148 // current accumulator counts
149 1/1 assign { hw2reg.classd_accum_cnt.d,
Tests: T1 T2 T3
150 hw2reg.classc_accum_cnt.d,
151 hw2reg.classb_accum_cnt.d,
152 hw2reg.classa_accum_cnt.d } = hw2reg_wrap.class_accum_cnt;
153
154 // current accumulator counts
155 1/1 assign { hw2reg.classd_esc_cnt.d,
Tests: T1 T2 T3
156 hw2reg.classc_esc_cnt.d,
157 hw2reg.classb_esc_cnt.d,
158 hw2reg.classa_esc_cnt.d } = hw2reg_wrap.class_esc_cnt;
159
160 // current accumulator counts
161 1/1 assign { hw2reg.classd_state.d,
Tests: T1 T2 T3
162 hw2reg.classc_state.d,
163 hw2reg.classb_state.d,
164 hw2reg.classa_state.d } = hw2reg_wrap.class_esc_state;
165
166 /////////////////////
167 // reg2hw mappings //
168 /////////////////////
169
170 // config register lock
171 1/1 assign reg2hw_wrap.ping_enable = reg2hw.ping_timer_en_shadowed.q;
Tests: T1 T2 T3
172
173 // alert enable and class assignments
174 for (genvar k = 0; k < NAlerts; k++) begin : gen_alert_en_class
175 // we only ping enabled alerts that are locked
176 65/65 assign reg2hw_wrap.alert_ping_en[k] = reg2hw.alert_en_shadowed[k].q &
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
177 ~reg2hw.alert_regwen[k].q;
178 65/65 assign reg2hw_wrap.alert_en[k] = reg2hw.alert_en_shadowed[k].q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
179 65/65 assign reg2hw_wrap.alert_class[k] = reg2hw.alert_class_shadowed[k].q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
180 end
181
182 // local alert enable and class assignments
183 for (genvar k = 0; k < N_LOC_ALERT; k++) begin : gen_loc_alert_en_class
184 7/7 assign reg2hw_wrap.loc_alert_en[k] = reg2hw.loc_alert_en_shadowed[k].q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
185 7/7 assign reg2hw_wrap.loc_alert_class[k] = reg2hw.loc_alert_class_shadowed[k].q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
186 end
187
188 1/1 assign reg2hw_wrap.ping_timeout_cyc = reg2hw.ping_timeout_cyc_shadowed.q;
Tests: T1 T2 T3
189
190 // class enable
191 // we require that at least one of the enable signals is
192 // set for a class to be enabled
193 1/1 assign reg2hw_wrap.class_en = {
Tests: T1 T2 T3
194 reg2hw.classd_ctrl_shadowed.en.q & ( reg2hw.classd_ctrl_shadowed.en_e3.q |
195 reg2hw.classd_ctrl_shadowed.en_e2.q |
196 reg2hw.classd_ctrl_shadowed.en_e1.q |
197 reg2hw.classd_ctrl_shadowed.en_e0.q ),
198 //
199 reg2hw.classc_ctrl_shadowed.en.q & ( reg2hw.classc_ctrl_shadowed.en_e3.q |
200 reg2hw.classc_ctrl_shadowed.en_e2.q |
201 reg2hw.classc_ctrl_shadowed.en_e1.q |
202 reg2hw.classc_ctrl_shadowed.en_e0.q ),
203 //
204 reg2hw.classb_ctrl_shadowed.en.q & ( reg2hw.classb_ctrl_shadowed.en_e3.q |
205 reg2hw.classb_ctrl_shadowed.en_e2.q |
206 reg2hw.classb_ctrl_shadowed.en_e1.q |
207 reg2hw.classb_ctrl_shadowed.en_e0.q ),
208 //
209 reg2hw.classa_ctrl_shadowed.en.q & ( reg2hw.classa_ctrl_shadowed.en_e3.q |
210 reg2hw.classa_ctrl_shadowed.en_e2.q |
211 reg2hw.classa_ctrl_shadowed.en_e1.q |
212 reg2hw.classa_ctrl_shadowed.en_e0.q )
213 };
214
215
216 // autolock enable
217 1/1 assign class_autolock_en = { reg2hw.classd_ctrl_shadowed.lock.q,
Tests: T1 T2 T3
218 reg2hw.classc_ctrl_shadowed.lock.q,
219 reg2hw.classb_ctrl_shadowed.lock.q,
220 reg2hw.classa_ctrl_shadowed.lock.q };
221
222 // escalation signal enable
223 1/1 assign reg2hw_wrap.class_esc_en = { reg2hw.classd_ctrl_shadowed.en_e3.q,
Tests: T1 T2 T3
224 reg2hw.classd_ctrl_shadowed.en_e2.q,
225 reg2hw.classd_ctrl_shadowed.en_e1.q,
226 reg2hw.classd_ctrl_shadowed.en_e0.q,
227 //
228 reg2hw.classc_ctrl_shadowed.en_e3.q,
229 reg2hw.classc_ctrl_shadowed.en_e2.q,
230 reg2hw.classc_ctrl_shadowed.en_e1.q,
231 reg2hw.classc_ctrl_shadowed.en_e0.q,
232 //
233 reg2hw.classb_ctrl_shadowed.en_e3.q,
234 reg2hw.classb_ctrl_shadowed.en_e2.q,
235 reg2hw.classb_ctrl_shadowed.en_e1.q,
236 reg2hw.classb_ctrl_shadowed.en_e0.q,
237 //
238 reg2hw.classa_ctrl_shadowed.en_e3.q,
239 reg2hw.classa_ctrl_shadowed.en_e2.q,
240 reg2hw.classa_ctrl_shadowed.en_e1.q,
241 reg2hw.classa_ctrl_shadowed.en_e0.q };
242
243
244 // escalation phase to escalation signal mapping
245 1/1 assign reg2hw_wrap.class_esc_map = { reg2hw.classd_ctrl_shadowed.map_e3.q,
Tests: T1 T2 T3
246 reg2hw.classd_ctrl_shadowed.map_e2.q,
247 reg2hw.classd_ctrl_shadowed.map_e1.q,
248 reg2hw.classd_ctrl_shadowed.map_e0.q,
249 //
250 reg2hw.classc_ctrl_shadowed.map_e3.q,
251 reg2hw.classc_ctrl_shadowed.map_e2.q,
252 reg2hw.classc_ctrl_shadowed.map_e1.q,
253 reg2hw.classc_ctrl_shadowed.map_e0.q,
254 //
255 reg2hw.classb_ctrl_shadowed.map_e3.q,
256 reg2hw.classb_ctrl_shadowed.map_e2.q,
257 reg2hw.classb_ctrl_shadowed.map_e1.q,
258 reg2hw.classb_ctrl_shadowed.map_e0.q,
259 //
260 reg2hw.classa_ctrl_shadowed.map_e3.q,
261 reg2hw.classa_ctrl_shadowed.map_e2.q,
262 reg2hw.classa_ctrl_shadowed.map_e1.q,
263 reg2hw.classa_ctrl_shadowed.map_e0.q };
264
265 // Determines in which phase to latch the crashdump.
266 1/1 assign reg2hw_wrap.class_crashdump_phase = { reg2hw.classd_crashdump_trigger_shadowed.q,
Tests: T1 T2 T3
267 reg2hw.classc_crashdump_trigger_shadowed.q,
268 reg2hw.classb_crashdump_trigger_shadowed.q,
269 reg2hw.classa_crashdump_trigger_shadowed.q };
270
271 // writing 1b1 to a class clr register clears the accumulator and
272 // escalation state if autolock is not asserted
273 1/1 assign reg2hw_wrap.class_clr = { reg2hw.classd_clr_shadowed.q & reg2hw.classd_clr_shadowed.qe,
Tests: T1 T2 T3
274 reg2hw.classc_clr_shadowed.q & reg2hw.classc_clr_shadowed.qe,
275 reg2hw.classb_clr_shadowed.q & reg2hw.classb_clr_shadowed.qe,
276 reg2hw.classa_clr_shadowed.q & reg2hw.classa_clr_shadowed.qe };
277
278
279 // accumulator thresholds
280 1/1 assign reg2hw_wrap.class_accum_thresh = { reg2hw.classd_accum_thresh_shadowed.q,
Tests: T1 T2 T3
281 reg2hw.classc_accum_thresh_shadowed.q,
282 reg2hw.classb_accum_thresh_shadowed.q,
283 reg2hw.classa_accum_thresh_shadowed.q };
284
285 // interrupt timeout lengths
286 1/1 assign reg2hw_wrap.class_timeout_cyc = { reg2hw.classd_timeout_cyc_shadowed.q,
Tests: T1 T2 T3
287 reg2hw.classc_timeout_cyc_shadowed.q,
288 reg2hw.classb_timeout_cyc_shadowed.q,
289 reg2hw.classa_timeout_cyc_shadowed.q };
290 // escalation phase lengths
291 1/1 assign reg2hw_wrap.class_phase_cyc = { reg2hw.classd_phase3_cyc_shadowed.q,
Tests: T1 T2 T3
292 reg2hw.classd_phase2_cyc_shadowed.q,
293 reg2hw.classd_phase1_cyc_shadowed.q,
294 reg2hw.classd_phase0_cyc_shadowed.q,
295 //
296 reg2hw.classc_phase3_cyc_shadowed.q,
297 reg2hw.classc_phase2_cyc_shadowed.q,
298 reg2hw.classc_phase1_cyc_shadowed.q,
299 reg2hw.classc_phase0_cyc_shadowed.q,
300 //
301 reg2hw.classb_phase3_cyc_shadowed.q,
302 reg2hw.classb_phase2_cyc_shadowed.q,
303 reg2hw.classb_phase1_cyc_shadowed.q,
304 reg2hw.classb_phase0_cyc_shadowed.q,
305 //
306 reg2hw.classa_phase3_cyc_shadowed.q,
307 reg2hw.classa_phase2_cyc_shadowed.q,
308 reg2hw.classa_phase1_cyc_shadowed.q,
309 reg2hw.classa_phase0_cyc_shadowed.q};
310
311 //////////////////////
312 // crashdump output //
313 //////////////////////
314
315 logic [N_CLASSES-1:0] crashdump_latched_q;
316 alert_crashdump_t crashdump_d, crashdump_q;
317
318 // alert cause output
319 for (genvar k = 0; k < NAlerts; k++) begin : gen_alert_cause_dump
320 65/65 assign crashdump_d.alert_cause[k] = reg2hw.alert_cause[k].q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
321 end
322
323 // local alert cause register output
324 for (genvar k = 0; k < N_LOC_ALERT; k++) begin : gen_loc_alert_cause_dump
325 7/7 assign crashdump_d.loc_alert_cause[k] = reg2hw.loc_alert_cause[k].q;
Tests: T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3 | T1 T2 T3
326 end
327
328 1/1 assign crashdump_d.class_accum_cnt = hw2reg_wrap.class_accum_cnt;
Tests: T1 T2 T3
329 1/1 assign crashdump_d.class_esc_cnt = hw2reg_wrap.class_esc_cnt;
Tests: T1 T2 T3
330 1/1 assign crashdump_d.class_esc_state = hw2reg_wrap.class_esc_state;
Tests: T1 T2 T3
331
332 // We latch the crashdump upon triggering any of the escalation protocols. The reason for this is
333 // that during escalation, certain alert senders may start to trigger due to FSMs being moved
334 // into escalation mode - thereby masking the actual alert reasons exposed in the cause
335 // registers.
336 always_ff @(posedge clk_i or negedge rst_ni) begin : p_crashdump
337 1/1 if (!rst_ni) begin
Tests: T1 T2 T3
338 1/1 crashdump_latched_q <= '0;
Tests: T1 T2 T3
339 1/1 crashdump_q <= '0;
Tests: T1 T2 T3
340 end else begin
341 // We track which class has been escalated so that the crashdump latching mechanism cannot be
342 // re-armed by clearing another class that has not escalated yet. This also implies that if
343 // an unclearable class has escalated, the crashdump latching mechanism cannot be re-armed.
344 1/1 crashdump_latched_q <= (crashdump_latched_q & ~reg2hw_wrap.class_clr) | latch_crashdump_i;
Tests: T1 T2 T3
345
346 // The alert handler only captures the first escalation event that asserts a latch_crashdump_i
347 // signal, unless all classes are cleared, in which case the crashdump latching mechanism is
348 // re-armed. In other words, we latch the crashdump if any of the latch_crashdump_i bits is
349 // asserted, and no crashdump has been latched yet.
350 1/1 if (|latch_crashdump_i && !(|crashdump_latched_q)) begin
Tests: T1 T2 T3
351 1/1 crashdump_q <= crashdump_d;
Tests: T1 T2 T3
352 end
MISSING_ELSE
353 end
354 end
355
356 // As long as the crashdump has not been latched yet, we output the current alert handler state.
357 // Once any of the classes has triggered the latching, we switch to the latched snapshot.
358 1/1 assign crashdump_o = (|crashdump_latched_q) ? crashdump_q : crashdump_d;
Tests: T1 T2 T3