[prim/fifo_async] Disallow non-power-of-two depths

If the depth is not a power of two, the transitions will not be
gray-coded when the pointers wrap.

Signed-off-by: Tom Roberts <tomroberts@lowrisc.org>
diff --git a/hw/ip/prim/rtl/prim_fifo_async.sv b/hw/ip/prim/rtl/prim_fifo_async.sv
index 3a7e8c1..558ab57 100644
--- a/hw/ip/prim/rtl/prim_fifo_async.sv
+++ b/hw/ip/prim/rtl/prim_fifo_async.sv
@@ -28,10 +28,10 @@
   output [DepthW-1:0]    rdepth_o
 );
 
-  `ASSERT_INIT(paramCheckDepth,  Depth >= 3)
+  // Depth must be a power of 2 for the gray code pointers to work
+  `ASSERT_INIT(ParamCheckDepth_A, (Depth > 2) && (Depth == 2**$clog2(Depth)))
 
   localparam int unsigned PTRV_W = $clog2(Depth);
-  localparam logic [PTRV_W-1:0] DepthMinus1 = PTRV_W'(Depth - 1);
   localparam int unsigned PTR_WIDTH = PTRV_W+1;
 
   logic [PTR_WIDTH-1:0]    fifo_wptr, fifo_rptr;
@@ -58,23 +58,15 @@
     if (!rst_wr_ni) begin
       fifo_wptr <= {(PTR_WIDTH){1'b0}};
     end else if (fifo_incr_wptr) begin
-      if (fifo_wptr[PTR_WIDTH-2:0] == DepthMinus1) begin
-        fifo_wptr <= {~fifo_wptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}};
-      end else begin
-        fifo_wptr <= fifo_wptr + {{(PTR_WIDTH-1){1'b0}},1'b1};
+      fifo_wptr <= fifo_wptr + PTR_WIDTH'(1);
     end
-  end
 
   // gray-coded version
   always_ff @(posedge clk_wr_i or negedge rst_wr_ni)
     if (!rst_wr_ni) begin
       fifo_wptr_gray <= {(PTR_WIDTH){1'b0}};
     end else if (fifo_incr_wptr) begin
-      if (fifo_wptr[PTR_WIDTH-2:0] == DepthMinus1) begin
-        fifo_wptr_gray <= dec2gray({~fifo_wptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}});
-      end else begin
-        fifo_wptr_gray <= dec2gray(fifo_wptr + {{(PTR_WIDTH-1){1'b0}},1'b1});
-      end
+      fifo_wptr_gray <= dec2gray(fifo_wptr + PTR_WIDTH'(1));
     end
 
   prim_flop_2sync #(.Width(PTR_WIDTH)) sync_wptr (
@@ -93,23 +85,15 @@
     if (!rst_rd_ni) begin
       fifo_rptr <= {(PTR_WIDTH){1'b0}};
     end else if (fifo_incr_rptr) begin
-      if (fifo_rptr[PTR_WIDTH-2:0] == DepthMinus1) begin
-        fifo_rptr <= {~fifo_rptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}};
-      end else begin
-        fifo_rptr <= fifo_rptr + {{(PTR_WIDTH-1){1'b0}},1'b1};
+      fifo_rptr <= fifo_rptr + PTR_WIDTH'(1);
     end
-  end
 
   // gray-coded version
   always_ff @(posedge clk_rd_i or negedge rst_rd_ni)
     if (!rst_rd_ni) begin
       fifo_rptr_gray <= {(PTR_WIDTH){1'b0}};
     end else if (fifo_incr_rptr) begin
-      if (fifo_rptr[PTR_WIDTH-2:0] == DepthMinus1) begin
-        fifo_rptr_gray <= dec2gray({~fifo_rptr[PTR_WIDTH-1],{(PTR_WIDTH-1){1'b0}}});
-      end else begin
-        fifo_rptr_gray <= dec2gray(fifo_rptr + {{(PTR_WIDTH-1){1'b0}},1'b1});
-      end
+      fifo_rptr_gray <= dec2gray(fifo_rptr + PTR_WIDTH'(1));
     end
 
   prim_flop_2sync #(.Width(PTR_WIDTH)) sync_rptr (
diff --git a/hw/top_earlgrey/ip/xbar_main/rtl/autogen/xbar_main.sv b/hw/top_earlgrey/ip/xbar_main/rtl/autogen/xbar_main.sv
index 0f79510..5b5ec0b 100644
--- a/hw/top_earlgrey/ip/xbar_main/rtl/autogen/xbar_main.sv
+++ b/hw/top_earlgrey/ip/xbar_main/rtl/autogen/xbar_main.sv
@@ -746,8 +746,8 @@
     .dev_select_i (dev_sel_s1n_27)
   );
   tlul_fifo_async #(
-    .ReqDepth        (3),// At least 3 to make async work
-    .RspDepth        (3) // At least 3 to make async work
+    .ReqDepth        (4),// At least 4 to make async work
+    .RspDepth        (4) // At least 4 to make async work
   ) u_asf_28 (
     .clk_h_i      (clk_main_i),
     .rst_h_ni     (rst_main_ni),
diff --git a/util/tlgen/xbar.rtl.sv.tpl b/util/tlgen/xbar.rtl.sv.tpl
index 5dce4df..cf1e2be 100644
--- a/util/tlgen/xbar.rtl.sv.tpl
+++ b/util/tlgen/xbar.rtl.sv.tpl
@@ -198,8 +198,8 @@
 % for block in xbar.nodes:
   % if block.node_type.name   == "ASYNC_FIFO":
   tlul_fifo_async #(
-    .ReqDepth        (3),// At least 3 to make async work
-    .RspDepth        (3) // At least 3 to make async work
+    .ReqDepth        (4),// At least 4 to make async work
+    .RspDepth        (4) // At least 4 to make async work
   ) u_${block.name} (
     .clk_h_i      (${block.clocks[0]}),
     .rst_h_ni     (${block.resets[0]}),