[alert_handler] Update regfile wrap and add crashdump out
diff --git a/hw/ip/alert_handler/doc/alert_handler.hjson b/hw/ip/alert_handler/doc/alert_handler.hjson
index 5ebaf7d..a72a26a 100644
--- a/hw/ip/alert_handler/doc/alert_handler.hjson
+++ b/hw/ip/alert_handler/doc/alert_handler.hjson
@@ -120,7 +120,7 @@
       count: 4,
       cname: "ALERT",
       swaccess: "rw1c",
-      hwaccess: "hwo",
+      hwaccess: "hrw",
       fields: [
         { bits: "0", name: "A", desc: "Cause bit " }
       ]
@@ -172,7 +172,7 @@
     { name:     "LOC_ALERT_CAUSE",
       desc:     "Alert Cause Register for Local Alerts",
       swaccess: "rw1c",
-      hwaccess: "hwo",
+      hwaccess: "hrw",
       fields: [
         { bits: "0",
           name: "LA0",
diff --git a/hw/ip/alert_handler/doc/alert_handler.tpl.hjson b/hw/ip/alert_handler/doc/alert_handler.tpl.hjson
index 471ff43..effb010 100644
--- a/hw/ip/alert_handler/doc/alert_handler.tpl.hjson
+++ b/hw/ip/alert_handler/doc/alert_handler.tpl.hjson
@@ -110,7 +110,7 @@
       count: ${n_alerts},
       cname: "ALERT",
       swaccess: "rw1c",
-      hwaccess: "hwo",
+      hwaccess: "hrw",
       fields: [
         { bits: "0", name: "A", desc: "Cause bit " }
       ]
@@ -163,7 +163,7 @@
     { name:     "LOC_ALERT_CAUSE",
       desc:     "Alert Cause Register for Local Alerts",
       swaccess: "rw1c",
-      hwaccess: "hwo",
+      hwaccess: "hrw",
       fields: [
         { bits: "0",
           name: "LA0",
diff --git a/hw/ip/alert_handler/doc/alert_handler_reg_wrap.tpl.sv b/hw/ip/alert_handler/doc/alert_handler_reg_wrap.tpl.sv
index 6c34810..5684505 100644
--- a/hw/ip/alert_handler/doc/alert_handler_reg_wrap.tpl.sv
+++ b/hw/ip/alert_handler/doc/alert_handler_reg_wrap.tpl.sv
@@ -12,12 +12,15 @@
   output tlul_pkg::tl_d2h_t               tl_o,
   // interrupt
   output logic [alert_pkg::N_CLASSES-1:0] irq_o,
+  // State information for HW crashdump
+  output alert_pkg::alert_crashdump_t     crashdump_o,
   // hw2reg
   input  alert_pkg::hw2reg_wrap_t         hw2reg_wrap,
   // reg2hw
   output alert_pkg::reg2hw_wrap_t         reg2hw_wrap
 );
 
+
   //////////////////////////////////////////////////////
   // reg instance
   //////////////////////////////////////////////////////
@@ -97,7 +100,8 @@
   prefix = space;%>${prefix}hw2reg.alert_cause${w}.a${k}.de${comma}
 %endfor
 ${space}} = hw2reg_wrap.alert_cause;
-  //----------------------------------------------------------------------------
+
+  //////////////////////////////////////////////////////////////////////////////
 
   // if a local alert is enabled and it fires,
   // we have to set the corresponding cause bit
@@ -111,6 +115,7 @@
            hw2reg.loc_alert_cause.la1.de,
            hw2reg.loc_alert_cause.la0.de } = hw2reg_wrap.loc_alert_cause;
 
+  // ping timeout in cycles
   // autolock can clear these regs automatically upon entering escalation
   // note: the class must be activated for this to occur
   assign { hw2reg.classd_clren.d,
@@ -168,7 +173,7 @@
 if k < n_alerts-1:
   prefix = space;%>${prefix}reg2hw.alert_en${w}.en_a${k}.q${comma}
 %endfor
-  //----------------------------------------------------------------------------
+  //////////////////////////////////////////////////////////////////////////////
 
   //////////////////////////////////////////////////////////////////////////////
   // classification mapping
@@ -188,7 +193,7 @@
 if k < n_alerts-1:
   prefix = space;%>${prefix}reg2hw.alert_class${w}.class_a${k}.q${comma}
 %endfor
-  //----------------------------------------------------------------------------
+  //////////////////////////////////////////////////////////////////////////////
 
   // local alert enable and class assignments
   assign reg2hw_wrap.loc_alert_en = { reg2hw.loc_alert_en.en_la3.q,
@@ -200,7 +205,7 @@
                                          reg2hw.loc_alert_class.class_la2.q[1:0],
                                          reg2hw.loc_alert_class.class_la1.q[1:0],
                                          reg2hw.loc_alert_class.class_la0.q[1:0]};
-  // ping timeout in cycles
+
   assign reg2hw_wrap.ping_timeout_cyc = reg2hw.ping_timeout_cyc.q;
 
   // class enable
@@ -298,4 +303,35 @@
                                          reg2hw.classa_phase1_cyc.q,
                                          reg2hw.classa_phase0_cyc.q};
 
+  //////////////////////////////////////////////////////
+  // crashdump output
+  //////////////////////////////////////////////////////
+
+  // alert cause output <%
+prefix = '  assign crashdump_o.alert_cause = { '
+space  = '';
+for k in range(len(prefix)):
+  space += ' '
+comma = ','
+w = '' %>
+%for k in range(n_alerts-1,-1,-1):
+<%
+if n_alerts > reg_dw:
+  w = int(k / reg_dw)
+if not k:
+  comma = ' };'
+if k < n_alerts-1:
+  prefix = space;%>${prefix}reg2hw.alert_cause${w}.a${k}.q${comma}
+%endfor
+
+  // local alert cause register output
+  assign crashdump_o.loc_alert_cause = { reg2hw.loc_alert_cause.la3.q,
+                                         reg2hw.loc_alert_cause.la2.q,
+                                         reg2hw.loc_alert_cause.la1.q,
+                                         reg2hw.loc_alert_cause.la0.q };
+
+  assign crashdump_o.class_accum_cnt = hw2reg_wrap.class_accum_cnt;
+  assign crashdump_o.class_esc_cnt   = hw2reg_wrap.class_esc_cnt;
+  assign crashdump_o.class_esc_state = hw2reg_wrap.class_esc_state;
+
 endmodule : alert_handler_reg_wrap
diff --git a/hw/ip/alert_handler/doc/alert_pkg.tpl.sv b/hw/ip/alert_handler/doc/alert_pkg.tpl.sv
index 4b7322a..2b6209f 100644
--- a/hw/ip/alert_handler/doc/alert_pkg.tpl.sv
+++ b/hw/ip/alert_handler/doc/alert_pkg.tpl.sv
@@ -27,14 +27,26 @@
                             Phase0 = 3'b100, Phase1 = 3'b101, Phase2 = 3'b110,
                             Phase3 = 3'b111} cstate_e;
 
+  // struct containing the current alert handler state
+  // can be used to gather crashdump information in HW
+  typedef struct packed {
+    // alerts
+    logic    [NAlerts-1:0]                  alert_cause;     // alert cause bits
+    logic    [N_LOC_ALERT-1:0]              loc_alert_cause; // local alert cause bits
+    // class state
+    logic    [N_CLASSES-1:0][AccuCntDw-1:0] class_accum_cnt; // current accumulator value
+    logic    [N_CLASSES-1:0][EscCntDw-1:0]  class_esc_cnt;   // current escalation counter value
+    cstate_e [N_CLASSES-1:0]                class_esc_state; // current escalation protocol state
+  } alert_crashdump_t;
+
   // breakout wrapper structs
   typedef struct packed {
     // alerts
     logic    [NAlerts-1:0]                  alert_cause;     // alert cause bits
     logic    [N_LOC_ALERT-1:0]              loc_alert_cause; // local alert cause bits
     // class state
-    logic    [N_CLASSES-1:0]                class_trig;      // class has been triggered
-    logic    [N_CLASSES-1:0]                class_esc_trig;  // escalation has triggered
+    logic    [N_CLASSES-1:0]                class_trig;      // class trigger
+    logic    [N_CLASSES-1:0]                class_esc_trig;  // escalation trigger
     logic    [N_CLASSES-1:0][AccuCntDw-1:0] class_accum_cnt; // current accumulator value
     logic    [N_CLASSES-1:0][EscCntDw-1:0]  class_esc_cnt;   // current escalation counter value
     cstate_e [N_CLASSES-1:0]                class_esc_state; // current escalation protocol state
diff --git a/hw/ip/alert_handler/rtl/alert_handler.sv b/hw/ip/alert_handler/rtl/alert_handler.sv
index 76d2592..8d0ba13 100644
--- a/hw/ip/alert_handler/rtl/alert_handler.sv
+++ b/hw/ip/alert_handler/rtl/alert_handler.sv
@@ -9,27 +9,29 @@
 //
 
 module alert_handler (
-  input                      clk_i,
-  input                      rst_ni,
+  input                                    clk_i,
+  input                                    rst_ni,
   // Bus Interface (device)
-  input  tlul_pkg::tl_h2d_t  tl_i,
-  output tlul_pkg::tl_d2h_t  tl_o,
+  input  tlul_pkg::tl_h2d_t                tl_i,
+  output tlul_pkg::tl_d2h_t                tl_o,
   // Interrupt Requests
-  output logic [alert_pkg::N_CLASSES-1:0] irq_o,
+  output logic [alert_pkg::N_CLASSES-1:0]  irq_o,
+  // State information for HW crashdump
+  output alert_pkg::alert_crashdump_t      crashdump_o,
   // Entropy Input from TRNG
-  input                                   entropy_i,
+  input                                    entropy_i,
   // Alert Sources
-  input        [alert_pkg::NAlerts-1:0]   alert_pi,
-  input        [alert_pkg::NAlerts-1:0]   alert_ni,
-  output logic [alert_pkg::NAlerts-1:0]   ack_po,
-  output logic [alert_pkg::NAlerts-1:0]   ack_no,
-  output logic [alert_pkg::NAlerts-1:0]   ping_po,
-  output logic [alert_pkg::NAlerts-1:0]   ping_no,
+  input        [alert_pkg::NAlerts-1:0]    alert_pi,
+  input        [alert_pkg::NAlerts-1:0]    alert_ni,
+  output logic [alert_pkg::NAlerts-1:0]    ack_po,
+  output logic [alert_pkg::NAlerts-1:0]    ack_no,
+  output logic [alert_pkg::NAlerts-1:0]    ping_po,
+  output logic [alert_pkg::NAlerts-1:0]    ping_no,
   // Escalation outputs
-  output logic [alert_pkg::N_ESC_SEV-1:0] esc_po,
-  output logic [alert_pkg::N_ESC_SEV-1:0] esc_no,
-  input        [alert_pkg::N_ESC_SEV-1:0] resp_pi,
-  input        [alert_pkg::N_ESC_SEV-1:0] resp_ni
+  output logic [alert_pkg::N_ESC_SEV-1:0]  esc_po,
+  output logic [alert_pkg::N_ESC_SEV-1:0]  esc_no,
+  input        [alert_pkg::N_ESC_SEV-1:0]  resp_pi,
+  input        [alert_pkg::N_ESC_SEV-1:0]  resp_ni
 );
 
   //////////////////////////////////////////////////////
@@ -45,6 +47,7 @@
     .tl_i        ,
     .tl_o        ,
     .irq_o       ,
+    .crashdump_o ,
     .hw2reg_wrap ,
     .reg2hw_wrap
   );
diff --git a/hw/ip/alert_handler/rtl/alert_handler_reg_pkg.sv b/hw/ip/alert_handler/rtl/alert_handler_reg_pkg.sv
index 5dd8e1d..fedc0f6 100644
--- a/hw/ip/alert_handler/rtl/alert_handler_reg_pkg.sv
+++ b/hw/ip/alert_handler/rtl/alert_handler_reg_pkg.sv
@@ -11,114 +11,142 @@
 
   struct packed {
     struct packed {
-      logic q; // [832]
+      logic q; // [840]
     } classa;
     struct packed {
-      logic q; // [831]
+      logic q; // [839]
     } classb;
     struct packed {
-      logic q; // [830]
+      logic q; // [838]
     } classc;
     struct packed {
-      logic q; // [829]
+      logic q; // [837]
     } classd;
   } intr_state;
   struct packed {
     struct packed {
-      logic q; // [828]
+      logic q; // [836]
     } classa;
     struct packed {
-      logic q; // [827]
+      logic q; // [835]
     } classb;
     struct packed {
-      logic q; // [826]
+      logic q; // [834]
     } classc;
     struct packed {
-      logic q; // [825]
+      logic q; // [833]
     } classd;
   } intr_enable;
   struct packed {
     struct packed {
-      logic q; // [824]
-      logic qe; // [823]
+      logic q; // [832]
+      logic qe; // [831]
     } classa;
     struct packed {
-      logic q; // [822]
-      logic qe; // [821]
+      logic q; // [830]
+      logic qe; // [829]
     } classb;
     struct packed {
-      logic q; // [820]
-      logic qe; // [819]
+      logic q; // [828]
+      logic qe; // [827]
     } classc;
     struct packed {
-      logic q; // [818]
-      logic qe; // [817]
+      logic q; // [826]
+      logic qe; // [825]
     } classd;
   } intr_test;
   struct packed {
-    logic [0:0] q; // [816:816]
+    logic [0:0] q; // [824:824]
   } regen;
   struct packed {
-    logic [23:0] q; // [815:792]
+    logic [23:0] q; // [823:800]
   } ping_timeout_cyc;
   struct packed {
     struct packed {
-      logic q; // [791]
+      logic q; // [799]
     } en_a0;
     struct packed {
-      logic q; // [790]
+      logic q; // [798]
     } en_a1;
     struct packed {
-      logic q; // [789]
+      logic q; // [797]
     } en_a2;
     struct packed {
-      logic q; // [788]
+      logic q; // [796]
     } en_a3;
   } alert_en;
   struct packed {
     struct packed {
-      logic [1:0] q; // [787:786]
+      logic [1:0] q; // [795:794]
     } class_a0;
     struct packed {
-      logic [1:0] q; // [785:784]
+      logic [1:0] q; // [793:792]
     } class_a1;
     struct packed {
-      logic [1:0] q; // [783:782]
+      logic [1:0] q; // [791:790]
     } class_a2;
     struct packed {
-      logic [1:0] q; // [781:780]
+      logic [1:0] q; // [789:788]
     } class_a3;
   } alert_class;
   struct packed {
     struct packed {
-      logic q; // [779]
+      logic q; // [787]
+    } a0;
+    struct packed {
+      logic q; // [786]
+    } a1;
+    struct packed {
+      logic q; // [785]
+    } a2;
+    struct packed {
+      logic q; // [784]
+    } a3;
+  } alert_cause;
+  struct packed {
+    struct packed {
+      logic q; // [783]
     } en_la0;
     struct packed {
-      logic q; // [778]
+      logic q; // [782]
     } en_la1;
     struct packed {
-      logic q; // [777]
+      logic q; // [781]
     } en_la2;
     struct packed {
-      logic q; // [776]
+      logic q; // [780]
     } en_la3;
   } loc_alert_en;
   struct packed {
     struct packed {
-      logic [1:0] q; // [775:774]
+      logic [1:0] q; // [779:778]
     } class_la0;
     struct packed {
-      logic [1:0] q; // [773:772]
+      logic [1:0] q; // [777:776]
     } class_la1;
     struct packed {
-      logic [1:0] q; // [771:770]
+      logic [1:0] q; // [775:774]
     } class_la2;
     struct packed {
-      logic [1:0] q; // [769:768]
+      logic [1:0] q; // [773:772]
     } class_la3;
   } loc_alert_class;
   struct packed {
     struct packed {
+      logic q; // [771]
+    } la0;
+    struct packed {
+      logic q; // [770]
+    } la1;
+    struct packed {
+      logic q; // [769]
+    } la2;
+    struct packed {
+      logic q; // [768]
+    } la3;
+  } loc_alert_cause;
+  struct packed {
+    struct packed {
       logic q; // [767]
     } en;
     struct packed {
diff --git a/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv b/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv
index a14f124..5d40dbd 100644
--- a/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv
+++ b/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv
@@ -979,7 +979,7 @@
 
     // to internal hardware
     .qe     (),
-    .q      (),
+    .q      (reg2hw.alert_cause.a0.q ),
 
     // to register interface (read)
     .qs     (alert_cause_a0_qs)
@@ -1005,7 +1005,7 @@
 
     // to internal hardware
     .qe     (),
-    .q      (),
+    .q      (reg2hw.alert_cause.a1.q ),
 
     // to register interface (read)
     .qs     (alert_cause_a1_qs)
@@ -1031,7 +1031,7 @@
 
     // to internal hardware
     .qe     (),
-    .q      (),
+    .q      (reg2hw.alert_cause.a2.q ),
 
     // to register interface (read)
     .qs     (alert_cause_a2_qs)
@@ -1057,7 +1057,7 @@
 
     // to internal hardware
     .qe     (),
-    .q      (),
+    .q      (reg2hw.alert_cause.a3.q ),
 
     // to register interface (read)
     .qs     (alert_cause_a3_qs)
@@ -1297,7 +1297,7 @@
 
     // to internal hardware
     .qe     (),
-    .q      (),
+    .q      (reg2hw.loc_alert_cause.la0.q ),
 
     // to register interface (read)
     .qs     (loc_alert_cause_la0_qs)
@@ -1323,7 +1323,7 @@
 
     // to internal hardware
     .qe     (),
-    .q      (),
+    .q      (reg2hw.loc_alert_cause.la1.q ),
 
     // to register interface (read)
     .qs     (loc_alert_cause_la1_qs)
@@ -1349,7 +1349,7 @@
 
     // to internal hardware
     .qe     (),
-    .q      (),
+    .q      (reg2hw.loc_alert_cause.la2.q ),
 
     // to register interface (read)
     .qs     (loc_alert_cause_la2_qs)
@@ -1375,7 +1375,7 @@
 
     // to internal hardware
     .qe     (),
-    .q      (),
+    .q      (reg2hw.loc_alert_cause.la3.q ),
 
     // to register interface (read)
     .qs     (loc_alert_cause_la3_qs)
diff --git a/hw/ip/alert_handler/rtl/alert_handler_reg_wrap.sv b/hw/ip/alert_handler/rtl/alert_handler_reg_wrap.sv
index 539d350..d9fe8ff 100644
--- a/hw/ip/alert_handler/rtl/alert_handler_reg_wrap.sv
+++ b/hw/ip/alert_handler/rtl/alert_handler_reg_wrap.sv
@@ -12,12 +12,15 @@
   output tlul_pkg::tl_d2h_t               tl_o,
   // interrupt
   output logic [alert_pkg::N_CLASSES-1:0] irq_o,
+  // State information for HW crashdump
+  output alert_pkg::alert_crashdump_t     crashdump_o,
   // hw2reg
   input  alert_pkg::hw2reg_wrap_t         hw2reg_wrap,
   // reg2hw
   output alert_pkg::reg2hw_wrap_t         reg2hw_wrap
 );
 
+
   //////////////////////////////////////////////////////
   // reg instance
   //////////////////////////////////////////////////////
@@ -112,7 +115,8 @@
            hw2reg.alert_cause.a1.de,
            hw2reg.alert_cause.a0.de
            } = hw2reg_wrap.alert_cause;
-  //----------------------------------------------------------------------------
+
+  //////////////////////////////////////////////////////////////////////////////
 
   // if a local alert is enabled and it fires,
   // we have to set the corresponding cause bit
@@ -126,6 +130,7 @@
            hw2reg.loc_alert_cause.la1.de,
            hw2reg.loc_alert_cause.la0.de } = hw2reg_wrap.loc_alert_cause;
 
+  // ping timeout in cycles
   // autolock can clear these regs automatically upon entering escalation
   // note: the class must be activated for this to occur
   assign { hw2reg.classd_clren.d,
@@ -172,7 +177,7 @@
                                   reg2hw.alert_en.en_a2.q,
                                   reg2hw.alert_en.en_a1.q,
                                   reg2hw.alert_en.en_a0.q };
-  //----------------------------------------------------------------------------
+  //////////////////////////////////////////////////////////////////////////////
 
   //////////////////////////////////////////////////////////////////////////////
   // classification mapping
@@ -181,7 +186,7 @@
                                      reg2hw.alert_class.class_a2.q,
                                      reg2hw.alert_class.class_a1.q,
                                      reg2hw.alert_class.class_a0.q };
-  //----------------------------------------------------------------------------
+  //////////////////////////////////////////////////////////////////////////////
 
   // local alert enable and class assignments
   assign reg2hw_wrap.loc_alert_en = { reg2hw.loc_alert_en.en_la3.q,
@@ -193,7 +198,7 @@
                                          reg2hw.loc_alert_class.class_la2.q[1:0],
                                          reg2hw.loc_alert_class.class_la1.q[1:0],
                                          reg2hw.loc_alert_class.class_la0.q[1:0]};
-  // ping timeout in cycles
+
   assign reg2hw_wrap.ping_timeout_cyc = reg2hw.ping_timeout_cyc.q;
 
   // class enable
@@ -291,5 +296,25 @@
                                          reg2hw.classa_phase1_cyc.q,
                                          reg2hw.classa_phase0_cyc.q};
 
