[tlul] Enable tlul integrity check across the design

Signed-off-by: Timothy Chen <timothytim@google.com>

[tlul] Minor enhancements

- remove commented out code after placing tlul_host_adapter inside lc_ctrl
- add full width parameters to tlul_pkg.sv

Signed-off-by: Timothy Chen <timothytim@google.com>

[dv] Minor hacks to get tlul integrity checks going

Signed-off-by: Timothy Chen <timothytim@google.com>

[top] Auto generate files

Signed-off-by: Timothy Chen <timothytim@google.com>

[tlul] correct comment typo

Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/dv/sv/sim_sram/sim_sram.sv b/hw/dv/sv/sim_sram/sim_sram.sv
index 25d7b40..05aaadf 100644
--- a/hw/dv/sv/sim_sram/sim_sram.sv
+++ b/hw/dv/sv/sim_sram/sim_sram.sv
@@ -96,7 +96,9 @@
       .SramAw     (SramAddrWidth),
       .SramDw     (Width),
       .ErrOnRead  (ErrOnRead),
-      .Outstanding(2)
+      .Outstanding(2),
+      .EnableRspIntgGen(1),
+      .EnableDataIntgGen(1)
     ) u_tl_adapter_sim_sram (
       .clk_i,
       .rst_ni,
diff --git a/hw/dv/sv/sim_sram/tlul_sink.sv b/hw/dv/sv/sim_sram/tlul_sink.sv
index 5220931..4c17190 100644
--- a/hw/dv/sv/sim_sram/tlul_sink.sv
+++ b/hw/dv/sv/sim_sram/tlul_sink.sv
@@ -75,7 +75,8 @@
   //////////////////
   // Final Output //
   //////////////////
-  assign tl_o = '{
+  tlul_pkg::tl_d2h_t tl_o_pre;
+  assign tl_o_pre = '{
     a_ready:  ~pending,
     d_valid:  pending,
     d_opcode: d_opcode_q,
@@ -88,4 +89,9 @@
     d_error:  d_error_q
   };
 
+  tlul_rsp_intg_gen u_gen (
+    .tl_i(tl_o_pre),
+    .tl_o
+  );
+
 endmodule
diff --git a/hw/dv/sv/tl_agent/tl_agent.core b/hw/dv/sv/tl_agent/tl_agent.core
index e8cc477..3acc9b9 100644
--- a/hw/dv/sv/tl_agent/tl_agent.core
+++ b/hw/dv/sv/tl_agent/tl_agent.core
@@ -9,6 +9,7 @@
   files_dv:
     depend:
       - lowrisc:tlul:headers:0.1
+      - lowrisc:prim:secded
       - lowrisc:dv:mem_model
       - lowrisc:dv:dv_lib
       - lowrisc:opentitan:bus_params_pkg
diff --git a/hw/dv/sv/tl_agent/tl_host_driver.sv b/hw/dv/sv/tl_agent/tl_host_driver.sv
index 37baf86..33b7264 100644
--- a/hw/dv/sv/tl_agent/tl_host_driver.sv
+++ b/hw/dv/sv/tl_agent/tl_host_driver.sv
@@ -107,7 +107,7 @@
         cfg.vif.host_cb.h2d_int.a_param   <= req.a_param;
         cfg.vif.host_cb.h2d_int.a_data    <= req.a_data;
         cfg.vif.host_cb.h2d_int.a_mask    <= req.a_mask;
-        cfg.vif.host_cb.h2d_int.a_user    <= tlul_pkg::TL_A_USER_DEFAULT;
+        cfg.vif.host_cb.h2d_int.a_user    <= req.get_a_user_val();
         cfg.vif.host_cb.h2d_int.a_source  <= req.a_source;
         cfg.vif.host_cb.h2d_int.a_valid   <= 1'b1;
       end else begin
