Skip to content

Commit e49132e

Browse files
committed
library/util_axis_fifo_asym: fix tlast behavior when tkeep=0
Fix tvalid low when tlast is present. Before this commit, util_axis_fifo would suppress all transfers with tkeep=0, even if tlast was asserted. This commit makes it so transfers with tlast asserted are preserved. The AXI-Streaming spec allows us to suppress transfers for which all tkeep bits are 0 (all bytes are null bytes), but only in the case when tlast=0 as well. Transfers where tlast is asserted can't be suppressed even when all bytes are null. Signed-off-by: Laez Barbosa <[email protected]>
1 parent 0e2e11c commit e49132e

File tree

1 file changed

+23
-3
lines changed

1 file changed

+23
-3
lines changed

library/util_axis_fifo_asym/util_axis_fifo_asym.v

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,18 @@ module util_axis_fifo_asym #(
153153

154154
if (TKEEP_EN) begin
155155

156-
assign s_axis_tlast_int_s[i] = (i==RATIO-1) ? ((|s_axis_tkeep[M_DATA_WIDTH/8*i+:M_DATA_WIDTH/8]) ? s_axis_tlast : 1'b0) :
157-
(((|s_axis_tkeep[M_DATA_WIDTH/8*i+:M_DATA_WIDTH/8]) & (~(|s_axis_tkeep[M_DATA_WIDTH/8*(i+1)+:M_DATA_WIDTH/8]))) ? s_axis_tlast : 1'b0);
156+
// tlast is asserted for the atomic fifo instances on the following conditions:
157+
// - for the most significant instance, tlast is the input tlast if any of the tkeep bits for the instance is asserted (so we are not suppressing this transfer)
158+
// - for the least significat instance, tlast is the input tlast if no tkeep bits are asserted for any instance (transfer is all null bytes)
159+
// - for the other instances, we store the input tlast if all the following instances have tkeep=0 for all bits and no less significant instance has stored it
160+
// thus, the tlast is stored on the most significant instance that has non-null bytes (meaning not all tkeep bits are 0), if there are any.
161+
if (i==RATIO-1) begin
162+
assign s_axis_tlast_int_s[i] = (|s_axis_tkeep[M_DATA_WIDTH/8*i+:M_DATA_WIDTH/8]) ? s_axis_tlast : 1'b0;
163+
end else if (i==0) begin
164+
assign s_axis_tlast_int_s[i] = (~|s_axis_tkeep) ? s_axis_tlast : 1'b0;
165+
end else begin
166+
assign s_axis_tlast_int_s[i] = (~(|s_axis_tkeep[(S_DATA_WIDTH/8)-1:(M_DATA_WIDTH/8)*(i+1)]) && ~|s_axis_tlast_int_s[i-1:0]) ? s_axis_tlast : 1'b0;
167+
end
158168

159169
end else begin
160170

@@ -226,7 +236,17 @@ module util_axis_fifo_asym #(
226236

227237
// VALID/EMPTY/ALMOST_EMPTY is driven by the current atomic instance
228238
assign m_axis_valid_int = m_axis_valid_int_s >> m_axis_counter;
229-
assign m_axis_valid = m_axis_valid_int & (|m_axis_tkeep);
239+
240+
// When TLAST_EN=1, we still have to assert m_axis_valid when tlast is
241+
// high even if all bytes are null due to tkeep. AXI-Streaming only allows
242+
// us to suppress transfers with all tkeep bits deasserted if tlast is
243+
// also deasserted.
244+
if (TLAST_EN) begin
245+
assign m_axis_valid = m_axis_valid_int & ((|m_axis_tkeep) || m_axis_tlast);
246+
end else begin
247+
assign m_axis_valid = m_axis_valid_int & (|m_axis_tkeep);
248+
end
249+
230250
assign m_axis_tlast = m_axis_tlast_int_s >> m_axis_counter;
231251

232252
// the FIFO has the same level as the last atomic instance

0 commit comments

Comments
 (0)