diff --git a/library/util_axis_fifo/util_axis_fifo.v b/library/util_axis_fifo/util_axis_fifo.v index 2dc54009d..812adb0cf 100644 --- a/library/util_axis_fifo/util_axis_fifo.v +++ b/library/util_axis_fifo/util_axis_fifo.v @@ -45,6 +45,7 @@ module util_axis_fifo #( input m_axis_ready, output m_axis_valid, output [DATA_WIDTH-1:0] m_axis_data, + output m_axis_tlast, output [ADDRESS_WIDTH-1:0] m_axis_level, output m_axis_empty, @@ -53,6 +54,7 @@ module util_axis_fifo #( output s_axis_ready, input s_axis_valid, input [DATA_WIDTH-1:0] s_axis_data, + input s_axis_tlast, output [ADDRESS_WIDTH-1:0] s_axis_room, output s_axis_full ); @@ -62,6 +64,7 @@ generate if (ADDRESS_WIDTH == 0) begin : zerodeep /* it's not a real FIFO, just if (ASYNC_CLK) begin (* KEEP = "yes" *) reg [DATA_WIDTH-1:0] cdc_sync_fifo_ram; + reg axis_tlast_d; reg s_axis_waddr = 1'b0; reg m_axis_raddr = 1'b0; @@ -97,6 +100,7 @@ generate if (ADDRESS_WIDTH == 0) begin : zerodeep /* it's not a real FIFO, just always @(posedge s_axis_aclk) begin if (s_axis_ready == 1'b1 && s_axis_valid == 1'b1) cdc_sync_fifo_ram <= s_axis_data; + axis_tlast_d <= s_axis_tlast; end always @(posedge s_axis_aclk) begin @@ -117,6 +121,7 @@ generate if (ADDRESS_WIDTH == 0) begin : zerodeep /* it's not a real FIFO, just end assign m_axis_data = cdc_sync_fifo_ram; + assign m_axis_tlast = axis_tlast_d; end else begin /* !ASYNC_CLK */ @@ -124,19 +129,23 @@ generate if (ADDRESS_WIDTH == 0) begin : zerodeep /* it's not a real FIFO, just // aspect ratio reg [DATA_WIDTH-1:0] axis_data_d; reg axis_valid_d; + reg axis_tlast_d; always @(posedge s_axis_aclk) begin if (!s_axis_aresetn) begin axis_data_d <= {DATA_WIDTH{1'b0}}; axis_valid_d <= 1'b0; + axis_tlast_d <= 1'b0; end else if (s_axis_ready) begin axis_data_d <= s_axis_data; axis_valid_d <= s_axis_valid; + axis_tlast_d <= s_axis_tlast; end end assign m_axis_data = axis_data_d; assign m_axis_valid = axis_valid_d; + assign m_axis_tlast = axis_tlast_d; assign s_axis_ready = m_axis_ready | ~m_axis_valid; assign m_axis_empty = 1'b0; assign m_axis_level = 1'b0; @@ -199,17 +208,17 @@ end else begin : fifo /* ADDRESS_WIDTH != 0 - this is a real FIFO implementation // regardless of the requested size to make sure we threat the // clock crossing correctly ad_mem #( - .DATA_WIDTH (DATA_WIDTH), + .DATA_WIDTH (DATA_WIDTH+1), .ADDRESS_WIDTH (ADDRESS_WIDTH)) i_mem ( .clka(s_axis_aclk), .wea(s_mem_write), .addra(s_axis_waddr), - .dina(s_axis_data), + .dina({s_axis_data, s_axis_tlast}), .clkb(m_axis_aclk), .reb(m_mem_read), .addrb(m_axis_raddr), - .doutb(m_axis_data) + .doutb({m_axis_data, m_axis_tlast}) ); assign _m_axis_ready = ~valid || m_axis_ready; @@ -217,18 +226,18 @@ end else begin : fifo /* ADDRESS_WIDTH != 0 - this is a real FIFO implementation end else begin : sync_clocks /* Synchronous WRITE/READ clocks */ - reg [DATA_WIDTH-1:0] ram[0:2**ADDRESS_WIDTH-1]; + reg [DATA_WIDTH:0] ram[0:2**ADDRESS_WIDTH-1]; // When the clocks are synchronous use behavioral modeling for the SDP RAM // Let the synthesizer decide what to infer (distributed or block RAM) always @(posedge s_axis_aclk) begin if (s_mem_write) - ram[s_axis_waddr] <= s_axis_data; + ram[s_axis_waddr] <= {s_axis_data, s_axis_tlast}; end if (M_AXIS_REGISTERED == 1) begin - reg [DATA_WIDTH-1:0] data; + reg [DATA_WIDTH:0] data; always @(posedge m_axis_aclk) begin if (m_mem_read) @@ -236,14 +245,15 @@ end else begin : fifo /* ADDRESS_WIDTH != 0 - this is a real FIFO implementation end assign _m_axis_ready = ~valid || m_axis_ready; - assign m_axis_data = data; + assign m_axis_data = data[DATA_WIDTH:1]; + assign m_axis_tlast = data[0]; assign m_axis_valid = valid; end else begin assign _m_axis_ready = m_axis_ready; assign m_axis_valid = _m_axis_valid; - assign m_axis_data = ram[m_axis_raddr]; + assign {m_axis_data, m_axis_tlast} = ram[m_axis_raddr]; end end