[CDC/PRIM] Updated prim_fifo_sync and prim_fifo_async to avoid CDC in rdata
- rdata_o is qualified with rvalid_o to avoid being used when rvalid_o is 0
- This CDC error is found in #13834
Signed-off-by: Joshua Park <jeoong@google.com>
Reverted back prim_fifo_sync to reduce area increase
Added OutputZeroIfInvalid to support read domain qualification
diff --git a/hw/ip/prim/rtl/prim_fifo_async.sv b/hw/ip/prim/rtl/prim_fifo_async.sv
index e2f2d07..0edebc7 100644
--- a/hw/ip/prim/rtl/prim_fifo_async.sv
+++ b/hw/ip/prim/rtl/prim_fifo_async.sv
@@ -10,6 +10,7 @@
parameter int unsigned Width = 16,
parameter int unsigned Depth = 4,
parameter bit OutputZeroIfEmpty = 1'b0, // if == 1 always output 0 when FIFO is empty
+ parameter bit OutputZeroIfInvalid = 1'b0, // if == 1 always output 0 when rvalid_o is low
localparam int unsigned DepthW = $clog2(Depth+1) // derived parameter representing [0..Depth]
) (
// write port
@@ -197,10 +198,21 @@
end
+ // rdata_o is qualified with rvalid_o to avoid CDC error
if (OutputZeroIfEmpty == 1'b1) begin : gen_output_zero
- assign rdata_o = empty_rclk ? '0 : rdata_int;
+ if (OutputZeroIfInvalid == 1'b1) begin : gen_invalid_zero
+ assign rdata_o = empty_rclk ? '0 : (rvalid_o ? rdata_int : '0);
+ end
+ else begin : gen_invalid_non_zero
+ assign rdata_o = empty_rclk ? '0 : rdata_int;
+ end
end else begin : gen_no_output_zero
- assign rdata_o = rdata_int;
+ if (OutputZeroIfInvalid == 1'b1) begin : gen_invalid_zero
+ assign rdata_o = rvalid_o ? rdata_int : '0;
+ end
+ else begin : gen_invalid_non_zero
+ assign rdata_o = rdata_int;
+ end
end
//////////////////////////////////////
diff --git a/hw/ip/tlul/rtl/tlul_fifo_async.sv b/hw/ip/tlul/rtl/tlul_fifo_async.sv
index fd0958c..d40d414 100644
--- a/hw/ip/tlul/rtl/tlul_fifo_async.sv
+++ b/hw/ip/tlul/rtl/tlul_fifo_async.sv
@@ -25,7 +25,11 @@
// Put everything on the request side into one FIFO
localparam int unsigned REQFIFO_WIDTH = $bits(tlul_pkg::tl_h2d_t)-2;
- prim_fifo_async #(.Width(REQFIFO_WIDTH), .Depth(ReqDepth)) reqfifo (
+ prim_fifo_async #(
+ .Width(REQFIFO_WIDTH),
+ .Depth(ReqDepth),
+ .OutputZeroIfInvalid(1)
+ ) reqfifo (
.clk_wr_i (clk_h_i),
.rst_wr_ni (rst_h_ni),
.clk_rd_i (clk_d_i),
@@ -58,7 +62,11 @@
localparam int unsigned RSPFIFO_WIDTH = $bits(tlul_pkg::tl_d2h_t) -2;
- prim_fifo_async #(.Width(RSPFIFO_WIDTH), .Depth(RspDepth)) rspfifo (
+ prim_fifo_async #(
+ .Width(RSPFIFO_WIDTH),
+ .Depth(RspDepth),
+ .OutputZeroIfInvalid(1)
+ ) rspfifo (
.clk_wr_i (clk_d_i),
.rst_wr_ni (rst_d_ni),
.clk_rd_i (clk_h_i),