diff --git a/hw/dv/sv/tl_agent/tl_seq_item.sv b/hw/dv/sv/tl_agent/tl_seq_item.sv
index c504a1c..e8babee 100644
--- a/hw/dv/sv/tl_agent/tl_seq_item.sv
+++ b/hw/dv/sv/tl_agent/tl_seq_item.sv
@@ -238,7 +238,55 @@
 
   function bit get_error_size_over_max();
     return !(`chk_prot_max_size);
-  endfunction
+  endfunction // get_error_size_over_max
+
+  // Calling secded 64_57 directly does not seem great...
+  // Temporary solution to get dv going
+  virtual function tl_a_user_t get_a_user_val();
+    tl_a_user_t user;
+    tl_h2d_cmd_intg_t cmd_intg_payload;
+    logic [H2DCmdFullWidth - 1:0] payload_intg;
+    logic [D2HRspFullWidth - 1:0] data_intg;
+
+    // construct command integrity
+    cmd_intg_payload.tl_type = DataType;
+    cmd_intg_payload.addr = a_addr;
+    cmd_intg_payload.opcode = tl_a_op_e'(a_opcode);
+    cmd_intg_payload.mask = a_mask;
+    payload_intg = prim_secded_pkg::prim_secded_64_57_enc(H2DCmdMaxWidth'(cmd_intg_payload));
+
+    // construct data integrity
+    data_intg = prim_secded_pkg::prim_secded_64_57_enc(DataMaxWidth'(a_data));
+
+    user.rsvd = '0;
+    user.tl_type = DataType;
+    user.cmd_intg = payload_intg[H2DCmdFullWidth -1 -: H2DCmdIntgWidth];
+    user.data_intg = data_intg[DataFullWidth -1 -: DataIntgWidth];;
+    return user;
+  endfunction // get_a_user_val
+
+  // device facing version of the function above
+  virtual function tl_d_user_t get_d_user_val();
+    tl_d_user_t user;
+    tl_d2h_rsp_intg_t rsp_intg_payload;
+    logic [D2HRspFullWidth - 1:0] payload_intg;
+    logic [D2HRspFullWidth - 1:0] data_intg;
+
+    // construct response integrity
+    rsp_intg_payload.opcode = tl_d_op_e'(d_opcode);
+    rsp_intg_payload.size = d_size;
+    rsp_intg_payload.error = d_error;
+    payload_intg = prim_secded_pkg::prim_secded_64_57_enc(D2HRspMaxWidth'(rsp_intg_payload));
+
+    // construct data integrity
+    data_intg = prim_secded_pkg::prim_secded_64_57_enc(DataMaxWidth'(d_data));
+
+    user.rsp_intg = payload_intg[D2HRspFullWidth -1 -: D2HRspIntgWidth];
+    user.data_intg = data_intg[DataFullWidth -1 -: DataIntgWidth];
+    return user;
+  endfunction // get_d_user_val
+
+
 
   function void disable_a_chan_protocol_constraint();
     a_opcode_c.constraint_mode(0);
diff --git a/hw/ip/aes/rtl/aes_reg_top.sv b/hw/ip/aes/rtl/aes_reg_top.sv
index e9bc512..0fafc28 100644
--- a/hw/ip/aes/rtl/aes_reg_top.sv
+++ b/hw/ip/aes/rtl/aes_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
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 6af994e..f831beb 100644
--- a/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv
+++ b/hw/ip/alert_handler/rtl/alert_handler_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/aon_timer/rtl/aon_timer_reg_top.sv b/hw/ip/aon_timer/rtl/aon_timer_reg_top.sv
index 4253ec6..1aea347 100644
--- a/hw/ip/aon_timer/rtl/aon_timer_reg_top.sv
+++ b/hw/ip/aon_timer/rtl/aon_timer_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/clkmgr/rtl/clkmgr_reg_top.sv b/hw/ip/clkmgr/rtl/clkmgr_reg_top.sv
index 24aa924..da62678 100644
--- a/hw/ip/clkmgr/rtl/clkmgr_reg_top.sv
+++ b/hw/ip/clkmgr/rtl/clkmgr_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/csrng/rtl/csrng_reg_top.sv b/hw/ip/csrng/rtl/csrng_reg_top.sv
index b3e29d8..be56390 100644
--- a/hw/ip/csrng/rtl/csrng_reg_top.sv
+++ b/hw/ip/csrng/rtl/csrng_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/edn/rtl/edn_reg_top.sv b/hw/ip/edn/rtl/edn_reg_top.sv
index 0fef80b..100ec75 100644
--- a/hw/ip/edn/rtl/edn_reg_top.sv
+++ b/hw/ip/edn/rtl/edn_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/entropy_src/rtl/entropy_src_reg_top.sv b/hw/ip/entropy_src/rtl/entropy_src_reg_top.sv
index 021fa74..c7d65ed 100644
--- a/hw/ip/entropy_src/rtl/entropy_src_reg_top.sv
+++ b/hw/ip/entropy_src/rtl/entropy_src_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/flash_ctrl/rtl/flash_ctrl_reg_top.sv b/hw/ip/flash_ctrl/rtl/flash_ctrl_reg_top.sv
index 1721ee4..3480c6a 100644
--- a/hw/ip/flash_ctrl/rtl/flash_ctrl_reg_top.sv
+++ b/hw/ip/flash_ctrl/rtl/flash_ctrl_reg_top.sv
@@ -55,20 +55,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/gpio/rtl/gpio_reg_top.sv b/hw/ip/gpio/rtl/gpio_reg_top.sv
index aa7fc90..069f43d 100644
--- a/hw/ip/gpio/rtl/gpio_reg_top.sv
+++ b/hw/ip/gpio/rtl/gpio_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/hmac/rtl/hmac_reg_top.sv b/hw/ip/hmac/rtl/hmac_reg_top.sv
index 90c9227..7bb0f06 100644
--- a/hw/ip/hmac/rtl/hmac_reg_top.sv
+++ b/hw/ip/hmac/rtl/hmac_reg_top.sv
@@ -55,20 +55,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/i2c/rtl/i2c_reg_top.sv b/hw/ip/i2c/rtl/i2c_reg_top.sv
index 9df5f51..771a1d5 100644
--- a/hw/ip/i2c/rtl/i2c_reg_top.sv
+++ b/hw/ip/i2c/rtl/i2c_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/keymgr/rtl/keymgr_reg_top.sv b/hw/ip/keymgr/rtl/keymgr_reg_top.sv
index 39ecc16..b31b753 100644
--- a/hw/ip/keymgr/rtl/keymgr_reg_top.sv
+++ b/hw/ip/keymgr/rtl/keymgr_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/kmac/rtl/kmac_reg_top.sv b/hw/ip/kmac/rtl/kmac_reg_top.sv
index a0a46b6..2a61981 100644
--- a/hw/ip/kmac/rtl/kmac_reg_top.sv
+++ b/hw/ip/kmac/rtl/kmac_reg_top.sv
@@ -55,20 +55,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/lc_ctrl/rtl/lc_ctrl.sv b/hw/ip/lc_ctrl/rtl/lc_ctrl.sv
index bdb0cc3..4aa28ff 100644
--- a/hw/ip/lc_ctrl/rtl/lc_ctrl.sv
+++ b/hw/ip/lc_ctrl/rtl/lc_ctrl.sv
@@ -115,7 +115,7 @@
   // Life Cycle TAP //
   ////////////////////
 
-  tlul_pkg::tl_h2d_t tap_tl_h2d_pre, tap_tl_h2d;
+  tlul_pkg::tl_h2d_t tap_tl_h2d;
   tlul_pkg::tl_d2h_t tap_tl_d2h;
   lc_ctrl_reg_pkg::lc_ctrl_reg2hw_t tap_reg2hw;
   lc_ctrl_reg_pkg::lc_ctrl_hw2reg_t tap_hw2reg;
@@ -157,6 +157,8 @@
     .clk_o (tck_muxed)
   );
 
+  logic req_ready;
+  assign req_ready = dmi_req_ready & dmi_resp_ready;
   dmi_jtag #(
     .IdcodeValue(IdcodeValue)
   ) u_dmi_jtag (
@@ -166,7 +168,8 @@
     .dmi_rst_no       (                   ), // unused
     .dmi_req_o        ( dmi_req           ),
     .dmi_req_valid_o  ( dmi_req_valid     ),
-    .dmi_req_ready_i  ( dmi_req_ready     ),
+    // unless there is room for response, stall
+    .dmi_req_ready_i  ( req_ready         ),
     .dmi_resp_i       ( dmi_resp          ),
     .dmi_resp_ready_o ( dmi_resp_ready    ),
     .dmi_resp_valid_i ( dmi_resp_valid    ),
@@ -179,32 +182,27 @@
   );
 
   // DMI to TL-UL transducing
-  assign dmi_req_ready            = tap_tl_d2h.a_ready;
-  assign tap_tl_h2d_pre.a_valid   = dmi_req_valid;
-  assign tap_tl_h2d_pre.a_opcode  = (dmi_req.op == dm::DTM_WRITE) ? tlul_pkg::PutFullData :
-                                                               tlul_pkg::Get;
-  // Always read/write 32bit
-  assign tap_tl_h2d_pre.a_size    = top_pkg::TL_SZW'(2'h2);
-  assign tap_tl_h2d_pre.a_mask    = {top_pkg::TL_DBW{1'b1}};
-  // Need to transform register address into byte address.
-  assign tap_tl_h2d_pre.a_address = top_pkg::TL_AW'({dmi_req.addr, 2'b00});
-  assign tap_tl_h2d_pre.a_data    = dmi_req.data;
-  // Unused
-  assign tap_tl_h2d_pre.a_param   = '0;
-  assign tap_tl_h2d_pre.a_source  = '0;
-  // TODO need to add appropriate handling for integrity
-  assign tap_tl_h2d_pre.a_user    = '0;
-
-  tlul_cmd_intg_gen u_tap_intg_gen (
-    .tl_i(tap_tl_h2d_pre),
-    .tl_o(tap_tl_h2d)
+  tlul_adapter_host u_tap_tlul_host (
+    .clk_i,
+    .rst_ni,
+    // do not make a request unless there is room for the response
+    .req_i      ( dmi_req_valid & dmi_resp_ready         ),
+    .gnt_o      ( dmi_req_ready                          ),
+    .addr_i     ( top_pkg::TL_AW'({dmi_req.addr, 2'b00}) ),
+    .we_i       ( dmi_req.op == dm::DTM_WRITE            ),
+    .wdata_i    ( dmi_req.data                           ),
+    .be_i       ( {top_pkg::TL_DBW{1'b1}}                ),
+    .type_i     ( tlul_pkg::DataType                     ),
+    .valid_o    ( dmi_resp_valid                         ),
+    .rdata_o    ( dmi_resp.data                          ),
+    .err_o      (                                        ),
+    .intg_err_o (                                        ),
+    .tl_o       ( tap_tl_h2d                             ),
+    .tl_i       ( tap_tl_d2h                             )
   );
 
   // TL-UL to DMI transducing
-  assign tap_tl_h2d_pre.d_ready  = dmi_resp_ready;
-  assign dmi_resp_valid          = tap_tl_d2h.d_valid;
-  assign dmi_resp.data           = tap_tl_d2h.d_data;
-  assign dmi_resp.resp           = '0; // unused inside dmi_jtag
+  assign dmi_resp.resp = '0; // unused inside dmi_jtag
 
   // These signals are unused
   logic unused_tap_tl_d2h;
diff --git a/hw/ip/lc_ctrl/rtl/lc_ctrl_reg_top.sv b/hw/ip/lc_ctrl/rtl/lc_ctrl_reg_top.sv
index ffc5ca8..6ff365e 100644
--- a/hw/ip/lc_ctrl/rtl/lc_ctrl_reg_top.sv
+++ b/hw/ip/lc_ctrl/rtl/lc_ctrl_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/nmi_gen/rtl/nmi_gen_reg_top.sv b/hw/ip/nmi_gen/rtl/nmi_gen_reg_top.sv
index fbfe218..678d7d3 100644
--- a/hw/ip/nmi_gen/rtl/nmi_gen_reg_top.sv
+++ b/hw/ip/nmi_gen/rtl/nmi_gen_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/otbn/rtl/otbn_reg_top.sv b/hw/ip/otbn/rtl/otbn_reg_top.sv
index 0323486..693e25d 100644
--- a/hw/ip/otbn/rtl/otbn_reg_top.sv
+++ b/hw/ip/otbn/rtl/otbn_reg_top.sv
@@ -55,20 +55,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_top.sv b/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_top.sv
index c6fe56a..e7645cb 100644
--- a/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_top.sv
+++ b/hw/ip/otp_ctrl/rtl/otp_ctrl_reg_top.sv
@@ -55,20 +55,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/pattgen/rtl/pattgen_reg_top.sv b/hw/ip/pattgen/rtl/pattgen_reg_top.sv
index 029d946..2d4c489 100644
--- a/hw/ip/pattgen/rtl/pattgen_reg_top.sv
+++ b/hw/ip/pattgen/rtl/pattgen_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/pinmux/rtl/pinmux_reg_top.sv b/hw/ip/pinmux/rtl/pinmux_reg_top.sv
index 7a30d6c..d655720 100644
--- a/hw/ip/pinmux/rtl/pinmux_reg_top.sv
+++ b/hw/ip/pinmux/rtl/pinmux_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv b/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv
index d30e73f..39eea34 100644
--- a/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv
+++ b/hw/ip/pwrmgr/rtl/pwrmgr_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/rstmgr/rtl/rstmgr_reg_top.sv b/hw/ip/rstmgr/rtl/rstmgr_reg_top.sv
index 2ad0e84..e9154e7 100644
--- a/hw/ip/rstmgr/rtl/rstmgr_reg_top.sv
+++ b/hw/ip/rstmgr/rtl/rstmgr_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/rv_dm/rtl/rv_dm.sv b/hw/ip/rv_dm/rtl/rv_dm.sv
index 40e13d5..9d3d227 100644
--- a/hw/ip/rv_dm/rtl/rv_dm.sv
+++ b/hw/ip/rv_dm/rtl/rv_dm.sv
@@ -337,7 +337,8 @@
     .SramAw(AddressWidthWords),
     .SramDw(BusWidth),
     .Outstanding(1),
-    .ByteAccess(0)
+    .ByteAccess(0),
+    .EnableRspIntgGen(1)
   ) tl_adapter_device_mem (
     .clk_i,
     .rst_ni,
diff --git a/hw/ip/rv_plic/rtl/rv_plic_reg_top.sv b/hw/ip/rv_plic/rtl/rv_plic_reg_top.sv
index ef4be0a..623edaa 100644
--- a/hw/ip/rv_plic/rtl/rv_plic_reg_top.sv
+++ b/hw/ip/rv_plic/rtl/rv_plic_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/rv_timer/rtl/rv_timer_reg_top.sv b/hw/ip/rv_timer/rtl/rv_timer_reg_top.sv
index 4a76ba7..8eb1938 100644
--- a/hw/ip/rv_timer/rtl/rv_timer_reg_top.sv
+++ b/hw/ip/rv_timer/rtl/rv_timer_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/spi_device/rtl/spi_device_reg_top.sv b/hw/ip/spi_device/rtl/spi_device_reg_top.sv
index 2758c15..7325e96 100644
--- a/hw/ip/spi_device/rtl/spi_device_reg_top.sv
+++ b/hw/ip/spi_device/rtl/spi_device_reg_top.sv
@@ -55,20 +55,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/spi_host/rtl/spi_host_reg_top.sv b/hw/ip/spi_host/rtl/spi_host_reg_top.sv
index 960ee32..7878a26 100644
--- a/hw/ip/spi_host/rtl/spi_host_reg_top.sv
+++ b/hw/ip/spi_host/rtl/spi_host_reg_top.sv
@@ -55,20 +55,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/sram_ctrl/rtl/sram_ctrl_reg_top.sv b/hw/ip/sram_ctrl/rtl/sram_ctrl_reg_top.sv
index 9a679d1..e3a8cda 100644
--- a/hw/ip/sram_ctrl/rtl/sram_ctrl_reg_top.sv
+++ b/hw/ip/sram_ctrl/rtl/sram_ctrl_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/tlul/rtl/tlul_adapter_host.sv b/hw/ip/tlul/rtl/tlul_adapter_host.sv
index fb1e42c..934e7b7 100644
--- a/hw/ip/tlul/rtl/tlul_adapter_host.sv
+++ b/hw/ip/tlul/rtl/tlul_adapter_host.sv
@@ -110,14 +110,28 @@
   assign valid_o = tl_i.d_valid;
   assign rdata_o = tl_i.d_data;
 
+  logic intg_err;
   tlul_rsp_intg_chk u_rsp_chk (
     .tl_i,
-    .err_o(intg_err_o)
+    .err_o(intg_err)
   );
 
-  //TODO, fully connect error once DV and memory initialization is ready
-  //assign err_o   = tl_i.d_error | intg_err_o;
-  assign err_o   = tl_i.d_error;
+  logic intg_err_q;
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      intg_err_q <= '0;
+    end else if (intg_err) begin
+      intg_err_q <= 1'b1;
+    end
+  end
+
+  // err_o is transactional.  This allows the host to continue
+  // debug without receiving an endless stream of errors.
+  assign err_o   = tl_i.d_error | intg_err;
+
+  // intg_err_o is permanent once detected, and should be used
+  // to trigger alerts
+  assign intg_err_o = intg_err_q | intg_err;
 
   // Addresses are assumed to be word-aligned, and the bottom bits are ignored
   logic unused_addr_bottom_bits;
diff --git a/hw/ip/tlul/rtl/tlul_cmd_intg_chk.sv b/hw/ip/tlul/rtl/tlul_cmd_intg_chk.sv
index 6dc82d9..1025e08 100644
--- a/hw/ip/tlul/rtl/tlul_cmd_intg_chk.sv
+++ b/hw/ip/tlul/rtl/tlul_cmd_intg_chk.sv
@@ -27,7 +27,9 @@
     .err_o(err)
   );
 
-  assign err_o = |err;
+  // error output is transactional, it is up to the instantiating module
+  // to determine if a permanent latch is feasible
+  assign err_o = tl_i.a_valid & |err;
 
   logic unused_tl;
   assign unused_tl = |tl_i;
diff --git a/hw/ip/tlul/rtl/tlul_pkg.sv b/hw/ip/tlul/rtl/tlul_pkg.sv
index eb02923..ce46ab2 100644
--- a/hw/ip/tlul/rtl/tlul_pkg.sv
+++ b/hw/ip/tlul/rtl/tlul_pkg.sv
@@ -39,10 +39,13 @@
 
   parameter int H2DCmdMaxWidth  = 57;
   parameter int H2DCmdIntgWidth = 7;
+  parameter int H2DCmdFullWidth = H2DCmdMaxWidth + H2DCmdIntgWidth;
   parameter int D2HRspMaxWidth  = 57;
   parameter int D2HRspIntgWidth = 7;
+  parameter int D2HRspFullWidth = D2HRspMaxWidth + D2HRspIntgWidth;
   parameter int DataMaxWidth    = 57;
   parameter int DataIntgWidth   = 7;
+  parameter int DataFullWidth   = DataMaxWidth + DataIntgWidth;
 
   typedef struct packed {
     logic [4:0]                 rsvd;
@@ -114,7 +117,11 @@
   typedef struct packed {
     tl_d_op_e                     opcode;
     logic  [top_pkg::TL_SZW-1:0]  size;
-    logic  [top_pkg::TL_AIW-1:0]  source;
+    // Temporarily removed because source changes throughout the fabric
+    // and thus cannot be used for end-to-end checking.
+    // A different PR will propose a work-around (a hoaky one) to see if
+    // it gets the job done.
+    //logic  [top_pkg::TL_AIW-1:0]  source;
     logic                         error;
   } tl_d2h_rsp_intg_t;
 
@@ -153,7 +160,7 @@
     unused_tlul = ^tl;
     payload.opcode = tl.d_opcode;
     payload.size   = tl.d_size;
-    payload.source = tl.d_source;
+    //payload.source = tl.d_source;
     payload.error  = tl.d_error;
     return payload;
   endfunction // extract_d2h_rsp_intg
diff --git a/hw/ip/tlul/rtl/tlul_rsp_intg_chk.sv b/hw/ip/tlul/rtl/tlul_rsp_intg_chk.sv
index 888820c..09da58a 100644
--- a/hw/ip/tlul/rtl/tlul_rsp_intg_chk.sv
+++ b/hw/ip/tlul/rtl/tlul_rsp_intg_chk.sv
@@ -27,7 +27,12 @@
     .err_o(err)
   );
 
-  assign err_o = |err;
+  // error is not permanently latched as rsp_intg_chk is typically
+  // used near the host.
+  // if the error is permanent, it would imply the host could forever
+  // receive bus errors and lose all ability to debug.
+  // It should be up to the host to determine the permanence of this error.
+  assign err_o = tl_i.d_valid & |err;
 
   logic unused_tl;
   assign unused_tl = |tl_i;
diff --git a/hw/ip/trial1/rtl/trial1_reg_top.sv b/hw/ip/trial1/rtl/trial1_reg_top.sv
index 54d02eb..89bf89f 100644
--- a/hw/ip/trial1/rtl/trial1_reg_top.sv
+++ b/hw/ip/trial1/rtl/trial1_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/uart/rtl/uart_reg_top.sv b/hw/ip/uart/rtl/uart_reg_top.sv
index 128fb33..3b0516a 100644
--- a/hw/ip/uart/rtl/uart_reg_top.sv
+++ b/hw/ip/uart/rtl/uart_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/usbdev/rtl/usbdev_reg_top.sv b/hw/ip/usbdev/rtl/usbdev_reg_top.sv
index b752c6d..2401aed 100644
--- a/hw/ip/usbdev/rtl/usbdev_reg_top.sv
+++ b/hw/ip/usbdev/rtl/usbdev_reg_top.sv
@@ -55,20 +55,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/ip/usbuart/rtl/usbuart_reg_top.sv b/hw/ip/usbuart/rtl/usbuart_reg_top.sv
index 66de953..375da57 100644
--- a/hw/ip/usbuart/rtl/usbuart_reg_top.sv
+++ b/hw/ip/usbuart/rtl/usbuart_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_top.sv b/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_top.sv
index e4671d9..a721e68 100644
--- a/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_top.sv
+++ b/hw/top_earlgrey/ip/alert_handler/rtl/autogen/alert_handler_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv b/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv
index fa0d29d..b5e8247 100644
--- a/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/top_earlgrey/ip/clkmgr/rtl/autogen/clkmgr_reg_top.sv b/hw/top_earlgrey/ip/clkmgr/rtl/autogen/clkmgr_reg_top.sv
index 11bc0fe..635c1dc 100644
--- a/hw/top_earlgrey/ip/clkmgr/rtl/autogen/clkmgr_reg_top.sv
+++ b/hw/top_earlgrey/ip/clkmgr/rtl/autogen/clkmgr_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_reg_top.sv b/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_reg_top.sv
index 1721ee4..3480c6a 100644
--- a/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_reg_top.sv
+++ b/hw/top_earlgrey/ip/flash_ctrl/rtl/autogen/flash_ctrl_reg_top.sv
@@ -55,20 +55,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/top_earlgrey/ip/pinmux/rtl/autogen/pinmux_reg_top.sv b/hw/top_earlgrey/ip/pinmux/rtl/autogen/pinmux_reg_top.sv
index 6f3b368..2d82b84 100644
--- a/hw/top_earlgrey/ip/pinmux/rtl/autogen/pinmux_reg_top.sv
+++ b/hw/top_earlgrey/ip/pinmux/rtl/autogen/pinmux_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv b/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv
index 76afb70..449f196 100644
--- a/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv
+++ b/hw/top_earlgrey/ip/pwrmgr/rtl/autogen/pwrmgr_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/top_earlgrey/ip/rstmgr/rtl/autogen/rstmgr_reg_top.sv b/hw/top_earlgrey/ip/rstmgr/rtl/autogen/rstmgr_reg_top.sv
index 407c03d..621acad 100644
--- a/hw/top_earlgrey/ip/rstmgr/rtl/autogen/rstmgr_reg_top.sv
+++ b/hw/top_earlgrey/ip/rstmgr/rtl/autogen/rstmgr_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/top_earlgrey/ip/rv_plic/rtl/autogen/rv_plic_reg_top.sv b/hw/top_earlgrey/ip/rv_plic/rtl/autogen/rv_plic_reg_top.sv
index 0c29fc7..5e3438f 100644
--- a/hw/top_earlgrey/ip/rv_plic/rtl/autogen/rv_plic_reg_top.sv
+++ b/hw/top_earlgrey/ip/rv_plic/rtl/autogen/rv_plic_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl_reg_top.sv b/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl_reg_top.sv
index bfb4bf2..6757966 100644
--- a/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl_reg_top.sv
+++ b/hw/top_earlgrey/ip/sensor_ctrl/rtl/sensor_ctrl_reg_top.sv
@@ -50,20 +50,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (
diff --git a/util/reggen/reg_top.sv.tpl b/util/reggen/reg_top.sv.tpl
index 1923d19..dd6911d 100644
--- a/util/reggen/reg_top.sv.tpl
+++ b/util/reggen/reg_top.sv.tpl
@@ -75,20 +75,22 @@
   logic intg_err;
   tlul_cmd_intg_chk u_chk (
     .tl_i,
-    // connect this to intg_err later when all DV / hosts are hooked up
-    .err_o()
+    .err_o(intg_err)
   );
-  assign intg_err = 1'b0;
 
-  // Once integrity error is detected, it does not let go until reset.
+  logic intg_err_q;
   always_ff @(posedge clk_i or negedge rst_ni) begin
     if (!rst_ni) begin
-      intg_err_o <= '0;
+      intg_err_q <= '0;
     end else if (intg_err) begin
-      intg_err_o <= 1'b1;
+      intg_err_q <= 1'b1;
     end
   end
 
+  // integrity error output is permanent and should be used for alert generation
+  // register errors are transactional
+  assign intg_err_o = intg_err_q | intg_err;
+
   // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
   tlul_rsp_intg_gen u_rsp_intg_gen (