+  //////////////////////////////////////////////////////
+  // crashdump output
+  //////////////////////////////////////////////////////
+
+  // alert cause output 
+  assign crashdump_o.alert_cause = { reg2hw.alert_cause.a3.q,
+                                     reg2hw.alert_cause.a2.q,
+                                     reg2hw.alert_cause.a1.q,
+                                     reg2hw.alert_cause.a0.q };
+
+  // local alert cause register output
+  assign crashdump_o.loc_alert_cause = { reg2hw.loc_alert_cause.la3.q,
+                                         reg2hw.loc_alert_cause.la2.q,
+                                         reg2hw.loc_alert_cause.la1.q,
+                                         reg2hw.loc_alert_cause.la0.q };
+
+  assign crashdump_o.class_accum_cnt = hw2reg_wrap.class_accum_cnt;
+  assign crashdump_o.class_esc_cnt   = hw2reg_wrap.class_esc_cnt;
+  assign crashdump_o.class_esc_state = hw2reg_wrap.class_esc_state;
+
 endmodule : alert_handler_reg_wrap
 
diff --git a/hw/ip/alert_handler/rtl/alert_pkg.sv b/hw/ip/alert_handler/rtl/alert_pkg.sv
index 226bbcc..2bf9112 100644
--- a/hw/ip/alert_handler/rtl/alert_pkg.sv
+++ b/hw/ip/alert_handler/rtl/alert_pkg.sv
@@ -27,14 +27,26 @@
                             Phase0 = 3'b100, Phase1 = 3'b101, Phase2 = 3'b110,
                             Phase3 = 3'b111} cstate_e;
 
