hw/ip/alert_handler/rtl/alert_handler_reg_wrap.sv Cov: 89.8%

   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:   assign reg2hw_wrap.class_en = { reg2hw.classd_ctrl.en,
 174:                                   reg2hw.classc_ctrl.en,
 175:                                   reg2hw.classb_ctrl.en,
 176:                                   reg2hw.classa_ctrl.en };
 177: 
 178:   // autolock enable
 179:   assign class_autolock_en = { reg2hw.classd_ctrl.lock,
 180:                                reg2hw.classc_ctrl.lock,
 181:                                reg2hw.classb_ctrl.lock,
 182:                                reg2hw.classa_ctrl.lock };
 183: 
 184:   // escalation signal enable
 185:   assign reg2hw_wrap.class_esc_en = { reg2hw.classd_ctrl.en_e3,
 186:                                       reg2hw.classd_ctrl.en_e2,
 187:                                       reg2hw.classd_ctrl.en_e1,
 188:                                       reg2hw.classd_ctrl.en_e0,
 189:                                       //
 190:                                       reg2hw.classc_ctrl.en_e3,
 191:                                       reg2hw.classc_ctrl.en_e2,
 192:                                       reg2hw.classc_ctrl.en_e1,
 193:                                       reg2hw.classc_ctrl.en_e0,
 194:                                       //
 195:                                       reg2hw.classb_ctrl.en_e3,
 196:                                       reg2hw.classb_ctrl.en_e2,
 197:                                       reg2hw.classb_ctrl.en_e1,
 198:                                       reg2hw.classb_ctrl.en_e0,
 199:                                       //
 200:                                       reg2hw.classa_ctrl.en_e3,
 201:                                       reg2hw.classa_ctrl.en_e2,
 202:                                       reg2hw.classa_ctrl.en_e1,
 203:                                       reg2hw.classa_ctrl.en_e0 };
 204: 
 205: 
 206:   // escalation phase to escalation signal mapping
 207:   assign reg2hw_wrap.class_esc_map = { reg2hw.classd_ctrl.map_e3,
 208:                                        reg2hw.classd_ctrl.map_e2,
 209:                                        reg2hw.classd_ctrl.map_e1,
 210:                                        reg2hw.classd_ctrl.map_e0,
 211:                                        //
 212:                                        reg2hw.classc_ctrl.map_e3,
 213:                                        reg2hw.classc_ctrl.map_e2,
 214:                                        reg2hw.classc_ctrl.map_e1,
 215:                                        reg2hw.classc_ctrl.map_e0,
 216:                                        //
 217:                                        reg2hw.classb_ctrl.map_e3,
 218:                                        reg2hw.classb_ctrl.map_e2,
 219:                                        reg2hw.classb_ctrl.map_e1,
 220:                                        reg2hw.classb_ctrl.map_e0,
 221:                                        //
 222:                                        reg2hw.classa_ctrl.map_e3,
 223:                                        reg2hw.classa_ctrl.map_e2,
 224:                                        reg2hw.classa_ctrl.map_e1,
 225:                                        reg2hw.classa_ctrl.map_e0 };
 226: 
 227:   // TODO: check whether this is correctly locked inside the regfile
 228:   // writing 1b1 to a class clr register clears the accumulator and
 229:   // escalation state if autolock is not asserted
 230:   assign reg2hw_wrap.class_clr = { reg2hw.classd_clr.q & reg2hw.classd_clr.qe,
 231:                                    reg2hw.classc_clr.q & reg2hw.classc_clr.qe,
 232:                                    reg2hw.classb_clr.q & reg2hw.classb_clr.qe,
 233:                                    reg2hw.classa_clr.q & reg2hw.classa_clr.qe };
 234: 
 235:   // accumulator thresholds
 236:   assign reg2hw_wrap.class_accum_thresh = { reg2hw.classd_accum_thresh.q,
 237:                                             reg2hw.classc_accum_thresh.q,
 238:                                             reg2hw.classb_accum_thresh.q,
 239:                                             reg2hw.classa_accum_thresh.q };
 240: 
 241:   // interrupt timeout lengths
 242:   assign reg2hw_wrap.class_timeout_cyc = { reg2hw.classd_timeout_cyc.q,
 243:                                            reg2hw.classc_timeout_cyc.q,
 244:                                            reg2hw.classb_timeout_cyc.q,
 245:                                            reg2hw.classa_timeout_cyc.q };
 246:   // escalation phase lengths
 247:   assign reg2hw_wrap.class_phase_cyc = { reg2hw.classd_phase3_cyc.q,
 248:                                          reg2hw.classd_phase2_cyc.q,
 249:                                          reg2hw.classd_phase1_cyc.q,
 250:                                          reg2hw.classd_phase0_cyc.q,
 251:                                          //
 252:                                          reg2hw.classc_phase3_cyc.q,
 253:                                          reg2hw.classc_phase2_cyc.q,
 254:                                          reg2hw.classc_phase1_cyc.q,
 255:                                          reg2hw.classc_phase0_cyc.q,
 256:                                          //
 257:                                          reg2hw.classb_phase3_cyc.q,
 258:                                          reg2hw.classb_phase2_cyc.q,
 259:                                          reg2hw.classb_phase1_cyc.q,
 260:                                          reg2hw.classb_phase0_cyc.q,
 261:                                          //
 262:                                          reg2hw.classa_phase3_cyc.q,
 263:                                          reg2hw.classa_phase2_cyc.q,
 264:                                          reg2hw.classa_phase1_cyc.q,
 265:                                          reg2hw.classa_phase0_cyc.q};
 266: 
 267:   //////////////////////
 268:   // crashdump output //
 269:   //////////////////////
 270: 
 271:   // alert cause output
 272:   for (genvar k = 0; k < NAlerts; k++) begin : gen_alert_cause_dump
 273:     assign crashdump_o.alert_cause[k]  = reg2hw.alert_cause[k].q;
 274:   end
 275: 
 276:   // local alert cause register output
 277:   for (genvar k = 0; k < N_LOC_ALERT; k++) begin : gen_loc_alert_cause_dump
 278:     assign crashdump_o.loc_alert_cause[k]  = reg2hw.loc_alert_cause[k].q;
 279:   end
 280: 
 281:   assign crashdump_o.class_accum_cnt = hw2reg_wrap.class_accum_cnt;
 282:   assign crashdump_o.class_esc_cnt   = hw2reg_wrap.class_esc_cnt;
 283:   assign crashdump_o.class_esc_state = hw2reg_wrap.class_esc_state;
 284: 
 285: endmodule : alert_handler_reg_wrap
 286: 
 287: