Repository: zeroasiccorp/umi (language: python)

Issue:
Catch up to main



Discussion / hints:

Fix patch:
diff --git a/umi/rtl/umi_fifo_flex.v b/umi/rtl/umi_fifo_flex.v
index 1fb975e..c16f95f 100644
--- a/umi/rtl/umi_fifo_flex.v
+++ b/umi/rtl/umi_fifo_flex.v
@@ -17,14 +17,14 @@
  *
  * Documentation:
  * - Converts UMI transactions between different width options.
- * - Currently does not support merge small -> large
  *
  * Future enhancements:
- * 1. merge small->large transactions (adds latency)
- * 2. do not split large->small transactions in case they carry no data
+ * 1. do not split large->small transactions in case they carry no data
  *
  * Known limitation/bugs:
  * - Does not handle cases where SIZE>ODW (does not manipulate SIZE)
+ * - When ODW>IDW, incoming transaction is merged only if merged transaction
+ *   does not cross ODW boundary (num_merged_bits + IDW)<=ODW
  *
  ******************************************************************************/
 
@@ -69,33 +69,40 @@ module umi_fifo_flex
    // Local FIFO
    wire [ODW+AW+AW+CW-1:0] fifo_dout;
    wire [ODW+AW+AW+CW-1:0] fifo_din;
+   wire                    fifo_full_raw;
+   wire                    fifo_empty_raw;
+   wire                    fifo_read;
+   wire                    fifo_write;
+
+   // Split/merge packet latch
    reg                     packet_latch_valid;
    wire                    packet_latch_en;
    reg [CW-1:0]            packet_cmd_latch;
    reg [AW-1:0]            packet_dstaddr_latch;
    reg [AW-1:0]            packet_srcaddr_latch;
-   reg [IDW-1:0]           packet_data_latch;
    wire [CW-1:0]           packet_cmd;
    wire [AW-1:0]           latch_dstaddr;
-   wire [AW-1:0]           fifo_dstaddr;
    wire [AW-1:0]           latch_srcaddr;
-   wire [AW-1:0]           fifo_srcaddr;
    wire [IDW-1:0]          latch_data;
-   wire [IDW-1:0]          fifo_data;
-   wire                    fifo_full_raw;
-   wire                    fifo_empty_raw;
+
+   localparam MAX_DW = (ODW > IDW) ? ODW : IDW;
+
+   // Split/merge to fifo
+   wire [AW-1:0]           latch2fifo_dstaddr;
+   wire [AW-1:0]           latch2fifo_srcaddr;
+   wire [MAX_DW-1:0]       latch2fifo_data;
+   wire [7:0]              latch2fifo_len;
+   wire                    latch2fifo_eom;
+   wire                    latch2fifo_valid;
+   wire                    latch2fifo_ready;
+   wire                    latch2in_ready;
 
    // local wires
    wire                    umi_out_beat;
-   wire                    fifo_read;
-   wire                    fifo_write;
    wire                    fifo_in_ready;
-   wire [7:0]              fifo_len;
    wire [7:0]              latch_len;
-   reg                     last_sent;
    wire [8:0]              cmd_len_plus_one;
-   reg [1:0]               fifo_ready;
-   wire                    fifo_eom;
+   wire                    fifo_out_of_reset;
    wire [AW-1:0]           addr_mask;
    wire [AW-1:0]           dstaddr_masked;
 
@@ -114,15 +121,122 @@ module umi_fifo_flex
    wire [2:0]           cmd_size;
    wire [1:0]           cmd_user;
    wire [23:0]          cmd_user_extended;
-   wire [CW-1:0]        fifo_cmd;
+   wire [CW-1:0]        latch2fifo_cmd;
    wire [CW-1:0]        latch_cmd;
    // End of automatics
 
+   //#################################
+   // Input decoding
+   //#################################
+   wire [4:0]           umi_in_cmd_opcode;
+   wire [2:0]           umi_in_cmd_size;
+   wire [7:0]           umi_in_cmd_len;
+   wire [7:0]           umi_in_cmd_atype;
+   wire [3:0]           umi_in_cmd_qos;
+   wire [1:0]           umi_in_cmd_prot;
+   wire                 umi_in_cmd_eom;
+   wire                 umi_in_cmd_eof;
+   wire                 umi_in_cmd_ex;
+   wire [1:0]           umi_in_cmd_user;
+   wire [23:0]          umi_in_cmd_user_extended;
+   wire [1:0]           umi_in_cmd_err;
+   wire [4:0]           umi_in_cmd_hostid;
+
+   umi_unpack #(.CW(CW))
+   umi_unpack_i(
+                // Outputs
+                .cmd_opcode         (umi_in_cmd_opcode[4:0]),
+                .cmd_size           (umi_in_cmd_size[2:0]),
+                .cmd_len            (umi_in_cmd_len[7:0]),
+                .cmd_atype          (umi_in_cmd_atype[7:0]),
+                .cmd_qos            (umi_in_cmd_qos[3:0]),
+                .cmd_prot           (umi_in_cmd_prot[1:0]),
+                .cmd_eom            (umi_in_cmd_eom),
+                .cmd_eof            (umi_in_cmd_eof),
+                .cmd_ex             (umi_in_cmd_ex),
+                .cmd_user           (umi_in_cmd_user[1:0]),
+                .cmd_user_extended  (umi_in_cmd_user_extended[23:0]),
+                .cmd_err            (umi_in_cmd_err[1:0]),
+                .cmd_hostid         (umi_in_cmd_hostid[4:0]),
+                // Inputs
+                .packet_cmd         (umi_in_cmd[CW-1:0]));
+
+   wire                 umi_in_cmd_invalid;
+
+   wire                 umi_in_cmd_request;
+   wire                 umi_in_cmd_response;
+
+   wire                 umi_in_cmd_read;
+   wire                 umi_in_cmd_write;
+
+   wire                 umi_in_cmd_write_posted;
+   wire                 umi_in_cmd_rdma;
+   wire                 umi_in_cmd_atomic;
+   wire                 umi_in_cmd_user0;
+   wire                 umi_in_cmd_future0;
+   wire                 umi_in_cmd_error;
+   wire                 umi_in_cmd_link;
+
+   wire                 umi_in_cmd_read_resp;
+   wire                 umi_in_cmd_write_resp;
+   wire                 umi_in_cmd_user0_resp;
+   wire                 umi_in_cmd_user1_resp;
+   wire                 umi_in_cmd_future0_resp;
+   wire                 umi_in_cmd_future1_resp;
+   wire                 umi_in_cmd_link_resp;
+
+   wire                 umi_in_cmd_atomic_add;
+   wire                 umi_in_cmd_atomic_and;
+   wire                 umi_in_cmd_atomic_or;
+   wire                 umi_in_cmd_atomic_xor;
+   wire                 umi_in_cmd_atomic_max;
+   wire                 umi_in_cmd_atomic_min;
+   wire                 umi_in_cmd_atomic_maxu;
+   wire                 umi_in_cmd_atomic_minu;
+   wire                 umi_in_cmd_atomic_swap;
+
+   umi_decode #(.CW(CW))
+   umi_decode_i(
+                // Packet Command
+                .command            (umi_in_cmd[CW-1:0]),
+                .cmd_invalid        (umi_in_cmd_invalid),
+                // request/response/link
+                .cmd_request        (umi_in_cmd_request),
+                .cmd_response       (umi_in_cmd_response),
+                // requests
+                .cmd_read           (umi_in_cmd_read),
+                .cmd_write          (umi_in_cmd_write),
+                .cmd_write_posted   (umi_in_cmd_write_posted),
+                .cmd_rdma           (umi_in_cmd_rdma),
+                .cmd_atomic         (umi_in_cmd_atomic),
+                .cmd_user0          (umi_in_cmd_user0),
+                .cmd_future0        (umi_in_cmd_future0),
+                .cmd_error          (umi_in_cmd_error),
+                .cmd_link           (umi_in_cmd_link),
+                // Response (device -> host)
+                .cmd_read_resp      (umi_in_cmd_read_resp),
+                .cmd_write_resp     (umi_in_cmd_write_resp),
+                .cmd_user0_resp     (umi_in_cmd_user0_resp),
+                .cmd_user1_resp     (umi_in_cmd_user1_resp),
+                .cmd_future0_resp   (umi_in_cmd_future0_resp),
+                .cmd_future1_resp   (umi_in_cmd_future1_resp),
+                .cmd_link_resp      (umi_in_cmd_link_resp),
+                // Atomic operations
+                .cmd_atomic_add     (umi_in_cmd_atomic_add),
+                .cmd_atomic_and     (umi_in_cmd_atomic_and),
+                .cmd_atomic_or      (umi_in_cmd_atomic_or),
+                .cmd_atomic_xor     (umi_in_cmd_atomic_xor),
+                .cmd_atomic_max     (umi_in_cmd_atomic_max),
+                .cmd_atomic_min     (umi_in_cmd_atomic_min),
+                .cmd_atomic_maxu    (umi_in_cmd_atomic_maxu),
+                .cmd_atomic_minu    (umi_in_cmd_atomic_minu),
+                .cmd_atomic_swap    (umi_in_cmd_atomic_swap));
+
    //#################################
    // Packet manipulation
    //#################################
    umi_unpack #(.CW(CW))