+  // struct containing the current alert handler state
+  // can be used to gather crashdump information in HW
+  typedef struct packed {
+    // alerts
+    logic    [NAlerts-1:0]                  alert_cause;     // alert cause bits
+    logic    [N_LOC_ALERT-1:0]              loc_alert_cause; // local alert cause bits
+    // class state
+    logic    [N_CLASSES-1:0][AccuCntDw-1:0] class_accum_cnt; // current accumulator value
+    logic    [N_CLASSES-1:0][EscCntDw-1:0]  class_esc_cnt;   // current escalation counter value
+    cstate_e [N_CLASSES-1:0]                class_esc_state; // current escalation protocol state
+  } alert_crashdump_t;
+
   // breakout wrapper structs
   typedef struct packed {
     // alerts
     logic    [NAlerts-1:0]                  alert_cause;     // alert cause bits
     logic    [N_LOC_ALERT-1:0]              loc_alert_cause; // local alert cause bits
     // class state
-    logic    [N_CLASSES-1:0]                class_trig;      // class has been triggered
-    logic    [N_CLASSES-1:0]                class_esc_trig;  // escalation has triggered
+    logic    [N_CLASSES-1:0]                class_trig;      // class trigger
+    logic    [N_CLASSES-1:0]                class_esc_trig;  // escalation trigger
     logic    [N_CLASSES-1:0][AccuCntDw-1:0] class_accum_cnt; // current accumulator value
     logic    [N_CLASSES-1:0][EscCntDw-1:0]  class_esc_cnt;   // current escalation counter value
     cstate_e [N_CLASSES-1:0]                class_esc_state; // current escalation protocol state