[alert_handler/top] Integration of alert handler LPGs

Signed-off-by: Michael Schaffner <msf@google.com>
diff --git a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
index 0b91197..c0901b3 100644
--- a/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
+++ b/hw/top_earlgrey/data/autogen/top_earlgrey.gen.hjson
@@ -29,6 +29,7 @@
     {
       top: clkmgr_aon_clocks.
       ext: ""
+      lpg: clkmgr_aon_cg_en.
     }
     srcs:
     [
@@ -178,6 +179,7 @@
     {
       top: rstmgr_aon_resets.
       ext: ""
+      lpg: rstmgr_aon_rst_en.
     }
     nodes:
     [
@@ -2685,6 +2687,8 @@
           act: req
           width: 1
           inst_name: rstmgr_aon
+          default: ""
+          top_signame: rstmgr_aon_rst_en
           index: -1
         }
         {
@@ -2857,6 +2861,8 @@
           act: req
           width: 1
           inst_name: clkmgr_aon
+          default: ""
+          top_signame: clkmgr_aon_cg_en
           index: -1
         }
         {
@@ -7508,7 +7514,9 @@
     top:
     [
       clkmgr_aon.clocks
+      clkmgr_aon.cg_en
       rstmgr_aon.resets
+      rstmgr_aon.rst_en
       rv_core_ibex.irq_timer
       rv_core_ibex.hart_id
       rv_core_ibex.boot_addr
@@ -13113,6 +13121,8 @@
       type: alert
       async: "1"
       module_name: uart0
+      lpg_name: peri_sys_io_div4_0
+      lpg_idx: 0
     }
     {
       name: uart1_fatal_fault
@@ -13120,6 +13130,8 @@
       type: alert
       async: "1"
       module_name: uart1
+      lpg_name: peri_sys_io_div4_0
+      lpg_idx: 0
     }
     {
       name: uart2_fatal_fault
@@ -13127,6 +13139,8 @@
       type: alert
       async: "1"
       module_name: uart2
+      lpg_name: peri_sys_io_div4_0
+      lpg_idx: 0
     }
     {
       name: uart3_fatal_fault
@@ -13134,6 +13148,8 @@
       type: alert
       async: "1"
       module_name: uart3
+      lpg_name: peri_sys_io_div4_0
+      lpg_idx: 0
     }
     {
       name: gpio_fatal_fault
@@ -13141,6 +13157,8 @@
       type: alert
       async: "1"
       module_name: gpio
+      lpg_name: peri_sys_io_div4_0
+      lpg_idx: 0
     }
     {
       name: spi_device_fatal_fault
@@ -13148,6 +13166,8 @@
       type: alert
       async: "1"
       module_name: spi_device
+      lpg_name: peri_spi_device_0
+      lpg_idx: 1
     }
     {
       name: spi_host0_fatal_fault
@@ -13155,6 +13175,8 @@
       type: alert
       async: "1"
       module_name: spi_host0
+      lpg_name: peri_spi_host0_0
+      lpg_idx: 2
     }
     {
       name: spi_host1_fatal_fault
@@ -13162,6 +13184,8 @@
       type: alert
       async: "1"
       module_name: spi_host1
+      lpg_name: peri_spi_host1_0
+      lpg_idx: 3
     }
     {
       name: i2c0_fatal_fault
@@ -13169,6 +13193,8 @@
       type: alert
       async: "1"
       module_name: i2c0
+      lpg_name: peri_i2c0_0
+      lpg_idx: 4
     }
     {
       name: i2c1_fatal_fault
@@ -13176,6 +13202,8 @@
       type: alert
       async: "1"
       module_name: i2c1
+      lpg_name: peri_i2c1_0
+      lpg_idx: 5
     }
     {
       name: i2c2_fatal_fault
@@ -13183,6 +13211,8 @@
       type: alert
       async: "1"
       module_name: i2c2
+      lpg_name: peri_i2c2_0
+      lpg_idx: 6
     }
     {
       name: pattgen_fatal_fault
@@ -13190,6 +13220,8 @@
       type: alert
       async: "1"
       module_name: pattgen
+      lpg_name: peri_sys_io_div4_0
+      lpg_idx: 0
     }
     {
       name: rv_timer_fatal_fault
@@ -13197,6 +13229,8 @@
       type: alert
       async: "1"
       module_name: rv_timer
+      lpg_name: timers_sys_io_div4_0
+      lpg_idx: 7
     }
     {
       name: usbdev_fatal_fault
@@ -13204,6 +13238,8 @@
       type: alert
       async: "1"
       module_name: usbdev
+      lpg_name: peri_usb_0
+      lpg_idx: 8
     }
     {
       name: otp_ctrl_fatal_macro_error
@@ -13211,6 +13247,8 @@
       type: alert
       async: "1"
       module_name: otp_ctrl
+      lpg_name: secure_lc_io_div4_0
+      lpg_idx: 9
     }
     {
       name: otp_ctrl_fatal_check_error
@@ -13218,6 +13256,8 @@
       type: alert
       async: "1"
       module_name: otp_ctrl
+      lpg_name: secure_lc_io_div4_0
+      lpg_idx: 9
     }
     {
       name: otp_ctrl_fatal_bus_integ_error
@@ -13225,6 +13265,8 @@
       type: alert
       async: "1"
       module_name: otp_ctrl
+      lpg_name: secure_lc_io_div4_0
+      lpg_idx: 9
     }
     {
       name: lc_ctrl_fatal_prog_error
@@ -13232,6 +13274,8 @@
       type: alert
       async: "1"
       module_name: lc_ctrl
+      lpg_name: secure_lc_io_div4_0
+      lpg_idx: 9
     }
     {
       name: lc_ctrl_fatal_state_error
@@ -13239,6 +13283,8 @@
       type: alert
       async: "1"
       module_name: lc_ctrl
+      lpg_name: secure_lc_io_div4_0
+      lpg_idx: 9
     }
     {
       name: lc_ctrl_fatal_bus_integ_error
@@ -13246,6 +13292,8 @@
       type: alert
       async: "1"
       module_name: lc_ctrl
+      lpg_name: secure_lc_io_div4_0
+      lpg_idx: 9
     }
     {
       name: pwrmgr_aon_fatal_fault
@@ -13253,6 +13301,8 @@
       type: alert
       async: "1"
       module_name: pwrmgr_aon
+      lpg_name: powerup_por_io_div4_Aon
+      lpg_idx: 10
     }
     {
       name: rstmgr_aon_fatal_fault
@@ -13260,6 +13310,8 @@
       type: alert
       async: "1"
       module_name: rstmgr_aon
+      lpg_name: powerup_por_io_div4_Aon
+      lpg_idx: 10
     }
     {
       name: clkmgr_aon_recov_fault
@@ -13267,6 +13319,8 @@
       type: alert
       async: "1"
       module_name: clkmgr_aon
+      lpg_name: powerup_por_io_div4_Aon
+      lpg_idx: 10
     }
     {
       name: clkmgr_aon_fatal_fault
@@ -13274,6 +13328,8 @@
       type: alert
       async: "1"
       module_name: clkmgr_aon
+      lpg_name: powerup_por_io_div4_Aon
+      lpg_idx: 10
     }
     {
       name: sysrst_ctrl_aon_fatal_fault
@@ -13281,6 +13337,8 @@
       type: alert
       async: "1"
       module_name: sysrst_ctrl_aon
+      lpg_name: infra_sys_io_div4_Aon
+      lpg_idx: 11
     }
     {
       name: adc_ctrl_aon_fatal_fault
@@ -13288,6 +13346,8 @@
       type: alert
       async: "1"
       module_name: adc_ctrl_aon
+      lpg_name: peri_sys_io_div4_Aon
+      lpg_idx: 12
     }
     {
       name: pwm_aon_fatal_fault
@@ -13295,6 +13355,8 @@
       type: alert
       async: "1"
       module_name: pwm_aon
+      lpg_name: powerup_sys_io_div4_Aon
+      lpg_idx: 13
     }
     {
       name: pinmux_aon_fatal_fault
@@ -13302,6 +13364,8 @@
       type: alert
       async: "1"
       module_name: pinmux_aon
+      lpg_name: powerup_sys_io_div4_Aon
+      lpg_idx: 13
     }
     {
       name: aon_timer_aon_fatal_fault
@@ -13309,6 +13373,8 @@
       type: alert
       async: "1"
       module_name: aon_timer_aon
+      lpg_name: timers_lc_io_div4_Aon
+      lpg_idx: 14
     }
     {
       name: sensor_ctrl_recov_alert
@@ -13316,6 +13382,8 @@
       type: alert
       async: "1"
       module_name: sensor_ctrl
+      lpg_name: secure_lc_io_div4_Aon
+      lpg_idx: 15
     }
     {
       name: sensor_ctrl_fatal_alert
@@ -13323,6 +13391,8 @@
       type: alert
       async: "1"
       module_name: sensor_ctrl
+      lpg_name: secure_lc_io_div4_Aon
+      lpg_idx: 15
     }
     {
       name: sram_ctrl_ret_aon_fatal_error
@@ -13330,6 +13400,8 @@
       type: alert
       async: "1"
       module_name: sram_ctrl_ret_aon
+      lpg_name: infra_sys_io_div4_Aon
+      lpg_idx: 11
     }
     {
       name: flash_ctrl_recov_err
@@ -13337,6 +13409,8 @@
       type: alert
       async: "1"
       module_name: flash_ctrl
+      lpg_name: infra_lc_0
+      lpg_idx: 16
     }
     {
       name: flash_ctrl_fatal_err
@@ -13344,6 +13418,8 @@
       type: alert
       async: "1"
       module_name: flash_ctrl
+      lpg_name: infra_lc_0
+      lpg_idx: 16
     }
     {
       name: rv_dm_fatal_fault
@@ -13351,6 +13427,8 @@
       type: alert
       async: "1"
       module_name: rv_dm
+      lpg_name: infra_lc_0
+      lpg_idx: 16
     }
     {
       name: rv_plic_fatal_fault
@@ -13358,6 +13436,8 @@
       type: alert
       async: "1"
       module_name: rv_plic
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: aes_recov_ctrl_update_err
@@ -13365,6 +13445,8 @@
       type: alert
       async: "1"
       module_name: aes
+      lpg_name: trans_sys_0
+      lpg_idx: 18
     }
     {
       name: aes_fatal_fault
@@ -13372,6 +13454,8 @@
       type: alert
       async: "1"
       module_name: aes
+      lpg_name: trans_sys_0
+      lpg_idx: 18
     }
     {
       name: hmac_fatal_fault
@@ -13379,6 +13463,8 @@
       type: alert
       async: "1"
       module_name: hmac
+      lpg_name: trans_sys_0
+      lpg_idx: 18
     }
     {
       name: kmac_fatal_fault
@@ -13386,6 +13472,8 @@
       type: alert
       async: "1"
       module_name: kmac
+      lpg_name: trans_sys_0
+      lpg_idx: 18
     }
     {
       name: otbn_fatal
@@ -13393,6 +13481,8 @@
       type: alert
       async: "1"
       module_name: otbn
+      lpg_name: trans_sys_0
+      lpg_idx: 18
     }
     {
       name: otbn_recov
@@ -13400,6 +13490,8 @@
       type: alert
       async: "1"
       module_name: otbn
+      lpg_name: trans_sys_0
+      lpg_idx: 18
     }
     {
       name: keymgr_fatal_fault_err
@@ -13407,6 +13499,8 @@
       type: alert
       async: "1"
       module_name: keymgr
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: keymgr_recov_operation_err
@@ -13414,6 +13508,8 @@
       type: alert
       async: "1"
       module_name: keymgr
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: csrng_recov_alert
@@ -13421,6 +13517,8 @@
       type: alert
       async: "1"
       module_name: csrng
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: csrng_fatal_alert
@@ -13428,6 +13526,8 @@
       type: alert
       async: "1"
       module_name: csrng
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: entropy_src_recov_alert
@@ -13435,6 +13535,8 @@
       type: alert
       async: "1"
       module_name: entropy_src
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: entropy_src_fatal_alert
@@ -13442,6 +13544,8 @@
       type: alert
       async: "1"
       module_name: entropy_src
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: edn0_recov_alert
@@ -13449,6 +13553,8 @@
       type: alert
       async: "1"
       module_name: edn0
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: edn0_fatal_alert
@@ -13456,6 +13562,8 @@
       type: alert
       async: "1"
       module_name: edn0
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: edn1_recov_alert
@@ -13463,6 +13571,8 @@
       type: alert
       async: "1"
       module_name: edn1
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: edn1_fatal_alert
@@ -13470,6 +13580,8 @@
       type: alert
       async: "1"
       module_name: edn1
+      lpg_name: secure_sys_0
+      lpg_idx: 17
     }
     {
       name: sram_ctrl_main_fatal_error
@@ -13477,6 +13589,8 @@
       type: alert
       async: "1"
       module_name: sram_ctrl_main
+      lpg_name: infra_sys_0
+      lpg_idx: 19
     }
     {
       name: rom_ctrl_fatal
@@ -13484,6 +13598,8 @@
       type: alert
       async: "1"
       module_name: rom_ctrl
+      lpg_name: infra_sys_0
+      lpg_idx: 19
     }
     {
       name: rv_core_ibex_fatal_sw_err
@@ -13491,6 +13607,8 @@
       type: alert
       async: "1"
       module_name: rv_core_ibex
+      lpg_name: infra_sys_0
+      lpg_idx: 19
     }
     {
       name: rv_core_ibex_recov_sw_err
@@ -13498,6 +13616,8 @@
       type: alert
       async: "1"
       module_name: rv_core_ibex
+      lpg_name: infra_sys_0
+      lpg_idx: 19
     }
     {
       name: rv_core_ibex_fatal_hw_err
@@ -13505,6 +13625,8 @@
       type: alert
       async: "1"
       module_name: rv_core_ibex
+      lpg_name: infra_sys_0
+      lpg_idx: 19
     }
     {
       name: rv_core_ibex_recov_hw_err
@@ -13512,9 +13634,214 @@
       type: alert
       async: "1"
       module_name: rv_core_ibex
+      lpg_name: infra_sys_0
+      lpg_idx: 19
     }
   ]
   exported_rsts: {}
+  alert_lpgs:
+  [
+    {
+      name: peri_sys_io_div4_0
+      clock_group: peri
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
+      reset_connection:
+      {
+        name: sys_io_div4
+        domain: "0"
+      }
+    }
+    {
+      name: peri_spi_device_0
+      clock_group: peri
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
+      reset_connection:
+      {
+        name: spi_device
+        domain: "0"
+      }
+    }
+    {
+      name: peri_spi_host0_0
+      clock_group: peri
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
+      reset_connection:
+      {
+        name: spi_host0
+        domain: "0"
+      }
+    }
+    {
+      name: peri_spi_host1_0
+      clock_group: peri
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
+      reset_connection:
+      {
+        name: spi_host1
+        domain: "0"
+      }
+    }
+    {
+      name: peri_i2c0_0
+      clock_group: peri
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
+      reset_connection:
+      {
+        name: i2c0
+        domain: "0"
+      }
+    }
+    {
+      name: peri_i2c1_0
+      clock_group: peri
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
+      reset_connection:
+      {
+        name: i2c1
+        domain: "0"
+      }
+    }
+    {
+      name: peri_i2c2_0
+      clock_group: peri
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
+      reset_connection:
+      {
+        name: i2c2
+        domain: "0"
+      }
+    }
+    {
+      name: timers_sys_io_div4_0
+      clock_group: timers
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_timers
+      reset_connection:
+      {
+        name: sys_io_div4
+        domain: "0"
+      }
+    }
+    {
+      name: peri_usb_0
+      clock_group: peri
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
+      reset_connection:
+      {
+        name: usb
+        domain: "0"
+      }
+    }
+    {
+      name: secure_lc_io_div4_0
+      clock_group: secure
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_secure
+      reset_connection:
+      {
+        name: lc_io_div4
+        domain: "0"
+      }
+    }
+    {
+      name: powerup_por_io_div4_Aon
+      clock_group: powerup
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_powerup
+      reset_connection:
+      {
+        name: por_io_div4
+        domain: Aon
+      }
+    }
+    {
+      name: infra_sys_io_div4_Aon
+      clock_group: infra
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_infra
+      reset_connection:
+      {
+        name: sys_io_div4
+        domain: Aon
+      }
+    }
+    {
+      name: peri_sys_io_div4_Aon
+      clock_group: peri
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_peri
+      reset_connection:
+      {
+        name: sys_io_div4
+        domain: Aon
+      }
+    }
+    {
+      name: powerup_sys_io_div4_Aon
+      clock_group: powerup
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_powerup
+      reset_connection:
+      {
+        name: sys_io_div4
+        domain: Aon
+      }
+    }
+    {
+      name: timers_lc_io_div4_Aon
+      clock_group: timers
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_timers
+      reset_connection:
+      {
+        name: lc_io_div4
+        domain: Aon
+      }
+    }
+    {
+      name: secure_lc_io_div4_Aon
+      clock_group: secure
+      clock_connection: clkmgr_aon_clocks.clk_io_div4_secure
+      reset_connection:
+      {
+        name: lc_io_div4
+        domain: Aon
+      }
+    }
+    {
+      name: infra_lc_0
+      clock_group: infra
+      clock_connection: clkmgr_aon_clocks.clk_main_infra
+      reset_connection:
+      {
+        name: lc
+        domain: "0"
+      }
+    }
+    {
+      name: secure_sys_0
+      clock_group: secure
+      clock_connection: clkmgr_aon_clocks.clk_main_secure
+      reset_connection:
+      {
+        name: sys
+        domain: "0"
+      }
+    }
+    {
+      name: trans_sys_0
+      clock_group: trans
+      clock_connection: clkmgr_aon_clocks.clk_main_aes
+      reset_connection:
+      {
+        name: sys
+        domain: "0"
+      }
+    }
+    {
+      name: infra_sys_0
+      clock_group: infra
+      clock_connection: clkmgr_aon_clocks.clk_main_infra
+      reset_connection:
+      {
+        name: sys
+        domain: "0"
+      }
+    }
+  ]
   inter_signal:
   {
     signals:
@@ -14868,6 +15195,8 @@
         act: req
         width: 1
         inst_name: rstmgr_aon
+        default: ""
+        top_signame: rstmgr_aon_rst_en
         index: -1
       }
       {
@@ -14951,6 +15280,8 @@
         act: req
         width: 1
         inst_name: clkmgr_aon
+        default: ""
+        top_signame: clkmgr_aon_cg_en
         index: -1
       }
       {
@@ -20484,6 +20815,15 @@
         default: ""
       }
       {
+        package: clkmgr_pkg
+        struct: clkmgr_cg_en
+        signame: clkmgr_aon_cg_en
+        width: 1
+        type: uni
+        end_idx: -1
+        default: ""
+      }
+      {
         package: rstmgr_pkg
         struct: rstmgr_out
         signame: rstmgr_aon_resets
@@ -20493,6 +20833,15 @@
         default: ""
       }
       {
+        package: rstmgr_pkg
+        struct: rstmgr_rst_en
+        signame: rstmgr_aon_rst_en
+        width: 1
+        type: uni
+        end_idx: -1
+        default: ""
+      }
+      {
         package: ""
         struct: logic
         signame: rv_core_ibex_irq_timer
diff --git a/hw/top_earlgrey/data/top_earlgrey.hjson b/hw/top_earlgrey/data/top_earlgrey.hjson
index 53a92f7..e3c16fb 100644
--- a/hw/top_earlgrey/data/top_earlgrey.hjson
+++ b/hw/top_earlgrey/data/top_earlgrey.hjson
@@ -36,6 +36,7 @@
     hier_paths: {
       top: "clkmgr_aon_clocks.", // top level is a struct
       ext: "",                   // ext is a port of the clock name
+      lpg: "clkmgr_aon_cg_en.",  // top level struct for alert lpg reset enables
     },
 
     // Clock Source attributes
@@ -106,6 +107,7 @@
     hier_paths: {
       top: "rstmgr_aon_resets.", // top level is a struct
       ext: "",                   // ext is a port of the clock name
+      lpg: "rstmgr_aon_rst_en.", // top level struct for alert lpg reset enables
     },
 
     // Reset node attributes
@@ -898,9 +900,15 @@
         // top level net for clocks
         'clkmgr_aon.clocks',
 
-        // top levle net for reset
+        // top level clock gating indications for alert subsystem
+        'clkmgr_aon.cg_en',
+
+        // top level net for reset
         'rstmgr_aon.resets',
 
+        // top level reset asserted indications for alert subsystem
+        'rstmgr_aon.rst_en',
+
         // dedicated timer interrupt
         'rv_core_ibex.irq_timer',
 
diff --git a/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson b/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson
index 300c18b..b4719fa 100644
--- a/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson
+++ b/hw/top_earlgrey/ip/alert_handler/data/autogen/alert_handler.hjson
@@ -56,13 +56,13 @@
     { name: "NLpg",
       desc: "Number of LPGs.",
       type: "int",
-      default: "1",
+      default: "20",
       local: "true"
     },
     { name: "NLpgWidth",
       desc: "Width of LPG ID.",
       type: "int",
-      default: "1",
+      default: "5",
       local: "true"
     },
     { name: "LpgMap",
@@ -71,7 +71,64 @@
             '''
       type: "logic [NAlerts-1:0][NLpgWidth-1:0]",
       default: '''
-'0
+{5'd19,
+5'd19,
+5'd19,
+5'd19,
+5'd19,
+5'd19,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd18,
+5'd18,
+5'd18,
+5'd18,
+5'd18,
+5'd18,
+5'd17,
+5'd16,
+5'd16,
+5'd16,
+5'd11,
+5'd15,
+5'd15,
+5'd14,
+5'd13,
+5'd13,
+5'd12,
+5'd11,
+5'd10,
+5'd10,
+5'd10,
+5'd10,
+5'd9,
+5'd9,
+5'd9,
+5'd9,
+5'd9,
+5'd9,
+5'd8,
+5'd7,
+5'd0,
+5'd6,
+5'd5,
+5'd4,
+5'd3,
+5'd2,
+5'd1,
+5'd0,
+5'd0,
+5'd0,
+5'd0,
+5'd0}
                ''',
       local: "true"
     },
diff --git a/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_pkg.sv b/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_pkg.sv
index 185e320..151974d 100644
--- a/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_pkg.sv
+++ b/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_pkg.sv
@@ -8,9 +8,66 @@
 
   // Param list
   parameter int NAlerts = 58;
-  parameter int NLpg = 1;
-  parameter int NLpgWidth = 1;
-  parameter logic [NAlerts-1:0][NLpgWidth-1:0] LpgMap = '0;
+  parameter int NLpg = 20;
+  parameter int NLpgWidth = 5;
+  parameter logic [NAlerts-1:0][NLpgWidth-1:0] LpgMap = {5'd19,
+5'd19,
+5'd19,
+5'd19,
+5'd19,
+5'd19,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd17,
+5'd18,
+5'd18,
+5'd18,
+5'd18,
+5'd18,
+5'd18,
+5'd17,
+5'd16,
+5'd16,
+5'd16,
+5'd11,
+5'd15,
+5'd15,
+5'd14,
+5'd13,
+5'd13,
+5'd12,
+5'd11,
+5'd10,
+5'd10,
+5'd10,
+5'd10,
+5'd9,
+5'd9,
+5'd9,
+5'd9,
+5'd9,
+5'd9,
+5'd8,
+5'd7,
+5'd0,
+5'd6,
+5'd5,
+5'd4,
+5'd3,
+5'd2,
+5'd1,
+5'd0,
+5'd0,
+5'd0,
+5'd0,
+5'd0};
   parameter int EscCntDw = 32;
   parameter int AccuCntDw = 16;
   parameter logic [NAlerts-1:0] AsyncOn = 58'h3ffffffffffffff;
diff --git a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
index fb36769..3b181ec 100644
--- a/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
+++ b/hw/top_earlgrey/rtl/autogen/top_earlgrey.sv
@@ -709,7 +709,9 @@
   tlul_pkg::tl_h2d_t       adc_ctrl_aon_tl_req;
   tlul_pkg::tl_d2h_t       adc_ctrl_aon_tl_rsp;
   clkmgr_pkg::clkmgr_out_t       clkmgr_aon_clocks;
+  clkmgr_pkg::clkmgr_cg_en_t       clkmgr_aon_cg_en;
   rstmgr_pkg::rstmgr_out_t       rstmgr_aon_resets;
+  rstmgr_pkg::rstmgr_rst_en_t       rstmgr_aon_rst_en;
   logic       rv_core_ibex_irq_timer;
   logic [31:0] rv_core_ibex_hart_id;
   logic [31:0] rv_core_ibex_boot_addr;
@@ -799,6 +801,71 @@
     .tdo_oe_i (1'b0)
   );
 
+  // Wire up alert handler LPGs
+  lc_ctrl_pkg::lc_tx_t [alert_pkg::NLpg-1:0] lpg_cg_en;
+  lc_ctrl_pkg::lc_tx_t [alert_pkg::NLpg-1:0] lpg_rst_en;
+  // peri_sys_io_div4_0
+  assign lpg_cg_en[0] = clkmgr_aon_cg_en.io_div4_peri;
+  assign lpg_rst_en[0] = rstmgr_aon_rst_en.sys_io_div4[rstmgr_pkg::Domain0Sel];
+  // peri_spi_device_0
+  assign lpg_cg_en[1] = clkmgr_aon_cg_en.io_div4_peri;
+  assign lpg_rst_en[1] = rstmgr_aon_rst_en.spi_device[rstmgr_pkg::Domain0Sel];
+  // peri_spi_host0_0
+  assign lpg_cg_en[2] = clkmgr_aon_cg_en.io_div4_peri;
+  assign lpg_rst_en[2] = rstmgr_aon_rst_en.spi_host0[rstmgr_pkg::Domain0Sel];
+  // peri_spi_host1_0
+  assign lpg_cg_en[3] = clkmgr_aon_cg_en.io_div4_peri;
+  assign lpg_rst_en[3] = rstmgr_aon_rst_en.spi_host1[rstmgr_pkg::Domain0Sel];
+  // peri_i2c0_0
+  assign lpg_cg_en[4] = clkmgr_aon_cg_en.io_div4_peri;
+  assign lpg_rst_en[4] = rstmgr_aon_rst_en.i2c0[rstmgr_pkg::Domain0Sel];
+  // peri_i2c1_0
+  assign lpg_cg_en[5] = clkmgr_aon_cg_en.io_div4_peri;
+  assign lpg_rst_en[5] = rstmgr_aon_rst_en.i2c1[rstmgr_pkg::Domain0Sel];
+  // peri_i2c2_0
+  assign lpg_cg_en[6] = clkmgr_aon_cg_en.io_div4_peri;
+  assign lpg_rst_en[6] = rstmgr_aon_rst_en.i2c2[rstmgr_pkg::Domain0Sel];
+  // timers_sys_io_div4_0
+  assign lpg_cg_en[7] = clkmgr_aon_cg_en.io_div4_timers;
+  assign lpg_rst_en[7] = rstmgr_aon_rst_en.sys_io_div4[rstmgr_pkg::Domain0Sel];
+  // peri_usb_0
+  assign lpg_cg_en[8] = clkmgr_aon_cg_en.io_div4_peri;
+  assign lpg_rst_en[8] = rstmgr_aon_rst_en.usb[rstmgr_pkg::Domain0Sel];
+  // secure_lc_io_div4_0
+  assign lpg_cg_en[9] = clkmgr_aon_cg_en.io_div4_secure;
+  assign lpg_rst_en[9] = rstmgr_aon_rst_en.lc_io_div4[rstmgr_pkg::Domain0Sel];
+  // powerup_por_io_div4_Aon
+  assign lpg_cg_en[10] = clkmgr_aon_cg_en.io_div4_powerup;
+  assign lpg_rst_en[10] = rstmgr_aon_rst_en.por_io_div4[rstmgr_pkg::DomainAonSel];
+  // infra_sys_io_div4_Aon
+  assign lpg_cg_en[11] = clkmgr_aon_cg_en.io_div4_infra;
+  assign lpg_rst_en[11] = rstmgr_aon_rst_en.sys_io_div4[rstmgr_pkg::DomainAonSel];
+  // peri_sys_io_div4_Aon
+  assign lpg_cg_en[12] = clkmgr_aon_cg_en.io_div4_peri;
+  assign lpg_rst_en[12] = rstmgr_aon_rst_en.sys_io_div4[rstmgr_pkg::DomainAonSel];
+  // powerup_sys_io_div4_Aon
+  assign lpg_cg_en[13] = clkmgr_aon_cg_en.io_div4_powerup;
+  assign lpg_rst_en[13] = rstmgr_aon_rst_en.sys_io_div4[rstmgr_pkg::DomainAonSel];
+  // timers_lc_io_div4_Aon
+  assign lpg_cg_en[14] = clkmgr_aon_cg_en.io_div4_timers;
+  assign lpg_rst_en[14] = rstmgr_aon_rst_en.lc_io_div4[rstmgr_pkg::DomainAonSel];
+  // secure_lc_io_div4_Aon
+  assign lpg_cg_en[15] = clkmgr_aon_cg_en.io_div4_secure;
+  assign lpg_rst_en[15] = rstmgr_aon_rst_en.lc_io_div4[rstmgr_pkg::DomainAonSel];
+  // infra_lc_0
+  assign lpg_cg_en[16] = clkmgr_aon_cg_en.main_infra;
+  assign lpg_rst_en[16] = rstmgr_aon_rst_en.lc[rstmgr_pkg::Domain0Sel];
+  // secure_sys_0
+  assign lpg_cg_en[17] = clkmgr_aon_cg_en.main_secure;
+  assign lpg_rst_en[17] = rstmgr_aon_rst_en.sys[rstmgr_pkg::Domain0Sel];
+  // trans_sys_0
+  assign lpg_cg_en[18] = clkmgr_aon_cg_en.main_aes;
+  assign lpg_rst_en[18] = rstmgr_aon_rst_en.sys[rstmgr_pkg::Domain0Sel];
+  // infra_sys_0
+  assign lpg_cg_en[19] = clkmgr_aon_cg_en.main_infra;
+  assign lpg_rst_en[19] = rstmgr_aon_rst_en.sys[rstmgr_pkg::Domain0Sel];
+
+  // Peripheral Instantiation
 
 
   uart #(
@@ -833,7 +900,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_peri),
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   uart #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[1:1])
   ) u_uart1 (
@@ -866,7 +932,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_peri),
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   uart #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[2:2])
   ) u_uart2 (
@@ -899,7 +964,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_peri),
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   uart #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[3:3])
   ) u_uart3 (
@@ -932,7 +996,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_peri),
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   gpio #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[4:4])
   ) u_gpio (
@@ -958,7 +1021,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_peri),
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   spi_device #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[5:5])
   ) u_spi_device (
@@ -1001,7 +1063,6 @@
       .scan_clk_i (clkmgr_aon_clocks.clk_io_div2_peri),
       .rst_ni (rstmgr_aon_resets.rst_spi_device_n[rstmgr_pkg::Domain0Sel])
   );
-
   spi_host #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[6:6])
   ) u_spi_host0 (
@@ -1037,7 +1098,6 @@
       .rst_ni (rstmgr_aon_resets.rst_spi_host0_n[rstmgr_pkg::Domain0Sel]),
       .rst_core_ni (rstmgr_aon_resets.rst_spi_host0_core_n[rstmgr_pkg::Domain0Sel])
   );
-
   spi_host #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[7:7])
   ) u_spi_host1 (
@@ -1073,7 +1133,6 @@
       .rst_ni (rstmgr_aon_resets.rst_spi_host1_n[rstmgr_pkg::Domain0Sel]),
       .rst_core_ni (rstmgr_aon_resets.rst_spi_host1_core_n[rstmgr_pkg::Domain0Sel])
   );
-
   i2c #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[8:8])
   ) u_i2c0 (
@@ -1117,7 +1176,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_peri),
       .rst_ni (rstmgr_aon_resets.rst_i2c0_n[rstmgr_pkg::Domain0Sel])
   );
-
   i2c #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[9:9])
   ) u_i2c1 (
@@ -1161,7 +1219,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_peri),
       .rst_ni (rstmgr_aon_resets.rst_i2c1_n[rstmgr_pkg::Domain0Sel])
   );
-
   i2c #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[10:10])
   ) u_i2c2 (
@@ -1205,7 +1262,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_peri),
       .rst_ni (rstmgr_aon_resets.rst_i2c2_n[rstmgr_pkg::Domain0Sel])
   );
-
   pattgen #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[11:11])
   ) u_pattgen (
@@ -1235,7 +1291,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_peri),
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   rv_timer #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[12:12])
   ) u_rv_timer (
@@ -1254,7 +1309,6 @@
       .clk_i (clkmgr_aon_clocks.clk_io_div4_timers),
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   usbdev #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[13:13])
   ) u_usbdev (
@@ -1327,7 +1381,6 @@
       .rst_aon_ni (rstmgr_aon_resets.rst_sys_aon_n[rstmgr_pkg::Domain0Sel]),
       .rst_usb_48mhz_ni (rstmgr_aon_resets.rst_usbif_n[rstmgr_pkg::Domain0Sel])
   );
-
   otp_ctrl #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[16:14]),
     .MemInitFile(OtpCtrlMemInitFile),
@@ -1389,7 +1442,6 @@
       .rst_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]),
       .rst_edn_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   lc_ctrl #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[19:17]),
     .RndCnstLcKeymgrDivInvalid(RndCnstLcCtrlLcKeymgrDivInvalid),
@@ -1449,7 +1501,6 @@
       .rst_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]),
       .rst_kmac_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   alert_handler #(
     .RndCnstLfsrSeed(RndCnstAlertHandlerLfsrSeed),
     .RndCnstLfsrPerm(RndCnstAlertHandlerLfsrPerm)
@@ -1472,10 +1523,10 @@
       // alert signals
       .alert_rx_o  ( alert_rx ),
       .alert_tx_i  ( alert_tx ),
-
-      // TODO(#8174): top-level integration for LPGs
-      .lpg_cg_en_i ( {lc_ctrl_pkg::Off} ),
-      .lpg_rst_en_i ( {lc_ctrl_pkg::Off} ),
+      // synchronized clock gated / reset asserted
+      // indications for each alert
+      .lpg_cg_en_i  ( lpg_cg_en  ),
+      .lpg_rst_en_i ( lpg_rst_en ),
 
       // Clock and reset connections
       .clk_i (clkmgr_aon_clocks.clk_io_div4_secure),
@@ -1484,7 +1535,6 @@
       .rst_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]),
       .rst_edn_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   pwrmgr #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[20:20])
   ) u_pwrmgr_aon (
@@ -1528,7 +1578,6 @@
       .rst_esc_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel]),
       .rst_slow_ni (rstmgr_aon_resets.rst_por_aon_n[rstmgr_pkg::DomainAonSel])
   );
-
   rstmgr #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[21:21])
   ) u_rstmgr_aon (
@@ -1541,7 +1590,7 @@
       .pwr_i(pwrmgr_aon_pwr_rst_req),
       .pwr_o(pwrmgr_aon_pwr_rst_rsp),
       .resets_o(rstmgr_aon_resets),
-      .rst_en_o(),
+      .rst_en_o(rstmgr_aon_rst_en),
       .rst_cpu_n_i(rv_core_ibex_rst_cpu_n),
       .ndmreset_req_i(rv_dm_ndmreset_req),
       .alert_dump_i(alert_handler_crashdump),
@@ -1561,7 +1610,6 @@
       .clk_io_div4_i (clkmgr_aon_clocks.clk_io_div4_powerup),
       .rst_ni (rstmgr_aon_resets.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel])
   );
-
   clkmgr #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[23:22])
   ) u_clkmgr_aon (
@@ -1572,7 +1620,7 @@
 
       // Inter-module signals
       .clocks_o(clkmgr_aon_clocks),
-      .cg_en_o(),
+      .cg_en_o(clkmgr_aon_cg_en),
       .lc_dft_en_i(lc_ctrl_lc_dft_en),
       .ast_clk_byp_req_o(ast_clk_byp_req_o),
       .ast_clk_byp_ack_i(ast_clk_byp_ack_i),
@@ -1600,7 +1648,6 @@
       .rst_io_div4_ni (rstmgr_aon_resets.rst_por_io_div4_n[rstmgr_pkg::DomainAonSel]),
       .rst_aon_ni (rstmgr_aon_resets.rst_por_aon_n[rstmgr_pkg::DomainAonSel])
   );
-
   sysrst_ctrl #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[24:24])
   ) u_sysrst_ctrl_aon (
@@ -1650,7 +1697,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::DomainAonSel]),
       .rst_aon_ni (rstmgr_aon_resets.rst_sys_aon_n[rstmgr_pkg::DomainAonSel])
   );
-
   adc_ctrl #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[25:25])
   ) u_adc_ctrl_aon (
@@ -1674,7 +1720,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::DomainAonSel]),
       .rst_aon_ni (rstmgr_aon_resets.rst_sys_aon_n[rstmgr_pkg::DomainAonSel])
   );
-
   pwm #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[26:26])
   ) u_pwm_aon (
@@ -1696,7 +1741,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::DomainAonSel]),
       .rst_core_ni (rstmgr_aon_resets.rst_sys_aon_n[rstmgr_pkg::DomainAonSel])
   );
-
   pinmux #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[27:27]),
     .TargetCfg(PinmuxAonTargetCfg)
@@ -1754,7 +1798,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::DomainAonSel]),
       .rst_aon_ni (rstmgr_aon_resets.rst_sys_aon_n[rstmgr_pkg::DomainAonSel])
   );
-
   aon_timer #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[28:28])
   ) u_aon_timer_aon (
@@ -1781,7 +1824,6 @@
       .rst_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::DomainAonSel]),
       .rst_aon_ni (rstmgr_aon_resets.rst_lc_aon_n[rstmgr_pkg::DomainAonSel])
   );
-
   sensor_ctrl #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[30:29])
   ) u_sensor_ctrl (
@@ -1810,7 +1852,6 @@
       .rst_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::DomainAonSel]),
       .rst_aon_ni (rstmgr_aon_resets.rst_lc_aon_n[rstmgr_pkg::DomainAonSel])
   );
-
   sram_ctrl #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[31:31]),
     .RndCnstSramKey(RndCnstSramCtrlRetAonSramKey),
@@ -1842,7 +1883,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_io_div4_n[rstmgr_pkg::DomainAonSel]),
       .rst_otp_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::DomainAonSel])
   );
-
   flash_ctrl #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[33:32]),
     .RndCnstAddrKey(RndCnstFlashCtrlAddrKey),
@@ -1910,7 +1950,6 @@
       .rst_ni (rstmgr_aon_resets.rst_lc_n[rstmgr_pkg::Domain0Sel]),
       .rst_otp_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   rv_dm #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[34:34]),
     .IdcodeValue(RvDmIdcodeValue)
@@ -1940,7 +1979,6 @@
       .clk_i (clkmgr_aon_clocks.clk_main_infra),
       .rst_ni (rstmgr_aon_resets.rst_lc_n[rstmgr_pkg::Domain0Sel])
   );
-
   rv_plic #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[35:35])
   ) u_rv_plic (
@@ -1960,7 +1998,6 @@
       .clk_i (clkmgr_aon_clocks.clk_main_secure),
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   aes #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[37:36]),
     .AES192Enable(1'b1),
@@ -1996,7 +2033,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]),
       .rst_edn_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   hmac #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[38:38])
   ) u_hmac (
@@ -2018,7 +2054,6 @@
       .clk_i (clkmgr_aon_clocks.clk_main_hmac),
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   kmac #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[39:39]),
     .EnMasking(KmacEnMasking),
@@ -2053,7 +2088,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]),
       .rst_edn_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   otbn #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[41:40]),
     .Stub(OtbnStub),
@@ -2093,7 +2127,6 @@
       .rst_edn_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]),
       .rst_otp_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   keymgr #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[43:42]),
     .KmacEnMasking(KeymgrKmacEnMasking),
@@ -2144,7 +2177,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]),
       .rst_edn_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   csrng #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[45:44]),
     .RndCnstCsKeymgrDivNonProduction(RndCnstCsrngCsKeymgrDivNonProduction),
@@ -2178,7 +2210,6 @@
       .clk_i (clkmgr_aon_clocks.clk_main_secure),
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   entropy_src #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[47:46]),
     .Stub(EntropySrcStub)
@@ -2213,7 +2244,6 @@
       .clk_i (clkmgr_aon_clocks.clk_main_secure),
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   edn #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[49:48])
   ) u_edn0 (
@@ -2238,7 +2268,6 @@
       .clk_i (clkmgr_aon_clocks.clk_main_secure),
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   edn #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[51:50])
   ) u_edn1 (
@@ -2263,7 +2292,6 @@
       .clk_i (clkmgr_aon_clocks.clk_main_secure),
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   sram_ctrl #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[52:52]),
     .RndCnstSramKey(RndCnstSramCtrlMainSramKey),
@@ -2295,7 +2323,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]),
       .rst_otp_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   rom_ctrl #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[53:53]),
     .BootRomInitFile(RomCtrlBootRomInitFile),
@@ -2322,7 +2349,6 @@
       .clk_i (clkmgr_aon_clocks.clk_main_infra),
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel])
   );
-
   rv_core_ibex #(
     .AlertAsyncOn(alert_handler_reg_pkg::AsyncOn[57:54]),
     .RndCnstLfsrSeed(RndCnstRvCoreIbexLfsrSeed),
@@ -2385,7 +2411,6 @@
       .rst_ni (rstmgr_aon_resets.rst_sys_n[rstmgr_pkg::Domain0Sel]),
       .rst_esc_ni (rstmgr_aon_resets.rst_lc_io_div4_n[rstmgr_pkg::Domain0Sel])
   );
-
   // interrupt assignments
   assign intr_vector = {
       intr_edn1_edn_fatal_err, // IDs [180 +: 1]
diff --git a/hw/top_englishbreakfast/data/top_englishbreakfast.hjson b/hw/top_englishbreakfast/data/top_englishbreakfast.hjson
index 2045e9d..dc6a966 100644
--- a/hw/top_englishbreakfast/data/top_englishbreakfast.hjson
+++ b/hw/top_englishbreakfast/data/top_englishbreakfast.hjson
@@ -36,6 +36,7 @@
     hier_paths: {
       top: "clkmgr_aon_clocks.", // top level is a struct
       ext: "",                   // ext is a port of the clock name
+      lpg: "clkmgr_aon_cg_en.",  // top level struct for alert lpg reset enables
     },
 
     // Clock Source attributes
@@ -115,6 +116,7 @@
     hier_paths: {
       top: "rstmgr_aon_resets.", // top level is a struct
       ext: "",                   // ext is a port of the clock name
+      lpg: "rstmgr_aon_rst_en.", // top level struct for alert lpg reset enables
     },
 
     // Reset node attributes
@@ -586,8 +588,17 @@
     // It defines the signal in the top and connect from the module,
     // use of the signal is up to top template
     'top': [
-        // reset and clock connections
-        'rstmgr_aon.resets', 'clkmgr_aon.clocks',
+        // top level net for clocks
+        'clkmgr_aon.clocks',
+
+        // top level clock gating indications for alert subsystem
+        'clkmgr_aon.cg_en',
+
+        // top level net for reset
+        'rstmgr_aon.resets',
+
+        // top level reset asserted indications for alert subsystem
+        'rstmgr_aon.rst_en',
 
         // dedicated timer interrupt
         'rv_core_ibex.irq_timer',
diff --git a/util/topgen.py b/util/topgen.py
index c8b1be5..ebabb61 100755
--- a/util/topgen.py
+++ b/util/topgen.py
@@ -35,7 +35,7 @@
 from topgen.gen_top_docs import gen_top_docs
 from topgen.top import Top
 from topgen.clocks import Clocks
-from topgen.merge import extract_clocks, connect_clocks
+from topgen.merge import extract_clocks, connect_clocks, create_alert_lpgs
 from topgen.resets import Resets
 
 # Common header for generated files
@@ -140,19 +140,26 @@
     async_on = "'0"
     # leave this constant
     n_classes = 4
-    # TODO(#8174): topgen integration for LPGs
+    # low power groups
     n_lpg = 1
     lpg_map = "'0"
 
     topname = top["name"]
 
-    if esc_cnt_dw < 1:
-        log.error("EscCntDw must be larger than 0")
-    if accu_cnt_dw < 1:
-        log.error("AccuCntDw must be larger than 0")
-
-    # Count number of alerts
+    # Count number of alerts and LPGs
     n_alerts = sum([x["width"] if "width" in x else 1 for x in top["alert"]])
+    n_lpg = len(top['alert_lpgs'])
+    n_lpg_width = n_lpg.bit_length()
+    # format used to print out LPG map indices in binary format
+    lpg_idx_format = str(n_lpg_width) + "'d{:d},\n"
+
+    # Double check that all these values are greated than 0
+    if esc_cnt_dw < 1:
+        raise ValueError("esc_cnt_dw must be larger than 0")
+    if accu_cnt_dw < 1:
+        raise ValueError("accu_cnt_dw must be larger than 0")
+    if n_lpg < 1:
+        raise ValueError("n_lpg must be larger than 0")
 
     if n_alerts < 1:
         # set number of alerts to 1 such that the config is still valid
@@ -161,17 +168,22 @@
         log.warning("no alerts are defined in the system")
     else:
         async_on = ""
+        lpg_map = ""
         for alert in top['alert']:
             for k in range(alert['width']):
                 async_on = str(alert['async']) + async_on
+                lpg_map = lpg_idx_format.format(alert['lpg_idx']) + lpg_map
         # convert to hexstring to shorten line length
         async_on = ("%d'h" % n_alerts) + hex(int(async_on, 2))[2:]
+        lpg_map = '{' + lpg_map[:-2] + '}'
 
     log.info("alert handler parameterization:")
     log.info("NAlerts   = %d" % n_alerts)
     log.info("EscCntDw  = %d" % esc_cnt_dw)
     log.info("AccuCntDw = %d" % accu_cnt_dw)
     log.info("AsyncOn   = %s" % async_on)
+    log.info("NLpg      = %s" % n_lpg)
+    log.info("LpgMap    = %s" % lpg_map)
 
     # Define target path
     rtl_path = out_path / 'ip/alert_handler/rtl/autogen'
@@ -892,6 +904,10 @@
         if args.plic_only:
             sys.exit()
 
+    # Create Alert Handler LPGs before
+    # generating the Alert Handler
+    create_alert_lpgs(topcfg, name_to_block)
+
     # Generate Alert Handler
     if not args.xbar_only:
         generate_alert_handler(completecfg, out_path)
diff --git a/util/topgen/lib.py b/util/topgen/lib.py
index c3559e7..429fd6b 100644
--- a/util/topgen/lib.py
+++ b/util/topgen/lib.py
@@ -315,6 +315,12 @@
     return top['resets'].get_path(reset['name'], reset['domain'], shadow_sel)
 
 
+def get_reset_lpg_path(top: object, reset: str):
+    """Return the appropriate LPG reset path given name
+    """
+    return top['resets'].get_lpg_path(reset['name'], reset['domain'])
+
+
 def get_unused_resets(top):
     """Return dict of unused resets and associated domain
     """
diff --git a/util/topgen/merge.py b/util/topgen/merge.py
index 0ecb3be..56336d6 100644
--- a/util/topgen/merge.py
+++ b/util/topgen/merge.py
@@ -760,6 +760,52 @@
     top["resets"] = top_resets
 
 
+def create_alert_lpgs(top, name_to_block: Dict[str, IpBlock]):
+    '''Loop over modules and determine number of unique LPGs'''
+    num_lpg = 0
+    lpg_dict = {}
+    top['alert_lpgs'] = []
+    for module in top["module"]:
+        # the alert senders are attached to the primary clock of this block,
+        # so let's start by getting that primary clock.
+        block = name_to_block[module['type']]
+        block_clock = block.get_primary_clock()
+        primary_reset = module['reset_connections'][block_clock.reset]
+
+        # for the purposes of alert handler LPGs, we need to know:
+        #   1) the clock group of the primary clock
+        #   2) the primary reset name
+        #   3) the domain of the primary reset
+        clock_group = module['clock_group']
+        reset_name = primary_reset['name']
+        reset_domain = primary_reset['domain']
+
+        # using this info, we can create an LPG identifier
+        # and uniquify it via a dict.
+        lpg_name = '_'.join([clock_group, reset_name, reset_domain])
+        if lpg_name not in lpg_dict:
+            lpg_dict.update({lpg_name: num_lpg})
+            # since the alert handler can tolerate timing delays on LPG
+            # indication signals, we can just use the clock / reset signals
+            # of the first block that belongs to a new unique LPG.
+            clock = module['clock_connections'][block_clock.clock]
+            top['alert_lpgs'].append({
+                'name': lpg_name,
+                'clock_group': clock_group,
+                'clock_connection': clock,
+                'reset_connection': primary_reset
+            })
+            num_lpg += 1
+
+        # annotate all alerts of this module to use this LPG
+        for alert in top['alert']:
+            if alert['module_name'] == module['name']:
+                alert.update({
+                    'lpg_name': lpg_name,
+                    'lpg_idx': lpg_dict[lpg_name]
+                })
+
+
 def ensure_interrupt_modules(top: OrderedDict, name_to_block: Dict[str, IpBlock]):
     '''Populate top['interrupt_module'] if necessary
 
diff --git a/util/topgen/resets.py b/util/topgen/resets.py
index 264de81..1dd1e8f 100644
--- a/util/topgen/resets.py
+++ b/util/topgen/resets.py
@@ -19,6 +19,7 @@
         self.path = ""
         if self.rst_type == 'top':
             self.path = f"{hier['top']}rst_{self.name}_n"
+            self.lpg_path = f"{hier['lpg']}{self.name}"
         elif self.rst_type == 'ext':
             self.path = f"{hier['ext']}{self.name}"
 
@@ -154,6 +155,24 @@
 
         return path
 
+
+    def get_lpg_path(self, name: str, domain: Optional[str]) -> str:
+        '''Get path to lpg indication signals'''
+
+        reset = self.get_reset_by_name(name)
+        if reset.rst_type == 'int':
+            raise ValueError(f'Reset {name} is not a reset exported from rstmgr')
+
+        if reset.rst_type == 'ext':
+            raise ValueError(f'External reset cannot be associated with an LPG')
+
+        path = reset.lpg_path
+        if domain:
+            path += f'[rstmgr_pkg::Domain{domain}Sel]'
+
+        return path
+
+
     def get_unused_resets(self, domains: list) -> Dict[str, str]:
         '''Get unused resets'''
 
diff --git a/util/topgen/templates/toplevel.sv.tpl b/util/topgen/templates/toplevel.sv.tpl
index b974d25..c1e713f 100644
--- a/util/topgen/templates/toplevel.sv.tpl
+++ b/util/topgen/templates/toplevel.sv.tpl
@@ -296,7 +296,21 @@
     .tdo_oe_i (1'b0)
   );
 
-## Peripheral Instantiation
+  // Wire up alert handler LPGs
+  lc_ctrl_pkg::lc_tx_t [alert_pkg::NLpg-1:0] lpg_cg_en;
+  lc_ctrl_pkg::lc_tx_t [alert_pkg::NLpg-1:0] lpg_rst_en;
+% for k, lpg in enumerate(top['alert_lpgs']):
+  // ${lpg['name']}
+<%
+  ## TODO: need to find a better way to assemble the clock path here.
+  cg_en = top['clocks'].hier_paths['lpg'] + lpg['clock_connection'].split('.clk_')[-1]
+  rst_en = lib.get_reset_lpg_path(top, lpg['reset_connection'])
+%>\
+  assign lpg_cg_en[${k}] = ${cg_en};
+  assign lpg_rst_en[${k}] = ${rst_en};
+% endfor
+
+  // Peripheral Instantiation
 
 <% alert_idx = 0 %>
 % for m in top["module"]:
@@ -403,10 +417,10 @@
       // alert signals
       .alert_rx_o  ( alert_rx ),
       .alert_tx_i  ( alert_tx ),
-
-      // TODO(#8174): top-level integration for LPGs
-      .lpg_cg_en_i ( {lc_ctrl_pkg::Off} ),
-      .lpg_rst_en_i ( {lc_ctrl_pkg::Off} ),
+      // synchronized clock gated / reset asserted
+      // indications for each alert
+      .lpg_cg_en_i  ( lpg_cg_en  ),
+      .lpg_rst_en_i ( lpg_rst_en ),
     % endif
     % if block.scan:
       .scanmode_i,
@@ -429,7 +443,6 @@
       .${port} (${lib.get_reset_path(top, reset)})${"," if not loop.last else ""}
     % endfor
   );
-
 % endfor
   // interrupt assignments
 <% base = interrupt_num %>\