[top] peripheral / host transmission integrity

- Add cmd / rsp generate and checks
- Currently does not natively handle peripherals that have
  windows with built in integrity (otbn). That will be a
  follow-on PR
- Currently the tap interface inside lc_ctrl is not correctly
  handled, that will also be a follow-on PR.
- All error hook-ups are tied to 0 right now, we need to wait for
  host updates and memory initialization before fully enabling them.

Signed-off-by: Timothy Chen <timothytim@google.com>
diff --git a/hw/ip/rv_core_ibex/rtl/rv_core_ibex.sv b/hw/ip/rv_core_ibex/rtl/rv_core_ibex.sv
index 3cd614b..5820aef 100644
--- a/hw/ip/rv_core_ibex/rtl/rv_core_ibex.sv
+++ b/hw/ip/rv_core_ibex/rtl/rv_core_ibex.sv
@@ -266,18 +266,19 @@
   ) tl_adapter_host_i_ibex (
     .clk_i,
     .rst_ni,
-    .req_i   (instr_req),
-    .type_i  (tlul_pkg::InstrType),
-    .gnt_o   (instr_gnt),
-    .addr_i  (instr_addr),
-    .we_i    (1'b0),
-    .wdata_i (32'b0),
-    .be_i    (4'hF),
-    .valid_o (instr_rvalid),
-    .rdata_o (instr_rdata),
-    .err_o   (instr_err),
-    .tl_o    (tl_i_ibex2fifo),
-    .tl_i    (tl_i_fifo2ibex)
+    .req_i      (instr_req),
+    .type_i     (tlul_pkg::InstrType),
+    .gnt_o      (instr_gnt),
+    .addr_i     (instr_addr),
+    .we_i       (1'b0),
+    .wdata_i    (32'b0),
+    .be_i       (4'hF),
+    .valid_o    (instr_rvalid),
+    .rdata_o    (instr_rdata),
+    .err_o      (instr_err),
+    .intg_err_o (),
+    .tl_o       (tl_i_ibex2fifo),
+    .tl_i       (tl_i_fifo2ibex)
   );
 
   tlul_fifo_sync #(
@@ -302,18 +303,19 @@
   ) tl_adapter_host_d_ibex (
     .clk_i,
     .rst_ni,
-    .req_i   (data_req),
-    .type_i  (tlul_pkg::DataType),
-    .gnt_o   (data_gnt),
-    .addr_i  (data_addr),
-    .we_i    (data_we),
-    .wdata_i (data_wdata),
-    .be_i    (data_be),
-    .valid_o (data_rvalid),
-    .rdata_o (data_rdata),
-    .err_o   (data_err),
-    .tl_o    (tl_d_ibex2fifo),
-    .tl_i    (tl_d_fifo2ibex)
+    .req_i      (data_req),
+    .type_i     (tlul_pkg::DataType),
+    .gnt_o      (data_gnt),
+    .addr_i     (data_addr),
+    .we_i       (data_we),
+    .wdata_i    (data_wdata),
+    .be_i       (data_be),
+    .valid_o    (data_rvalid),
+    .rdata_o    (data_rdata),
+    .err_o      (data_err),
+    .intg_err_o (),
+    .tl_o       (tl_d_ibex2fifo),
+    .tl_i       (tl_d_fifo2ibex)
   );
 
   tlul_fifo_sync #(
diff --git a/hw/ip/tlul/adapter_host.core b/hw/ip/tlul/adapter_host.core
index 6383057..786da3a 100644
--- a/hw/ip/tlul/adapter_host.core
+++ b/hw/ip/tlul/adapter_host.core
@@ -10,6 +10,7 @@
     depend:
       - lowrisc:prim:all
       - lowrisc:tlul:common
+      - lowrisc:tlul:trans_intg
       - lowrisc:constants:top_pkg
     files:
       - rtl/tlul_adapter_host.sv
diff --git a/hw/ip/tlul/adapter_reg.core b/hw/ip/tlul/adapter_reg.core
index 97f38d1..3ed3e4c 100644
--- a/hw/ip/tlul/adapter_reg.core
+++ b/hw/ip/tlul/adapter_reg.core
@@ -10,7 +10,7 @@
     depend:
       - lowrisc:prim:all
       - lowrisc:tlul:common
-      - lowrisc:tlul:payload_chk
+      - lowrisc:tlul:trans_intg
     files:
       - rtl/tlul_adapter_reg.sv
     file_type: systemVerilogSource
diff --git a/hw/ip/tlul/rtl/tlul_adapter_host.sv b/hw/ip/tlul/rtl/tlul_adapter_host.sv
index 33a65cb..fb1e42c 100644
--- a/hw/ip/tlul/rtl/tlul_adapter_host.sv
+++ b/hw/ip/tlul/rtl/tlul_adapter_host.sv
@@ -38,6 +38,7 @@
   output logic                       valid_o,
   output logic [top_pkg::TL_DW-1:0]  rdata_o,
   output logic                       err_o,
+  output logic                       intg_err_o,
 
   output tl_h2d_t                    tl_o,
   input  tl_d2h_t                    tl_i
@@ -47,7 +48,6 @@
   logic [top_pkg::TL_AIW-1:0] tl_source;
   logic [top_pkg::TL_DBW-1:0] tl_be;
   tl_h2d_t                    tl_out;
-  tl_a_user_t tl_user;
 
   if (MAX_REQS == 1) begin : g_single_req
     assign tl_source = '0;
@@ -96,37 +96,27 @@
     a_source:  tl_source,
     a_address: {addr_i[31:WordSize], {WordSize{1'b0}}},
     a_data:    wdata_i,
-    a_user:    '{default: '0, chk_en: CheckDis, chk_data: '0, tl_type: type_i},
+    a_user:    '{default: '0, tl_type: type_i},
     d_ready:   1'b1
   };
 
-  logic [H2DCmdMaxWidth-1:0] unused_cmd;
-  logic [H2DCmdChkWidth-1:0] chk_cmd;
-
-  prim_secded_64_57_enc u_enc (
-    .in(H2DCmdMaxWidth'(extract_h2d_cmd_chk(tl_out))),
-    .out({chk_cmd, unused_cmd})
+  tlul_cmd_intg_gen u_cmd_intg_gen (
+    .tl_i(tl_out),
+    .tl_o(tl_o)
   );
 
-  assign tl_user = '{
-    default: '0,
-    tl_type:  type_i,
-    chk_en:   CheckEn,
-    chk_cmd:  chk_cmd,
-    chk_data: '0
-  };
-
-  // override user bits.
-  always_comb begin
-    tl_o = tl_out;
-    tl_o.a_user = tl_user;
-  end
-
-
   assign gnt_o   = tl_i.a_ready;
 
   assign valid_o = tl_i.d_valid;
   assign rdata_o = tl_i.d_data;
+
+  tlul_rsp_intg_chk u_rsp_chk (
+    .tl_i,
+    .err_o(intg_err_o)
+  );
+
+  //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;
 
   // Addresses are assumed to be word-aligned, and the bottom bits are ignored
diff --git a/hw/ip/tlul/rtl/tlul_adapter_reg.sv b/hw/ip/tlul/rtl/tlul_adapter_reg.sv
index 304d000..ec69ebb 100644
--- a/hw/ip/tlul/rtl/tlul_adapter_reg.sv
+++ b/hw/ip/tlul/rtl/tlul_adapter_reg.sv
@@ -9,6 +9,7 @@
  */
 
 module tlul_adapter_reg import tlul_pkg::*; #(
+  parameter  bit EnableDataIntgGen = 1'b0,
   parameter  int RegAw = 8,
   parameter  int RegDw = 32, // Shall be matched with TL_DW
   localparam int RegBw = RegDw/8
@@ -95,6 +96,18 @@
     end
   end
 
+  logic [DataIntgWidth-1:0] data_intg;
+  if (EnableDataIntgGen) begin : gen_data_intg
+    logic [DataMaxWidth-1:0] unused_data;
+
+    prim_secded_64_57_enc u_data_gen (
+      .in(DataMaxWidth'(rdata_i)),
+      .out({data_intg, unused_data})
+    );
+  end else begin : gen_tieoff_data_intg
+    assign data_intg = '0;
+  end
+
   assign tl_o = '{
     a_ready:  ~outstanding,
     d_valid:  outstanding,
@@ -104,8 +117,8 @@
     d_source: reqid,
     d_sink:   '0,
     d_data:   rdata,
-    d_user:  '0,
-    d_error: error
+    d_user:   '{default: '0, data_intg: data_intg},
+    d_error:  error
   };
 
   ////////////////////
diff --git a/hw/ip/tlul/rtl/tlul_cmd_intg_chk.sv b/hw/ip/tlul/rtl/tlul_cmd_intg_chk.sv
new file mode 100644
index 0000000..6dc82d9
--- /dev/null
+++ b/hw/ip/tlul/rtl/tlul_cmd_intg_chk.sv
@@ -0,0 +1,37 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "prim_assert.sv"
+
+/**
+ * Tile-Link UL command integrity check
+ */
+
+module tlul_cmd_intg_chk import tlul_pkg::*; (
+  // TL-UL interface
+  input  tl_h2d_t tl_i,
+
+  // error output
+  output logic err_o
+);
+
+  logic [1:0] err;
+  tl_h2d_cmd_intg_t cmd;
+  assign cmd = extract_h2d_cmd_intg(tl_i);
+
+  prim_secded_64_57_dec u_chk (
+    .in({tl_i.a_user.cmd_intg, H2DCmdMaxWidth'(cmd)}),
+    .d_o(),
+    .syndrome_o(),
+    .err_o(err)
+  );
+
+  assign err_o = |err;
+
+  logic unused_tl;
+  assign unused_tl = |tl_i;
+
+  `ASSERT_INIT(PayLoadWidthCheck, $bits(tl_h2d_cmd_intg_t) <= H2DCmdMaxWidth)
+
+endmodule // tlul_payload_chk
diff --git a/hw/ip/tlul/rtl/tlul_cmd_intg_gen.sv b/hw/ip/tlul/rtl/tlul_cmd_intg_gen.sv
new file mode 100644
index 0000000..7bd65d6
--- /dev/null
+++ b/hw/ip/tlul/rtl/tlul_cmd_intg_gen.sv
@@ -0,0 +1,37 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "prim_assert.sv"
+
+/**
+ * Tile-Link UL command integrity generator
+ */
+
+module tlul_cmd_intg_gen import tlul_pkg::*; (
+  // TL-UL interface
+  input  tl_h2d_t tl_i,
+  output tl_h2d_t tl_o
+);
+
+  tl_h2d_cmd_intg_t cmd;
+  assign cmd = extract_h2d_cmd_intg(tl_i);
+  logic [H2DCmdMaxWidth-1:0] unused_cmd_payload;
+
+  logic [H2DCmdIntgWidth-1:0] cmd_intg;
+  prim_secded_64_57_enc u_cmd_gen (
+    .in(H2DCmdMaxWidth'(cmd)),
+    .out({cmd_intg, unused_cmd_payload})
+  );
+
+  always_comb begin
+    tl_o = tl_i;
+    tl_o.a_user.cmd_intg = cmd_intg;
+  end
+
+  logic unused_tl;
+  assign unused_tl = ^tl_i;
+
+  `ASSERT_INIT(PayMaxWidthCheck_A, $bits(tl_h2d_cmd_intg_t) <= H2DCmdMaxWidth)
+
+endmodule // tlul_rsp_intg_gen
diff --git a/hw/ip/tlul/rtl/tlul_gen_payload_chk.sv b/hw/ip/tlul/rtl/tlul_gen_payload_chk.sv
deleted file mode 100644
index aec7da1..0000000
--- a/hw/ip/tlul/rtl/tlul_gen_payload_chk.sv
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-`include "prim_assert.sv"
-
-/**
- * Tile-Link UL payload checker generator
- */
-
-module tlul_gen_payload_chk import tlul_pkg::*; (
-  // TL-UL interface
-  input  tl_d2h_t tl_i,
-  output tl_d2h_t tl_o
-);
-
-  tl_d2h_rsp_chk_t rsp;
-  logic [D2HRspMaxWidth-1:0] unused_payload;
-  logic [D2HRspChkWidth-1:0] chk;
-  assign rsp = extract_d2h_rsp_chk(tl_i);
-
-  prim_secded_64_57_enc u_gen (
-    .in(D2HRspMaxWidth'(rsp)),
-    .out({chk, unused_payload})
-  );
-
-  always_comb begin
-    tl_o = tl_i;
-    if (tl_i.d_user.chk_en == CheckDis) begin
-      tl_o.d_user.chk_en = CheckEn;
-      tl_o.d_user.chk_rsp = chk;
-    end
-  end
-
-
-  `ASSERT_INIT(PayLoadWidthCheck, $bits(tl_d2h_rsp_chk_t) <= D2HRspMaxWidth)
-
-endmodule // tlul_payload_chk
diff --git a/hw/ip/tlul/rtl/tlul_payload_chk.sv b/hw/ip/tlul/rtl/tlul_payload_chk.sv
deleted file mode 100644
index 91ce7ec..0000000
--- a/hw/ip/tlul/rtl/tlul_payload_chk.sv
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright lowRISC contributors.
-// Licensed under the Apache License, Version 2.0, see LICENSE for details.
-// SPDX-License-Identifier: Apache-2.0
-
-`include "prim_assert.sv"
-
-/**
- * Tile-Link UL payload checker
- */
-
-module tlul_payload_chk import tlul_pkg::*; (
-  // TL-UL interface
-  input  tl_h2d_t tl_i,
-
-  // error output
-  output logic err_o
-);
-
-  logic [1:0] err;
-  tl_h2d_cmd_chk_t cmd;
-  assign cmd = extract_h2d_cmd_chk(tl_i);
-
-  prim_secded_64_57_dec u_chk (
-    .in({tl_i.a_user.chk_cmd, H2DCmdMaxWidth'(cmd)}),
-    .d_o(),
-    .syndrome_o(),
-    .err_o(err)
-  );
-
-  // TODO: The chk_en qualification here should be removed long term under a
-  // compile time option.
-  assign err_o = (tl_i.a_user.chk_en == CheckDis) ? 1'b0 : |err;
-
-  logic unused_tl;
-  assign unused_tl = |tl_i;
-
-  `ASSERT_INIT(PayLoadWidthCheck, $bits(tl_h2d_cmd_chk_t) <= H2DCmdMaxWidth)
-
-endmodule // tlul_payload_chk
diff --git a/hw/ip/tlul/rtl/tlul_pkg.sv b/hw/ip/tlul/rtl/tlul_pkg.sv
index e3c3d91..eb02923 100644
--- a/hw/ip/tlul/rtl/tlul_pkg.sv
+++ b/hw/ip/tlul/rtl/tlul_pkg.sv
@@ -37,44 +37,33 @@
     DataType      = 2'b10
   } tl_type_e;
 
-  // Even though it is codified this way, all values
-  // NOT CheckDis is considered CheckEn
-  typedef enum logic [1:0] {
-    CheckDis      = 2'b01,
-    CheckEn       = 2'b10
-  } tl_chk_en_e;
-
-  parameter int H2DCmdMaxWidth = 57;
-  parameter int H2DCmdChkWidth = 7;
-  parameter int D2HRspMaxWidth = 57;
-  parameter int D2HRspChkWidth = 7;
-
-  //parameter int H2DPayLoadFullWidth = H2DPayLoadMaxWidth + H2DPayLoadChkWidth;
-  parameter int DataMaxWidth = 32;
-  parameter int DataChkWidth = 7;
+  parameter int H2DCmdMaxWidth  = 57;
+  parameter int H2DCmdIntgWidth = 7;
+  parameter int D2HRspMaxWidth  = 57;
+  parameter int D2HRspIntgWidth = 7;
+  parameter int DataMaxWidth    = 57;
+  parameter int DataIntgWidth   = 7;
 
   typedef struct packed {
-    logic [2:0]                    rsvd1;    // Reserved for future use
-    tl_type_e                      tl_type;
-    tl_chk_en_e                    chk_en;
-    logic [H2DCmdChkWidth-1:0]     chk_cmd;
-    logic [DataChkWidth-1:0]       chk_data;
+    logic [4:0]                 rsvd;
+    tl_type_e                   tl_type;
+    logic [H2DCmdIntgWidth-1:0] cmd_intg;
+    logic [DataIntgWidth-1:0]   data_intg;
   } tl_a_user_t;
 
   parameter tl_a_user_t TL_A_USER_DEFAULT = '{
-    rsvd1: '0,
+    rsvd: '0,
     tl_type: DataType,
-    // This value is temporary
-    chk_en: CheckDis,
-    chk_cmd:  '0,
-    chk_data: '0
+    cmd_intg:  '0,
+    data_intg: '0
   };
 
   typedef struct packed {
+    tl_type_e                     tl_type;
     logic   [top_pkg::TL_AW-1:0]  addr;
     tl_a_op_e                     opcode;
     logic  [top_pkg::TL_DBW-1:0]  mask;
-  } tl_h2d_cmd_chk_t;
+  } tl_h2d_cmd_intg_t;
 
   typedef struct packed {
     logic                         a_valid;
@@ -98,15 +87,13 @@
   };
 
   typedef struct packed {
-    logic [4:0]                    rsvd1;    // Reserved for future use
-    tl_chk_en_e                    chk_en;
-    logic [D2HRspChkWidth-1:0]     chk_rsp;
+    logic [D2HRspIntgWidth-1:0]    rsp_intg;
+    logic [DataIntgWidth-1:0]      data_intg;
   } tl_d_user_t;
 
   parameter tl_d_user_t TL_D_USER_DEFAULT = '{
-    rsvd1: '0,
-    chk_en: CheckDis,
-    chk_rsp: '0
+    rsp_intg: '0,
+    data_intg: '0
   };
 
   typedef struct packed {
@@ -129,7 +116,7 @@
     logic  [top_pkg::TL_SZW-1:0]  size;
     logic  [top_pkg::TL_AIW-1:0]  source;
     logic                         error;
-  } tl_d2h_rsp_chk_t;
+  } tl_d2h_rsp_intg_t;
 
   localparam tl_d2h_t TL_D2H_DEFAULT = '{
     a_ready:  1'b1,
@@ -143,25 +130,25 @@
     logic malformed_err;
     logic unused_user;
     unused_user = |user;
-    malformed_err = ~(user.tl_type inside {InstrType, DataType}) |
-                    ~(user.chk_en inside {CheckDis, CheckEn});
+    malformed_err = ~(user.tl_type inside {InstrType, DataType});
     return malformed_err;
   endfunction // tl_a_user_chk
 
   // extract variables used for command checking
-  function automatic tl_h2d_cmd_chk_t extract_h2d_cmd_chk(tl_h2d_t tl);
-    tl_h2d_cmd_chk_t payload;
+  function automatic tl_h2d_cmd_intg_t extract_h2d_cmd_intg(tl_h2d_t tl);
+    tl_h2d_cmd_intg_t payload;
     logic unused_tlul;
     unused_tlul = ^tl;
     payload.addr = tl.a_address;
     payload.opcode = tl.a_opcode;
     payload.mask = tl.a_mask;
+    payload.tl_type = tl.a_user.tl_type;
     return payload;
   endfunction // extract_h2d_payload
 
   // extract variables used for response checking
-  function automatic tl_d2h_rsp_chk_t extract_d2h_rsp_chk(tl_d2h_t tl);
-    tl_d2h_rsp_chk_t payload;
+  function automatic tl_d2h_rsp_intg_t extract_d2h_rsp_intg(tl_d2h_t tl);
+    tl_d2h_rsp_intg_t payload;
     logic unused_tlul;
     unused_tlul = ^tl;
     payload.opcode = tl.d_opcode;
@@ -169,6 +156,6 @@
     payload.source = tl.d_source;
     payload.error  = tl.d_error;
     return payload;
-  endfunction // extract_d2h_rsp_chk
+  endfunction // extract_d2h_rsp_intg
 
 endpackage
diff --git a/hw/ip/tlul/rtl/tlul_rsp_intg_chk.sv b/hw/ip/tlul/rtl/tlul_rsp_intg_chk.sv
new file mode 100644
index 0000000..888820c
--- /dev/null
+++ b/hw/ip/tlul/rtl/tlul_rsp_intg_chk.sv
@@ -0,0 +1,37 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "prim_assert.sv"
+
+/**
+ * Tile-Link UL response integrity check
+ */
+
+module tlul_rsp_intg_chk import tlul_pkg::*; (
+  // TL-UL interface
+  input  tl_d2h_t tl_i,
+
+  // error output
+  output logic err_o
+);
+
+  logic [1:0] err;
+  tl_d2h_rsp_intg_t rsp;
+  assign rsp = extract_d2h_rsp_intg(tl_i);
+
+  prim_secded_64_57_dec u_chk (
+    .in({tl_i.d_user.rsp_intg, D2HRspMaxWidth'(rsp)}),
+    .d_o(),
+    .syndrome_o(),
+    .err_o(err)
+  );
+
+  assign err_o = |err;
+
+  logic unused_tl;
+  assign unused_tl = |tl_i;
+
+  `ASSERT_INIT(PayLoadWidthCheck, $bits(tl_d2h_rsp_intg_t) <= D2HRspMaxWidth)
+
+endmodule // tlul_rsp_intg_chk
diff --git a/hw/ip/tlul/rtl/tlul_rsp_intg_gen.sv b/hw/ip/tlul/rtl/tlul_rsp_intg_gen.sv
new file mode 100644
index 0000000..6ee680e
--- /dev/null
+++ b/hw/ip/tlul/rtl/tlul_rsp_intg_gen.sv
@@ -0,0 +1,55 @@
+// Copyright lowRISC contributors.
+// Licensed under the Apache License, Version 2.0, see LICENSE for details.
+// SPDX-License-Identifier: Apache-2.0
+
+`include "prim_assert.sv"
+
+/**
+ * Tile-Link UL response integrity generator
+ */
+
+module tlul_rsp_intg_gen import tlul_pkg::*; #(
+  parameter bit EnableDataIntgGen = 1'b1
+) (
+  // TL-UL interface
+  input  tl_d2h_t tl_i,
+  output tl_d2h_t tl_o
+);
+
+  tl_d2h_rsp_intg_t rsp;
+  logic [D2HRspMaxWidth-1:0] unused_payload;
+  logic [D2HRspIntgWidth-1:0] rsp_intg;
+  assign rsp = extract_d2h_rsp_intg(tl_i);
+
+  prim_secded_64_57_enc u_rsp_gen (
+    .in(D2HRspMaxWidth'(rsp)),
+    .out({rsp_intg, unused_payload})
+  );
+
+  logic [DataIntgWidth-1:0] data_intg;
+  if (EnableDataIntgGen) begin : gen_data_intg
+    logic [DataMaxWidth-1:0] unused_data;
+
+    prim_secded_64_57_enc u_data_gen (
+      .in(DataMaxWidth'(tl_i.d_data)),
+      .out({data_intg, unused_data})
+    );
+  end else begin : gen_passthrough_data_intg
+    assign data_intg = tl_i.d_user.data_intg;
+  end
+
+
+  always_comb begin
+    tl_o = tl_i;
+    tl_o.d_user.rsp_intg = rsp_intg;
+    tl_o.d_user.data_intg = data_intg;
+  end
+
+  logic unused_tl;
+  assign unused_tl = ^tl_i;
+
+
+  `ASSERT_INIT(PayLoadWidthCheck, $bits(tl_d2h_rsp_intg_t) <= D2HRspMaxWidth)
+  `ASSERT_INIT(DataWidthCheck_A, $bits(tl_i.d_data) <= DataMaxWidth)
+
+endmodule // tlul_rsp_intg_gen
diff --git a/hw/ip/tlul/payload_chk.core b/hw/ip/tlul/trans_intg.core
similarity index 84%
rename from hw/ip/tlul/payload_chk.core
rename to hw/ip/tlul/trans_intg.core
index ef667d4..b3e0ca1 100644
--- a/hw/ip/tlul/payload_chk.core
+++ b/hw/ip/tlul/trans_intg.core
@@ -2,8 +2,8 @@
 # Copyright lowRISC contributors.
 # Licensed under the Apache License, Version 2.0, see LICENSE for details.
 # SPDX-License-Identifier: Apache-2.0
-name: "lowrisc:tlul:payload_chk:0.1"
-description: "TL-UL to Register interface adapter"
+name: "lowrisc:tlul:trans_intg:0.1"
+description: "Tlul transmission integrity"
 
 filesets:
   files_rtl:
@@ -12,8 +12,10 @@
       - lowrisc:prim:secded
       - lowrisc:tlul:common
     files:
-      - rtl/tlul_payload_chk.sv
-      - rtl/tlul_gen_payload_chk.sv
+      - rtl/tlul_cmd_intg_gen.sv
+      - rtl/tlul_cmd_intg_chk.sv
+      - rtl/tlul_rsp_intg_gen.sv
+      - rtl/tlul_rsp_intg_chk.sv
     file_type: systemVerilogSource
 
   files_verilator_waiver:
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 e72f88d..6e28915 100644
--- a/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv
+++ b/hw/top_earlgrey/ip/ast/rtl/ast_reg_top.sv
@@ -17,6 +17,9 @@
   output ast_reg_pkg::ast_reg2hw_t reg2hw, // Write
   input  ast_reg_pkg::ast_hw2reg_t hw2reg, // Read
 
+  // Integrity check errors
+  output logic intg_err_o,
+
   // Config
   input devmode_i // If 1, explicit error return for unmapped register access
 );
@@ -82,6 +85,7 @@
   assign reg_rdata = reg_rdata_next ;
   assign reg_error = (devmode_i & addrmiss) | wr_err | chk_err;
 
+
   // Define SW related signals
   // Format: <reg>_<field>_{wd|we|qs}
   //        or <reg>_{wd|we|qs} if field == 1 or 0
diff --git a/util/reggen/reg_top.sv.tpl b/util/reggen/reg_top.sv.tpl
index c61bed2..474f37c 100644
--- a/util/reggen/reg_top.sv.tpl
+++ b/util/reggen/reg_top.sv.tpl
@@ -38,6 +38,9 @@
   input  ${block.name}_reg_pkg::${block.name}_hw2reg_t hw2reg, // Read
 % endif
 
+  // Integrity check errors
+  output logic intg_err_o,
+
   // Config
   input devmode_i // If 1, explicit error return for unmapped register access
 );
@@ -65,15 +68,26 @@
   tlul_pkg::tl_d2h_t tl_reg_d2h;
 
   // incoming payload check
-  logic chk_err;
-  tlul_payload_chk u_chk (
+  logic intg_err;
+  tlul_cmd_intg_chk u_chk (
     .tl_i,
-    .err_o(chk_err)
+    // connect this to intg_err later when all DV / hosts are hooked up
+    .err_o()
   );
+  assign intg_err = 1'b0;
 
-  // outgoing payload generation
+  // Once integrity error is detected, it does not let go until reset.
+  always_ff @(posedge clk_i or negedge rst_ni) begin
+    if (!rst_ni) begin
+      intg_err_o <= '0;
+    end else if (intg_err) begin
+      intg_err_o <= 1'b1;
+    end
+  end
+
+  // outgoing integrity generation
   tlul_pkg::tl_d2h_t tl_o_pre;
-  tlul_gen_payload_chk u_gen_chk (
+  tlul_rsp_intg_gen u_rsp_intg_gen (
     .tl_i(tl_o_pre),
     .tl_o
   );
@@ -136,7 +150,7 @@
       reg_steer = ${i};
     end
   % endfor
-    if (chk_err) begin
+    if (intg_err) begin
       reg_steer = ${num_dsp-1};
     end
   end
@@ -162,7 +176,7 @@
   );
 
   assign reg_rdata = reg_rdata_next ;
-  assign reg_error = (devmode_i & addrmiss) | wr_err | chk_err;
+  assign reg_error = (devmode_i & addrmiss) | wr_err | intg_err;
 
   // Define SW related signals
   // Format: <reg>_<field>_{wd|we|qs}