-   umi_unpack_i(/*AUTOINST*/
+   umi_unpack_packet(/*AUTOINST*/
                 // Outputs
                 .cmd_opcode     (cmd_opcode[4:0]),
                 .cmd_size       (cmd_size[2:0]),
@@ -146,10 +260,159 @@ module umi_fifo_flex
    // cmd manipulation - at each cycle need to remove the bytes sent out
    // SPLIT will also split based on crossing DW boundary and not only size
 
-   generate if (SPLIT == 1)
+   generate if (ODW > IDW)
+     begin
+
+        reg  [ODW-1:0]  packet_data_latch;
+
+        //#################################
+        // Merged byte counter
+        //#################################
+        reg  [8:0]      latch_bytes;
+        wire [8:0]      latch_in_bytes;
+        wire [8:0]      latch_out_bytes;
+
+        wire [ODW-1:0]  umi_in_data_shifted;
+
+        assign latch_in_bytes = ((umi_in_cmd_len + 8'h01) << umi_in_cmd_size);
+
+        always @(posedge umi_in_clk or negedge umi_in_nreset)
+          if (~umi_in_nreset)
+               latch_bytes <= 'b0;
+          else if (umi_in_valid & umi_in_ready & fifo_write)
+               latch_bytes <= latch_in_bytes;
+           else if (umi_in_valid & umi_in_ready)
+               latch_bytes <= latch_bytes + latch_in_bytes;
+          else if (fifo_write)
+               latch_bytes <= 'b0;
+
+        //#################################
+        // Check Mergeability
+        //#################################
+        wire            opcode_mergeable;
+        wire            misc_mergeable;
+        wire            dstaddr_mergeable;
+        wire            srcaddr_mergeable;
+        wire            len_mergeable;
+        wire            tx_mergeable;
+
+        // Check opcode type and ensure opcode match across cycles
+        assign opcode_mergeable = (umi_in_cmd_read | umi_in_cmd_write |
+                                  umi_in_cmd_write_posted | umi_in_cmd_rdma |
+                                  umi_in_cmd_read_resp | umi_in_cmd_write_resp) &
+                                  !umi_in_cmd_ex & (umi_in_cmd_opcode == cmd_opcode);
+
+        assign misc_mergeable = (umi_in_cmd_size == cmd_size) &
+                                (umi_in_cmd_qos == cmd_qos) &
+                                (umi_in_cmd_prot == cmd_prot) &
+                                (umi_in_cmd_eof == cmd_eof) &
+                                (umi_in_cmd_user == cmd_user) &
+                                (umi_in_cmd_err == cmd_err) &
+                                (umi_in_cmd_hostid == cmd_hostid);
+
+        assign dstaddr_mergeable = (umi_in_dstaddr == (packet_dstaddr_latch + {{(AW-9){1'b0}}, latch_bytes}));
+        assign srcaddr_mergeable = (umi_in_srcaddr == (packet_srcaddr_latch + {{(AW-9){1'b0}}, latch_bytes})) |
+                                   umi_in_cmd_response;
+        assign len_mergeable = (latch_bytes + latch_in_bytes) <= (ODW >> 3);
+
+        assign tx_mergeable = opcode_mergeable & misc_mergeable &
+                              dstaddr_mergeable & srcaddr_mergeable &
+                              len_mergeable;
+
+        reg             packet_latch_eom;
+        wire            packet_boundary;
+        reg             packet_boundary_latch;
+
+        assign packet_cmd[CW-1:0] = packet_latch_valid ?
+                                    packet_cmd_latch[CW-1:0] :
+                                    umi_in_cmd[CW-1:0] & {CW{umi_in_valid}};
+
+        // Fifo signal - current command going out
+        assign latch2fifo_dstaddr = packet_dstaddr_latch;
+        assign latch2fifo_srcaddr = packet_srcaddr_latch;
+        assign latch2fifo_data    = packet_data_latch;
+        // cmd manipulation - at each cycle need to remove the bytes sent out
+        assign latch2fifo_eom     = packet_latch_eom;
+        /* verilator lint_off WIDTHTRUNC */
+        assign latch2fifo_len     = (latch_bytes >> cmd_size) - 8'h1;
+        /* verilator lint_on WIDTHTRUNC */
+        assign latch2fifo_valid   = (packet_boundary | packet_boundary_latch) & (latch_bytes > 0);
+        assign latch2fifo_ready   = (tx_mergeable & !packet_latch_eom) |
+                                    (tx_mergeable & packet_latch_eom & (latch_bytes == 0)) |
+                                    (!tx_mergeable & (latch_bytes == 0));
+        assign latch2in_ready     = latch2fifo_ready;
+
+        // Latched command for next split
+        // Unused for merge
+        assign latch_dstaddr = 'b0;
+        assign latch_srcaddr = 'b0;
+        assign latch_data    = 'b0;
+        assign latch_len     = 'b0;
+
+        assign packet_boundary    = packet_latch_eom | !tx_mergeable | !umi_in_valid;
+        always @(posedge umi_in_clk or negedge umi_in_nreset)
+          if (~umi_in_nreset)
+            packet_boundary_latch <= 1'b1;
+          else if (umi_in_valid & umi_in_ready)
+            packet_boundary_latch <= 1'b0;
+          else if (packet_boundary)
+            packet_boundary_latch <= 1'b1;
+
+        // Packet latch
+        always @(posedge umi_in_clk or negedge umi_in_nreset)
+          if (~umi_in_nreset)
+            begin
+               packet_latch_valid   <= 1'b0;
+               packet_dstaddr_latch <= {AW{1'b0}};
+               packet_srcaddr_latch <= {AW{1'b0}};
+            end
+          else if ((umi_in_ready & umi_in_valid) & (packet_boundary | fifo_write))
+            begin
+               packet_latch_valid   <= 1'b1;
+               packet_dstaddr_latch <= umi_in_dstaddr;
+               packet_srcaddr_latch <= umi_in_srcaddr;
+            end
+          else if (fifo_write)
+            begin
+               packet_latch_valid   <= 1'b0;
+            end
+
+        always @(posedge umi_in_clk or negedge umi_in_nreset)
+          if (~umi_in_nreset)
+            packet_cmd_latch     <= {CW{1'b0}};
+          else if (umi_in_ready & umi_in_valid)
+            packet_cmd_latch     <= latch_cmd;
+
+        always @(posedge umi_in_clk or negedge umi_in_nreset)
+          if (~umi_in_nreset)
+            packet_latch_eom     <= 1'b0;
+          else if (umi_in_ready & umi_in_valid)
+            packet_latch_eom     <= umi_in_cmd_eom;
+
+        // NOTE: Here, the correct shift would be
+        // (latch_bytes - latch_out_bytes) << 3
+        // However, if latch_out_bytes is non zero then the first 'else if'
+        // in the always block will be hit and umi_in_data_shifted will not
+        // be used. So to simplify we can use (latch_bytes << 3).
+        /* verilator lint_off WIDTHEXPAND */
+        assign umi_in_data_shifted = umi_in_data << (latch_bytes << 3);
+        /* verilator lint_on WIDTHEXPAND */
+
+        always @(posedge umi_in_clk or negedge umi_in_nreset)
+          if (~umi_in_nreset)
+               packet_data_latch    <= {ODW{1'b0}};
+          else if ((umi_in_ready & umi_in_valid) & (packet_boundary | fifo_write))
+               packet_data_latch    <= {{ODW-IDW{1'b0}}, umi_in_data};
+          else if (umi_in_ready & umi_in_valid)
+               packet_data_latch    <= packet_data_latch | umi_in_data_shifted;
+
+     end
+   else if (SPLIT == 1)
      begin
+        reg  [IDW-1:0]  packet_data_latch;
+
         assign addr_mask[AW-1:0] = {{AW-$clog2(ODW/8){1'b0}},{$clog2(ODW/8){1'b1}}};
-        assign dstaddr_masked[AW-1:0] = fifo_dstaddr[AW-1:0] & addr_mask[AW-1:0];
+        assign dstaddr_masked[AW-1:0] = latch2fifo_dstaddr[AW-1:0] & addr_mask[AW-1:0];
         assign packet_latch_en = (cmd_len_plus_one + (dstaddr_masked[9:0] >> cmd_size)) >
                                  (ODW >> cmd_size >> 3);
 
@@ -158,19 +421,22 @@ module umi_fifo_flex
                                     umi_in_cmd[CW-1:0] & {CW{umi_in_valid}};
 
         // Fifo signal - current command going out
-        assign fifo_dstaddr = packet_latch_valid ? packet_dstaddr_latch : umi_in_dstaddr;
-        assign fifo_srcaddr = packet_latch_valid ? packet_srcaddr_latch : umi_in_srcaddr;
-        assign fifo_data    = packet_latch_valid ? packet_data_latch    : umi_in_data;
+        assign latch2fifo_dstaddr = packet_latch_valid ? packet_dstaddr_latch : umi_in_dstaddr;
+        assign latch2fifo_srcaddr = packet_latch_valid ? packet_srcaddr_latch : umi_in_srcaddr;
+        assign latch2fifo_data    = packet_latch_valid ? packet_data_latch    : umi_in_data;
         // cmd manipulation - at each cycle need to remove the bytes sent out
-        assign fifo_eom     = packet_latch_en    ? 1'b0                 : cmd_eom;
-        assign fifo_len     = packet_latch_en    ?
+        assign latch2fifo_eom     = packet_latch_en    ? 1'b0                 : cmd_eom;
+        assign latch2fifo_len     = packet_latch_en    ?
                               (((ODW[10:3]) - dstaddr_masked[7:0]) >> cmd_size) - 1'b1 :
                               cmd_len[7:0];
+        assign latch2fifo_valid   = umi_in_valid | packet_latch_valid;
+        assign latch2fifo_ready   = ~packet_latch_valid;
+        assign latch2in_ready     = ~packet_latch_valid & umi_out_ready;
 
         // Latched command for next split
-        assign latch_dstaddr = fifo_dstaddr + ((ODW/8) - dstaddr_masked[AW-1:0]);
-        assign latch_srcaddr = fifo_srcaddr + ((ODW/8) - dstaddr_masked[AW-1:0]);
-        assign latch_data    = fifo_data >> (ODW - (dstaddr_masked[9:0] << 3));
+        assign latch_dstaddr = latch2fifo_dstaddr + ((ODW/8) - dstaddr_masked[AW-1:0]);
+        assign latch_srcaddr = latch2fifo_srcaddr + ((ODW/8) - dstaddr_masked[AW-1:0]);
+        assign latch_data    = latch2fifo_data >> (ODW - (dstaddr_masked[9:0] << 3));
         assign latch_len     = cmd_len -
                                ((ODW[10:3] - dstaddr_masked[7:0]) >> cmd_size);
 
@@ -195,6 +461,8 @@ module umi_fifo_flex
      end
    else
      begin // split only based on (LEN-1)*(2^SIZE) > DW
+        reg  [IDW-1:0]  packet_data_latch;
+
         assign packet_latch_en = cmd_len_plus_one > (ODW[11:3] >> cmd_size);
 
         assign packet_cmd[CW-1:0] = packet_latch_valid ?
@@ -202,17 +470,20 @@ module umi_fifo_flex
                                     umi_in_cmd[CW-1:0] & {CW{umi_in_valid}};
 
         // Fifo signal - current command going out
-        assign fifo_dstaddr = packet_latch_valid ? packet_dstaddr_latch : umi_in_dstaddr;
-        assign fifo_srcaddr = packet_latch_valid ? packet_srcaddr_latch : umi_in_srcaddr;
-        assign fifo_data    = packet_latch_valid ? packet_data_latch    : umi_in_data;
+        assign latch2fifo_dstaddr = packet_latch_valid ? packet_dstaddr_latch : umi_in_dstaddr;
+        assign latch2fifo_srcaddr = packet_latch_valid ? packet_srcaddr_latch : umi_in_srcaddr;
+        assign latch2fifo_data    = packet_latch_valid ? packet_data_latch    : umi_in_data;
         // cmd manipulation - at each cycle need to remove the bytes sent out
-        assign fifo_eom     = packet_latch_en    ? 1'b0                            : cmd_eom;
-        assign fifo_len     = packet_latch_en    ? ((ODW[10:3] >> cmd_size) - 1'b1) : cmd_len;
+        assign latch2fifo_eom     = packet_latch_en    ? 1'b0                            : cmd_eom;
+        assign latch2fifo_len     = packet_latch_en    ? ((ODW[10:3] >> cmd_size) - 1'b1) : cmd_len;
+        assign latch2fifo_valid   = umi_in_valid | packet_latch_valid;
+        assign latch2fifo_ready   = ~packet_latch_valid;
+        assign latch2in_ready     = ~packet_latch_valid & umi_out_ready;
 
         // Latched command for next split
-        assign latch_dstaddr = fifo_dstaddr + (ODW/8);
-        assign latch_srcaddr = fifo_srcaddr + (ODW/8);
-        assign latch_data    = fifo_data >> ODW;
+        assign latch_dstaddr = latch2fifo_dstaddr + (ODW/8);
+        assign latch_srcaddr = latch2fifo_srcaddr + (ODW/8);
+        assign latch_data    = latch2fifo_data >> ODW;
         assign latch_len     = cmd_len - (ODW[10:3] >> cmd_size);
 
         // Packet latch
@@ -261,23 +532,23 @@ module umi_fifo_flex
                   .cmd_user_extended    (cmd_user_extended[23:0]));
 
    /* umi_pack AUTO_TEMPLATE(
-    .packet_cmd (fifo_cmd[]),
-    .cmd_len    (fifo_len),
-    .cmd_eom    (fifo_eom),
+    .packet_cmd (latch2fifo_cmd[]),
+    .cmd_len    (latch2fifo_len),
+    .cmd_eom    (latch2fifo_eom),
     );*/
 
    umi_pack #(.CW(CW))
    umi_pack_fifo(/*AUTOINST*/
                  // Outputs
-                 .packet_cmd            (fifo_cmd[CW-1:0]),      // Templated
+                 .packet_cmd            (latch2fifo_cmd[CW-1:0]),      // Templated
                  // Inputs
                  .cmd_opcode            (cmd_opcode[4:0]),
                  .cmd_size              (cmd_size[2:0]),
-                 .cmd_len               (fifo_len),              // Templated
+                 .cmd_len               (latch2fifo_len),              // Templated
                  .cmd_atype             (cmd_atype[7:0]),
                  .cmd_prot              (cmd_prot[1:0]),
                  .cmd_qos               (cmd_qos[3:0]),
-                 .cmd_eom               (fifo_eom),              // Templated
+                 .cmd_eom               (latch2fifo_eom),              // Templated
                  .cmd_eof               (cmd_eof),
                  .cmd_user              (cmd_user[1:0]),
                  .cmd_err               (cmd_err[1:0]),
@@ -289,21 +560,16 @@ module umi_fifo_flex
    assign fifo_read = ~fifo_empty & umi_out_ready;
 
    // Write fifo when high (blocked inside fifo when full)
-   assign fifo_write = ~fifo_full & fifo_ready[1] & (umi_in_valid | packet_latch_valid);
+   assign fifo_write = ~fifo_full & fifo_out_of_reset & latch2fifo_valid;
 
    // FIFO pushback
-   assign fifo_in_ready = ~fifo_full & ~packet_latch_valid;
+   assign fifo_in_ready = ~fifo_full & latch2fifo_ready;
 
-   generate
-      if (ODW>IDW) //TODO - expand transactions
-        assign fifo_din[AW+AW+CW+:ODW] = {{ODW-IDW{1'b0}},fifo_data[IDW-1:0]};
-      else
-        assign fifo_din[AW+AW+CW+:ODW] = fifo_data[ODW-1:0];
-   endgenerate
+   assign fifo_din[AW+AW+CW+:ODW] = latch2fifo_data[ODW-1:0];
 
-   assign fifo_din[AW+CW+:AW]     = fifo_srcaddr[AW-1:0];
-   assign fifo_din[CW+:AW]        = fifo_dstaddr[AW-1:0];
-   assign fifo_din[0+:CW]         = fifo_cmd[CW-1:0];
+   assign fifo_din[AW+CW+:AW]     = latch2fifo_srcaddr[AW-1:0];
+   assign fifo_din[CW+:AW]        = latch2fifo_dstaddr[AW-1:0];
+   assign fifo_din[0+:CW]         = latch2fifo_cmd[CW-1:0];
 
    //#################################
    // Standard Dual Clock FIFO
@@ -320,7 +586,7 @@ module umi_fifo_flex
                .wr_clk       (umi_in_clk),
                .wr_nreset    (umi_in_nreset),
                .wr_din       (fifo_din[ODW+AW+AW+CW-1:0]),
-               .wr_en        (fifo_ready[1] & (umi_in_valid | packet_latch_valid)),
+               .wr_en        (fifo_write),
                .wr_chaosmode (chaosmode),
                .rd_clk       (umi_out_clk),
                .rd_nreset    (umi_out_nreset),
@@ -342,7 +608,7 @@ module umi_fifo_flex
                .clk          (umi_in_clk),
                .nreset       (umi_in_nreset),
                .wr_din       (fifo_din[ODW+AW+AW+CW-1:0]),
-               .wr_en        (fifo_ready[1] & (umi_in_valid | packet_latch_valid)),
+               .wr_en        (fifo_write),
                .chaosmode    (chaosmode),
                .rd_en        (fifo_read),
                .vss          (vss),
@@ -358,11 +624,12 @@ module umi_fifo_flex
      end
    endgenerate
 
-   always @(posedge umi_in_clk or negedge umi_in_nreset)
-     if (~umi_in_nreset)
-       fifo_ready[1:0] <= 2'b00;
-     else
-       fifo_ready[1:0] <= {fifo_ready[0],1'b1};
+   la_drsync la_drsync_i (
+       .clk     (umi_in_clk),
+       .nreset  (umi_in_nreset),
+       .in      (1'b1),
+       .out     (fifo_out_of_reset)
+   );
 
    //#################################
    // FIFO Bypass
@@ -371,21 +638,15 @@ module umi_fifo_flex
    assign fifo_full               = (bypass | ~(|DEPTH)) ? ~umi_out_ready       : fifo_full_raw;
    assign fifo_empty              = (bypass | ~(|DEPTH)) ? 1'b1                 : fifo_empty_raw;
 
-   assign umi_out_cmd[CW-1:0]     = (bypass | ~(|DEPTH)) ? fifo_cmd[CW-1:0]     : fifo_dout[CW-1:0];
-   assign umi_out_dstaddr[AW-1:0] = (bypass | ~(|DEPTH)) ? fifo_dstaddr[AW-1:0] : fifo_dout[CW+:AW] & 64'hFFFF_FFFF_FFFF_FFFF;
-   assign umi_out_srcaddr[AW-1:0] = (bypass | ~(|DEPTH)) ? fifo_srcaddr[AW-1:0] : fifo_dout[CW+AW+:AW];
-
-   generate
-      if (ODW>IDW) //TODO - expand transactions
-        assign umi_out_data[ODW-1:0]   = (bypass | ~(|DEPTH)) ? {{ODW-IDW{1'b0}},fifo_data[IDW-1:0]} : fifo_dout[CW+AW+AW+:ODW];
-      else
-        assign umi_out_data[ODW-1:0]   = (bypass | ~(|DEPTH)) ? fifo_data[ODW-1:0] : fifo_dout[CW+AW+AW+:ODW];
-   endgenerate
+   assign umi_out_cmd[CW-1:0]     = (bypass | ~(|DEPTH)) ? latch2fifo_cmd[CW-1:0]     : fifo_dout[CW-1:0];
+   assign umi_out_dstaddr[AW-1:0] = (bypass | ~(|DEPTH)) ? latch2fifo_dstaddr[AW-1:0] : fifo_dout[CW+:AW] & 64'hFFFF_FFFF_FFFF_FFFF;
+   assign umi_out_srcaddr[AW-1:0] = (bypass | ~(|DEPTH)) ? latch2fifo_srcaddr[AW-1:0] : fifo_dout[CW+AW+:AW];
+   assign umi_out_data[ODW-1:0]   = (bypass | ~(|DEPTH)) ? latch2fifo_data[ODW-1:0] : fifo_dout[CW+AW+AW+:ODW];
 
-   assign umi_out_valid           = ~fifo_ready[1] ? 1'b0 :
-                                    (bypass | ~(|DEPTH)) ? (umi_in_valid | packet_latch_valid) : ~fifo_empty;
-   assign umi_in_ready            = ~fifo_ready[1] ? 1'b0 :
-                                    (bypass | ~(|DEPTH)) ? ~packet_latch_valid & umi_out_ready : fifo_in_ready;
+   assign umi_out_valid           = ~fifo_out_of_reset ? 1'b0 :
+                                    (bypass | ~(|DEPTH)) ? latch2fifo_valid : ~fifo_empty;
+   assign umi_in_ready            = ~fifo_out_of_reset ? 1'b0 :
+                                    (bypass | ~(|DEPTH)) ? latch2in_ready : fifo_in_ready;
 
    // debug signals
    assign umi_out_beat = umi_out_valid & umi_out_ready;
diff --git a/utils/rtl/umi2tl_np.v b/utils/rtl/umi2tl_np.v
index 029f8f3..7fe8c61 100644
--- a/utils/rtl/umi2tl_np.v
+++ b/utils/rtl/umi2tl_np.v
@@ -170,7 +170,7 @@ module umi2tl_np #(
     );
 
     // Calculate byte shift needed
-    wire [$clog2(ODW/8):0] req_bytes = (1 << fifoflex_out_req_cmd_size)*(fifoflex_out_req_cmd_len + 1);
+    wire [7:0] req_bytes = (1 << fifoflex_out_req_cmd_size)*(fifoflex_out_req_cmd_len + 1);
 
     reg [2:0]   masked_shift;
     reg [2:0]   masked_tl_a_size;
diff --git a/utils/rtl/umi_packet_merge_greedy.v b/utils/rtl/umi_packet_merge_greedy.v
index cf42932..0282a41 100644
--- a/utils/rtl/umi_packet_merge_greedy.v
+++ b/utils/rtl/umi_packet_merge_greedy.v
@@ -148,7 +148,7 @@ module umi_packet_merge_greedy #(
     wire                    umi_in_ready_r;
     wire                    umi_in_cmd_commit_r;
 
-    reg [$clog2(ODW/8):0]   byte_counter;
+    reg [7:0]               byte_counter;
     localparam [$clog2(ODW/8):0]    ODW_BYTES = ODW[3+$clog2(ODW/8):3];
     localparam                      ADDR_PAD_BYTES = AW - 1 - $clog2(ODW/8);
 
@@ -236,9 +236,9 @@ module umi_packet_merge_greedy #(
     wire                    umi_in_opcode_check;
     wire                    umi_in_field_match;
     wire                    umi_in_mergeable;
-    wire [$clog2(IDW/8):0]  umi_in_bytes;
+    wire [7:0]              umi_in_bytes;
     reg                     umi_in_mergeable_r;
-    reg  [$clog2(IDW/8):0]  umi_in_bytes_r;
+    reg  [7:0]              umi_in_bytes_r;
 
     reg [AW-1:0]            umi_in_dstaddr_nx;
     reg [AW-1:0]            umi_in_srcaddr_nx;


Test patch:
diff --git a/umi/testbench/test_fifo_flex.py b/umi/testbench/test_fifo_flex.py
index 0040277..2d80575 100755
--- a/umi/testbench/test_fifo_flex.py
+++ b/umi/testbench/test_fifo_flex.py
@@ -65,16 +65,16 @@ def main(vldmode="2", rdymode="2", host2dut="host2dut_0.q", dut2host="dut2host_0
 
     print("### Statring test ###")
 
-    for count in range (100):
+    for count in range (1000):
         # length should not cross the DW boundary - umi_mem_agent limitation
-        length = np.random.randint(0,15)
+        length = np.random.randint(0,255)
         dst_addr = 32*random.randrange(2**(10-5)-1) # sb limitation - should align to bus width
         src_addr = 32*random.randrange(2**(10-5)-1)
         data8 = np.random.randint(0,255,size=length,dtype=np.uint8)
-        print(f"umi writing {length+1} bytes to addr 0x{dst_addr:08x}")
-        host.write(dst_addr, data8, srcaddr=src_addr)
-        print(f"umi read from addr 0x{dst_addr:08x}")
-        val8 = host.read(dst_addr, length, np.uint8, srcaddr=src_addr)
+        print(f"[{count}] umi writing {length} bytes to addr 0x{dst_addr:08x}")
+        host.write(dst_addr, data8, srcaddr=src_addr, max_bytes=16)
+        print(f"[{count}] umi read from addr 0x{dst_addr:08x}")
+        val8 = host.read(dst_addr, length, np.uint8, srcaddr=src_addr, max_bytes=16)
         if ~((val8 == data8).all()):
             print(f"ERROR umi read from addr 0x{dst_addr:08x}")
             print(f"Expected:")
diff --git a/umi/testbench/testbench_fifo_flex.sv b/umi/testbench/testbench_fifo_flex.sv
index 16ee2df..dcd9b95 100644
--- a/umi/testbench/testbench_fifo_flex.sv
+++ b/umi/testbench/testbench_fifo_flex.sv
@@ -51,7 +51,7 @@ module testbench (
    wire [AW-1:0]        umi_resp_in_srcaddr;
    wire                 umi_resp_in_valid;
    // End of automatics
-   reg                  nreset;
+   wire                 nreset;
 
    wire [CTRLW-1:0]     sram_ctrl = 8'b0;
 
@@ -86,10 +86,10 @@ module testbench (
                   );
 
    umi_tx_sim #(.READY_MODE_DEFAULT(2),
-                .DW(ODW)
+                .DW(IDW)
                 )
    host_umi_tx_i (.clk(clk),
-                  .data(umi_resp_out_data[ODW-1:0]),
+                  .data(umi_resp_out_data[IDW-1:0]),
                   .srcaddr(umi_resp_out_srcaddr[AW-1:0]),
                   .dstaddr(umi_resp_out_dstaddr[AW-1:0]),
                   .cmd(umi_resp_out_cmd[CW-1:0]),
@@ -238,14 +238,17 @@ module testbench (
 
    // VCD
 
+   reg [15:0] nreset_r;
+   assign nreset = ~nreset_r[15];
+
    initial
      begin
-        nreset   = 1'b0;
+        nreset_r = 16'hFFFF;
      end // initial begin
 
    always @(negedge clk)
      begin
-        nreset <= nreset | 1'b1;
+        nreset_r <= nreset_r << 1;
      end
 
    // control block
@@ -260,7 +263,7 @@ module testbench (
 
    // auto-stop
 
-   auto_stop_sim #(.CYCLES(50000)) auto_stop_sim_i (.clk(clk));
+   auto_stop_sim #(.CYCLES(500000)) auto_stop_sim_i (.clk(clk));
 
 endmodule
 // Local Variables:
diff --git a/utils/testbench/config.vlt b/utils/testbench/config.vlt
index 2aa67ae..bdb19a7 100644
--- a/utils/testbench/config.vlt
+++ b/utils/testbench/config.vlt
@@ -18,5 +18,5 @@ lint_off -rule BLKSEQ -file "*switchboard/switchboard/verilog/*"
 lint_off -rule GENUNNAMED
 lint_off -rule TIMESCALEMOD
 // To be fixed:
-lint_off -rule SYNCASYNCNET
-lint_off -rule WIDTHTRUNC
+//lint_off -rule SYNCASYNCNET
+//lint_off -rule WIDTHTRUNC
diff --git a/utils/testbench/testbench_umi2tl_np.v b/utils/testbench/testbench_umi2tl_np.v
index 8fb1fd6..106f3d1 100644
--- a/utils/testbench/testbench_umi2tl_np.v
+++ b/utils/testbench/testbench_umi2tl_np.v
@@ -50,7 +50,7 @@ module testbench #(
 
     // Reset initialization
     always @(posedge clk) begin
-        nreset_vec <= {nreset_vec[15:0], 1'b1};
+        nreset_vec <= {nreset_vec[14:0], 1'b1};
     end
 
     assign nreset = nreset_vec[14];
diff --git a/utils/testbench/testbench_umi_packet_merge_greedy.v b/utils/testbench/testbench_umi_packet_merge_greedy.v
index 8dc2973..1c63e34 100644
--- a/utils/testbench/testbench_umi_packet_merge_greedy.v
+++ b/utils/testbench/testbench_umi_packet_merge_greedy.v
@@ -56,7 +56,7 @@ module testbench #(
     wire [ODW-1:0]  umi_dut2check_data;
     reg             umi_dut2check_ready;
 
-    always @(posedge clk) begin
+    always @(posedge clk or negedge nreset) begin
         if(~nreset)
             umi_dut2check_ready <= 1'b0;
         else