../src/lowrisc_ip_alert_handler_component_0.1/rtl/alert_handler_reg_wrap.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: // Breakout / remapping wrapper for register file. Generated from template.
6:
7: module alert_handler_reg_wrap import alert_pkg::*; (
8: input clk_i,
9: input rst_ni,
10: // Bus Interface (device)
11: input tlul_pkg::tl_h2d_t tl_i,
12: output tlul_pkg::tl_d2h_t tl_o,
13: // interrupt
14: output logic [N_CLASSES-1:0] irq_o,
15: // State information for HW crashdump
16: output alert_crashdump_t crashdump_o,
17: // hw2reg
18: input hw2reg_wrap_t hw2reg_wrap,
19: // reg2hw
20: output reg2hw_wrap_t reg2hw_wrap
21: );
22:
23:
24: //////////////////
25: // reg instance //
26: //////////////////
27:
28: logic [N_CLASSES-1:0] class_autolock_en;
29: alert_handler_reg_pkg::alert_handler_reg2hw_t reg2hw;
30: alert_handler_reg_pkg::alert_handler_hw2reg_t hw2reg;
31:
32: alert_handler_reg_top i_reg (
33: .clk_i,
34: .rst_ni,
35: .tl_i,
36: .tl_o,
37: .reg2hw,
38: .hw2reg,
39: .devmode_i(1'b1)
40: );
41:
42: ////////////////
43: // interrupts //
44: ////////////////
45:
46: prim_intr_hw #(
47: .Width(1)
48: ) i_irq_classa (
49: .event_intr_i ( hw2reg_wrap.class_trig[0] ),
50: .reg2hw_intr_enable_q_i ( reg2hw.intr_enable.classa.q ),
51: .reg2hw_intr_test_q_i ( reg2hw.intr_test.classa.q ),
52: .reg2hw_intr_test_qe_i ( reg2hw.intr_test.classa.qe ),
53: .reg2hw_intr_state_q_i ( reg2hw.intr_state.classa.q ),
54: .hw2reg_intr_state_de_o ( hw2reg.intr_state.classa.de ),
55: .hw2reg_intr_state_d_o ( hw2reg.intr_state.classa.d ),
56: .intr_o ( irq_o[0] )
57: );
58:
59: prim_intr_hw #(
60: .Width(1)
61: ) i_irq_classb (
62: .event_intr_i ( hw2reg_wrap.class_trig[1] ),
63: .reg2hw_intr_enable_q_i ( reg2hw.intr_enable.classb.q ),
64: .reg2hw_intr_test_q_i ( reg2hw.intr_test.classb.q ),
65: .reg2hw_intr_test_qe_i ( reg2hw.intr_test.classb.qe ),
66: .reg2hw_intr_state_q_i ( reg2hw.intr_state.classb.q ),
67: .hw2reg_intr_state_de_o ( hw2reg.intr_state.classb.de ),
68: .hw2reg_intr_state_d_o ( hw2reg.intr_state.classb.d ),
69: .intr_o ( irq_o[1] )
70: );
71:
72: prim_intr_hw #(
73: .Width(1)
74: ) i_irq_classc (
75: .event_intr_i ( hw2reg_wrap.class_trig[2] ),
76: .reg2hw_intr_enable_q_i ( reg2hw.intr_enable.classc.q ),
77: .reg2hw_intr_test_q_i ( reg2hw.intr_test.classc.q ),
78: .reg2hw_intr_test_qe_i ( reg2hw.intr_test.classc.qe ),
79: .reg2hw_intr_state_q_i ( reg2hw.intr_state.classc.q ),
80: .hw2reg_intr_state_de_o ( hw2reg.intr_state.classc.de ),
81: .hw2reg_intr_state_d_o ( hw2reg.intr_state.classc.d ),
82: .intr_o ( irq_o[2] )
83: );
84:
85: prim_intr_hw #(
86: .Width(1)
87: ) i_irq_classd (
88: .event_intr_i ( hw2reg_wrap.class_trig[3] ),
89: .reg2hw_intr_enable_q_i ( reg2hw.intr_enable.classd.q ),
90: .reg2hw_intr_test_q_i ( reg2hw.intr_test.classd.q ),
91: .reg2hw_intr_test_qe_i ( reg2hw.intr_test.classd.qe ),
92: .reg2hw_intr_state_q_i ( reg2hw.intr_state.classd.q ),
93: .hw2reg_intr_state_de_o ( hw2reg.intr_state.classd.de ),
94: .hw2reg_intr_state_d_o ( hw2reg.intr_state.classd.d ),
95: .intr_o ( irq_o[3] )
96: );
97:
98: /////////////////////
99: // hw2reg mappings //
100: /////////////////////
101:
102: // if an alert is enabled and it fires,
103: // we have to set the corresponding cause bit
104: for (genvar k = 0; k < NAlerts; k++) begin : gen_alert_cause
105: assign hw2reg.alert_cause[k].d = 1'b1;
106: assign hw2reg.alert_cause[k].de = reg2hw.alert_cause[k].q |
107: hw2reg_wrap.alert_cause[k];
108: end
109:
110: // if a local alert is enabled and it fires,
111: // we have to set the corresponding cause bit
112: for (genvar k = 0; k < N_LOC_ALERT; k++) begin : gen_loc_alert_cause
113: assign hw2reg.loc_alert_cause[k].d = 1'b1;
114: assign hw2reg.loc_alert_cause[k].de = reg2hw.loc_alert_cause[k].q |
115: hw2reg_wrap.loc_alert_cause[k];
116: end
117:
118: // ping timeout in cycles
119: // autolock can clear these regs automatically upon entering escalation
120: // note: the class must be activated for this to occur
121: assign { hw2reg.classd_clren.d,
122: hw2reg.classc_clren.d,
123: hw2reg.classb_clren.d,
124: hw2reg.classa_clren.d } = '0;
125:
126: assign { hw2reg.classd_clren.de,
127: hw2reg.classc_clren.de,
128: hw2reg.classb_clren.de,
129: hw2reg.classa_clren.de } = hw2reg_wrap.class_esc_trig &
130: class_autolock_en &
131: reg2hw_wrap.class_en;
132:
133: // current accumulator counts
134: assign { hw2reg.classd_accum_cnt.d,
135: hw2reg.classc_accum_cnt.d,
136: hw2reg.classb_accum_cnt.d,
137: hw2reg.classa_accum_cnt.d } = hw2reg_wrap.class_accum_cnt;
138:
139: // current accumulator counts
140: assign { hw2reg.classd_esc_cnt.d,
141: hw2reg.classc_esc_cnt.d,
142: hw2reg.classb_esc_cnt.d,
143: hw2reg.classa_esc_cnt.d } = hw2reg_wrap.class_esc_cnt;
144:
145: // current accumulator counts
146: assign { hw2reg.classd_state.d,
147: hw2reg.classc_state.d,
148: hw2reg.classb_state.d,
149: hw2reg.classa_state.d } = hw2reg_wrap.class_esc_state;
150:
151: /////////////////////
152: // reg2hw mappings //
153: /////////////////////
154:
155: // config register lock
156: assign reg2hw_wrap.config_locked = ~reg2hw.regen.q;
157:
158: // alert enable and class assignments
159: for (genvar k = 0; k < NAlerts; k++) begin : gen_alert_en_class
160: assign reg2hw_wrap.alert_en[k] = reg2hw.alert_en[k].q;
161: assign reg2hw_wrap.alert_class[k] = reg2hw.alert_class[k].q;
162: end
163:
164: // local alert enable and class assignments
165: for (genvar k = 0; k < N_LOC_ALERT; k++) begin : gen_loc_alert_en_class
166: assign reg2hw_wrap.loc_alert_en[k] = reg2hw.loc_alert_en[k].q;
167: assign reg2hw_wrap.loc_alert_class[k] = reg2hw.loc_alert_class[k].q;
168: end
169:
170: assign reg2hw_wrap.ping_timeout_cyc = reg2hw.ping_timeout_cyc.q;
171:
172: // class enable
173: // we require that at least one of the enable signals is
174: // set for a class to be enabled
175: assign reg2hw_wrap.class_en = { reg2hw.classd_ctrl.en & ( reg2hw.classd_ctrl.en_e3 |
176: reg2hw.classd_ctrl.en_e2 |
177: reg2hw.classd_ctrl.en_e1 |
178: reg2hw.classd_ctrl.en_e0 ),
179: //
180: reg2hw.classc_ctrl.en & ( reg2hw.classc_ctrl.en_e3 |
181: reg2hw.classc_ctrl.en_e2 |
182: reg2hw.classc_ctrl.en_e1 |
183: reg2hw.classc_ctrl.en_e0 ),
184: //
185: reg2hw.classb_ctrl.en & ( reg2hw.classb_ctrl.en_e3 |
186: reg2hw.classb_ctrl.en_e2 |
187: reg2hw.classb_ctrl.en_e1 |
188: reg2hw.classb_ctrl.en_e0 ),
189: //
190: reg2hw.classa_ctrl.en & ( reg2hw.classa_ctrl.en_e3 |
191: reg2hw.classa_ctrl.en_e2 |
192: reg2hw.classa_ctrl.en_e1 |
193: reg2hw.classa_ctrl.en_e0 ) };
194:
195:
196: // autolock enable
197: assign class_autolock_en = { reg2hw.classd_ctrl.lock,
198: reg2hw.classc_ctrl.lock,
199: reg2hw.classb_ctrl.lock,
200: reg2hw.classa_ctrl.lock };
201:
202: // escalation signal enable
203: assign reg2hw_wrap.class_esc_en = { reg2hw.classd_ctrl.en_e3,
204: reg2hw.classd_ctrl.en_e2,
205: reg2hw.classd_ctrl.en_e1,
206: reg2hw.classd_ctrl.en_e0,
207: //
208: reg2hw.classc_ctrl.en_e3,
209: reg2hw.classc_ctrl.en_e2,
210: reg2hw.classc_ctrl.en_e1,
211: reg2hw.classc_ctrl.en_e0,
212: //
213: reg2hw.classb_ctrl.en_e3,
214: reg2hw.classb_ctrl.en_e2,
215: reg2hw.classb_ctrl.en_e1,
216: reg2hw.classb_ctrl.en_e0,
217: //
218: reg2hw.classa_ctrl.en_e3,
219: reg2hw.classa_ctrl.en_e2,
220: reg2hw.classa_ctrl.en_e1,
221: reg2hw.classa_ctrl.en_e0 };
222:
223:
224: // escalation phase to escalation signal mapping
225: assign reg2hw_wrap.class_esc_map = { reg2hw.classd_ctrl.map_e3,
226: reg2hw.classd_ctrl.map_e2,
227: reg2hw.classd_ctrl.map_e1,
228: reg2hw.classd_ctrl.map_e0,
229: //
230: reg2hw.classc_ctrl.map_e3,
231: reg2hw.classc_ctrl.map_e2,
232: reg2hw.classc_ctrl.map_e1,
233: reg2hw.classc_ctrl.map_e0,
234: //
235: reg2hw.classb_ctrl.map_e3,
236: reg2hw.classb_ctrl.map_e2,
237: reg2hw.classb_ctrl.map_e1,
238: reg2hw.classb_ctrl.map_e0,
239: //
240: reg2hw.classa_ctrl.map_e3,
241: reg2hw.classa_ctrl.map_e2,
242: reg2hw.classa_ctrl.map_e1,
243: reg2hw.classa_ctrl.map_e0 };
244:
245: // TODO: check whether this is correctly locked inside the regfile
246: // writing 1b1 to a class clr register clears the accumulator and
247: // escalation state if autolock is not asserted
248: assign reg2hw_wrap.class_clr = { reg2hw.classd_clr.q & reg2hw.classd_clr.qe,
249: reg2hw.classc_clr.q & reg2hw.classc_clr.qe,
250: reg2hw.classb_clr.q & reg2hw.classb_clr.qe,
251: reg2hw.classa_clr.q & reg2hw.classa_clr.qe };
252:
253: // accumulator thresholds
254: assign reg2hw_wrap.class_accum_thresh = { reg2hw.classd_accum_thresh.q,
255: reg2hw.classc_accum_thresh.q,
256: reg2hw.classb_accum_thresh.q,
257: reg2hw.classa_accum_thresh.q };
258:
259: // interrupt timeout lengths
260: assign reg2hw_wrap.class_timeout_cyc = { reg2hw.classd_timeout_cyc.q,
261: reg2hw.classc_timeout_cyc.q,
262: reg2hw.classb_timeout_cyc.q,
263: reg2hw.classa_timeout_cyc.q };
264: // escalation phase lengths
265: assign reg2hw_wrap.class_phase_cyc = { reg2hw.classd_phase3_cyc.q,
266: reg2hw.classd_phase2_cyc.q,
267: reg2hw.classd_phase1_cyc.q,
268: reg2hw.classd_phase0_cyc.q,
269: //
270: reg2hw.classc_phase3_cyc.q,
271: reg2hw.classc_phase2_cyc.q,
272: reg2hw.classc_phase1_cyc.q,
273: reg2hw.classc_phase0_cyc.q,
274: //
275: reg2hw.classb_phase3_cyc.q,
276: reg2hw.classb_phase2_cyc.q,
277: reg2hw.classb_phase1_cyc.q,
278: reg2hw.classb_phase0_cyc.q,
279: //
280: reg2hw.classa_phase3_cyc.q,
281: reg2hw.classa_phase2_cyc.q,
282: reg2hw.classa_phase1_cyc.q,
283: reg2hw.classa_phase0_cyc.q};
284:
285: //////////////////////
286: // crashdump output //
287: //////////////////////
288:
289: // alert cause output
290: for (genvar k = 0; k < NAlerts; k++) begin : gen_alert_cause_dump
291: assign crashdump_o.alert_cause[k] = reg2hw.alert_cause[k].q;
292: end
293:
294: // local alert cause register output
295: for (genvar k = 0; k < N_LOC_ALERT; k++) begin : gen_loc_alert_cause_dump
296: assign crashdump_o.loc_alert_cause[k] = reg2hw.loc_alert_cause[k].q;
297: end
298:
299: assign crashdump_o.class_accum_cnt = hw2reg_wrap.class_accum_cnt;
300: assign crashdump_o.class_esc_cnt = hw2reg_wrap.class_esc_cnt;
301: assign crashdump_o.class_esc_state = hw2reg_wrap.class_esc_state;
302:
303: endmodule : alert_handler_reg_wrap
304:
305: