Skip to content

Commit c68efc0

Browse files
committed
merged changes in axis
2 parents 82fe5a6 + ccc1532 commit c68efc0

14 files changed

+2548
-32
lines changed

lib/axis/rtl/axis_async_fifo.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ always @* begin
302302
wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1);
303303
if (s_axis_tlast) begin
304304
// end of frame
305-
if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin
305+
if (DROP_BAD_FRAME && USER_BAD_FRAME_MASK & ~(s_axis_tuser ^ USER_BAD_FRAME_VALUE)) begin
306306
// bad packet, reset write pointer
307307
wr_ptr_cur_next = wr_ptr_reg;
308308
wr_ptr_cur_gray_next = wr_ptr_cur_next ^ (wr_ptr_cur_next >> 1);
Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
/*
2+
3+
Copyright (c) 2019 Alex Forencich
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.
22+
23+
*/
24+
25+
// Language: Verilog 2001
26+
27+
`timescale 1ns / 1ps
28+
29+
/*
30+
* AXI4-Stream asynchronous FIFO with width converter
31+
*/
32+
module axis_async_fifo_adapter #
33+
(
34+
parameter ADDR_WIDTH = 12,
35+
parameter S_DATA_WIDTH = 8,
36+
parameter S_KEEP_ENABLE = (S_DATA_WIDTH>8),
37+
parameter S_KEEP_WIDTH = (S_DATA_WIDTH/8),
38+
parameter M_DATA_WIDTH = 8,
39+
parameter M_KEEP_ENABLE = (M_DATA_WIDTH>8),
40+
parameter M_KEEP_WIDTH = (M_DATA_WIDTH/8),
41+
parameter ID_ENABLE = 0,
42+
parameter ID_WIDTH = 8,
43+
parameter DEST_ENABLE = 0,
44+
parameter DEST_WIDTH = 8,
45+
parameter USER_ENABLE = 1,
46+
parameter USER_WIDTH = 1,
47+
parameter FRAME_FIFO = 0,
48+
parameter USER_BAD_FRAME_VALUE = 1'b1,
49+
parameter USER_BAD_FRAME_MASK = 1'b1,
50+
parameter DROP_BAD_FRAME = 0,
51+
parameter DROP_WHEN_FULL = 0
52+
)
53+
(
54+
/*
55+
* AXI input
56+
*/
57+
input wire s_clk,
58+
input wire s_rst,
59+
input wire [S_DATA_WIDTH-1:0] s_axis_tdata,
60+
input wire [S_KEEP_WIDTH-1:0] s_axis_tkeep,
61+
input wire s_axis_tvalid,
62+
output wire s_axis_tready,
63+
input wire s_axis_tlast,
64+
input wire [ID_WIDTH-1:0] s_axis_tid,
65+
input wire [DEST_WIDTH-1:0] s_axis_tdest,
66+
input wire [USER_WIDTH-1:0] s_axis_tuser,
67+
68+
/*
69+
* AXI output
70+
*/
71+
input wire m_clk,
72+
input wire m_rst,
73+
output wire [M_DATA_WIDTH-1:0] m_axis_tdata,
74+
output wire [M_KEEP_WIDTH-1:0] m_axis_tkeep,
75+
output wire m_axis_tvalid,
76+
input wire m_axis_tready,
77+
output wire m_axis_tlast,
78+
output wire [ID_WIDTH-1:0] m_axis_tid,
79+
output wire [DEST_WIDTH-1:0] m_axis_tdest,
80+
output wire [USER_WIDTH-1:0] m_axis_tuser,
81+
82+
/*
83+
* Status
84+
*/
85+
output wire s_status_overflow,
86+
output wire s_status_bad_frame,
87+
output wire s_status_good_frame,
88+
output wire m_status_overflow,
89+
output wire m_status_bad_frame,
90+
output wire m_status_good_frame
91+
);
92+
93+
// force keep width to 1 when disabled
94+
parameter S_KEEP_WIDTH_INT = S_KEEP_ENABLE ? S_KEEP_WIDTH : 1;
95+
parameter M_KEEP_WIDTH_INT = M_KEEP_ENABLE ? M_KEEP_WIDTH : 1;
96+
97+
// bus word sizes (must be identical)
98+
parameter S_DATA_WORD_SIZE = S_DATA_WIDTH / S_KEEP_WIDTH_INT;
99+
parameter M_DATA_WORD_SIZE = M_DATA_WIDTH / M_KEEP_WIDTH_INT;
100+
// output bus is wider
101+
parameter EXPAND_BUS = M_KEEP_WIDTH_INT > S_KEEP_WIDTH_INT;
102+
// total data and keep widths
103+
parameter DATA_WIDTH = EXPAND_BUS ? M_DATA_WIDTH : S_DATA_WIDTH;
104+
parameter KEEP_WIDTH = EXPAND_BUS ? M_KEEP_WIDTH_INT : S_KEEP_WIDTH_INT;
105+
106+
// bus width assertions
107+
initial begin
108+
if (S_DATA_WORD_SIZE * S_KEEP_WIDTH_INT != S_DATA_WIDTH) begin
109+
$error("Error: input data width not evenly divisble");
110+
$finish;
111+
end
112+
113+
if (M_DATA_WORD_SIZE * M_KEEP_WIDTH_INT != M_DATA_WIDTH) begin
114+
$error("Error: output data width not evenly divisble");
115+
$finish;
116+
end
117+
118+
if (S_DATA_WORD_SIZE != M_DATA_WORD_SIZE) begin
119+
$error("Error: word size mismatch");
120+
$finish;
121+
end
122+
end
123+
124+
wire [DATA_WIDTH-1:0] pre_fifo_axis_tdata;
125+
wire [KEEP_WIDTH-1:0] pre_fifo_axis_tkeep;
126+
wire pre_fifo_axis_tvalid;
127+
wire pre_fifo_axis_tready;
128+
wire pre_fifo_axis_tlast;
129+
wire [ID_WIDTH-1:0] pre_fifo_axis_tid;
130+
wire [DEST_WIDTH-1:0] pre_fifo_axis_tdest;
131+
wire [USER_WIDTH-1:0] pre_fifo_axis_tuser;
132+
133+
wire [DATA_WIDTH-1:0] post_fifo_axis_tdata;
134+
wire [KEEP_WIDTH-1:0] post_fifo_axis_tkeep;
135+
wire post_fifo_axis_tvalid;
136+
wire post_fifo_axis_tready;
137+
wire post_fifo_axis_tlast;
138+
wire [ID_WIDTH-1:0] post_fifo_axis_tid;
139+
wire [DEST_WIDTH-1:0] post_fifo_axis_tdest;
140+
wire [USER_WIDTH-1:0] post_fifo_axis_tuser;
141+
142+
generate
143+
144+
if (M_KEEP_WIDTH == S_KEEP_WIDTH) begin
145+
146+
// same width, no adapter needed
147+
148+
assign pre_fifo_axis_tdata = s_axis_tdata;
149+
assign pre_fifo_axis_tkeep = s_axis_tkeep;
150+
assign pre_fifo_axis_tvalid = s_axis_tvalid;
151+
assign s_axis_tready = pre_fifo_axis_tready;
152+
assign pre_fifo_axis_tlast = s_axis_tlast;
153+
assign pre_fifo_axis_tid = s_axis_tid;
154+
assign pre_fifo_axis_tdest = s_axis_tdest;
155+
assign pre_fifo_axis_tuser = s_axis_tuser;
156+
157+
assign m_axis_tdata = post_fifo_axis_tdata;
158+
assign m_axis_tkeep = post_fifo_axis_tkeep;
159+
assign m_axis_tvalid = post_fifo_axis_tvalid;
160+
assign post_fifo_axis_tready = m_axis_tready;
161+
assign m_axis_tlast = post_fifo_axis_tlast;
162+
assign m_axis_tid = post_fifo_axis_tid;
163+
assign m_axis_tdest = post_fifo_axis_tdest;
164+
assign m_axis_tuser = post_fifo_axis_tuser;
165+
166+
167+
end else if (EXPAND_BUS) begin
168+
169+
// output wider, adapt width before FIFO
170+
171+
axis_adapter #(
172+
.S_DATA_WIDTH(S_DATA_WIDTH),
173+
.S_KEEP_ENABLE(S_KEEP_ENABLE),
174+
.S_KEEP_WIDTH(S_KEEP_WIDTH),
175+
.M_DATA_WIDTH(M_DATA_WIDTH),
176+
.M_KEEP_ENABLE(M_KEEP_ENABLE),
177+
.M_KEEP_WIDTH(M_KEEP_WIDTH),
178+
.ID_ENABLE(ID_ENABLE),
179+
.ID_WIDTH(ID_WIDTH),
180+
.DEST_ENABLE(DEST_ENABLE),
181+
.DEST_WIDTH(DEST_WIDTH),
182+
.USER_ENABLE(USER_ENABLE),
183+
.USER_WIDTH(USER_WIDTH)
184+
)
185+
adapter_inst (
186+
.clk(s_clk),
187+
.rst(s_rst),
188+
// AXI input
189+
.s_axis_tdata(s_axis_tdata),
190+
.s_axis_tkeep(s_axis_tkeep),
191+
.s_axis_tvalid(s_axis_tvalid),
192+
.s_axis_tready(s_axis_tready),
193+
.s_axis_tlast(s_axis_tlast),
194+
.s_axis_tid(s_axis_tid),
195+
.s_axis_tdest(s_axis_tdest),
196+
.s_axis_tuser(s_axis_tuser),
197+
// AXI output
198+
.m_axis_tdata(pre_fifo_axis_tdata),
199+
.m_axis_tkeep(pre_fifo_axis_tkeep),
200+
.m_axis_tvalid(pre_fifo_axis_tvalid),
201+
.m_axis_tready(pre_fifo_axis_tready),
202+
.m_axis_tlast(pre_fifo_axis_tlast),
203+
.m_axis_tid(pre_fifo_axis_tid),
204+
.m_axis_tdest(pre_fifo_axis_tdest),
205+
.m_axis_tuser(pre_fifo_axis_tuser)
206+
);
207+
208+
assign m_axis_tdata = post_fifo_axis_tdata;
209+
assign m_axis_tkeep = post_fifo_axis_tkeep;
210+
assign m_axis_tvalid = post_fifo_axis_tvalid;
211+
assign post_fifo_axis_tready = m_axis_tready;
212+
assign m_axis_tlast = post_fifo_axis_tlast;
213+
assign m_axis_tid = post_fifo_axis_tid;
214+
assign m_axis_tdest = post_fifo_axis_tdest;
215+
assign m_axis_tuser = post_fifo_axis_tuser;
216+
217+
end else begin
218+
219+
// input wider, adapt width after FIFO
220+
221+
assign pre_fifo_axis_tdata = s_axis_tdata;
222+
assign pre_fifo_axis_tkeep = s_axis_tkeep;
223+
assign pre_fifo_axis_tvalid = s_axis_tvalid;
224+
assign s_axis_tready = pre_fifo_axis_tready;
225+
assign pre_fifo_axis_tlast = s_axis_tlast;
226+
assign pre_fifo_axis_tid = s_axis_tid;
227+
assign pre_fifo_axis_tdest = s_axis_tdest;
228+
assign pre_fifo_axis_tuser = s_axis_tuser;
229+
230+
axis_adapter #(
231+
.S_DATA_WIDTH(S_DATA_WIDTH),
232+
.S_KEEP_ENABLE(S_KEEP_ENABLE),
233+
.S_KEEP_WIDTH(S_KEEP_WIDTH),
234+
.M_DATA_WIDTH(M_DATA_WIDTH),
235+
.M_KEEP_ENABLE(M_KEEP_ENABLE),
236+
.M_KEEP_WIDTH(M_KEEP_WIDTH),
237+
.ID_ENABLE(ID_ENABLE),
238+
.ID_WIDTH(ID_WIDTH),
239+
.DEST_ENABLE(DEST_ENABLE),
240+
.DEST_WIDTH(DEST_WIDTH),
241+
.USER_ENABLE(USER_ENABLE),
242+
.USER_WIDTH(USER_WIDTH)
243+
)
244+
adapter_inst (
245+
.clk(m_clk),
246+
.rst(m_rst),
247+
// AXI input
248+
.s_axis_tdata(post_fifo_axis_tdata),
249+
.s_axis_tkeep(post_fifo_axis_tkeep),
250+
.s_axis_tvalid(post_fifo_axis_tvalid),
251+
.s_axis_tready(post_fifo_axis_tready),
252+
.s_axis_tlast(post_fifo_axis_tlast),
253+
.s_axis_tid(post_fifo_axis_tid),
254+
.s_axis_tdest(post_fifo_axis_tdest),
255+
.s_axis_tuser(post_fifo_axis_tuser),
256+
// AXI output
257+
.m_axis_tdata(m_axis_tdata),
258+
.m_axis_tkeep(m_axis_tkeep),
259+
.m_axis_tvalid(m_axis_tvalid),
260+
.m_axis_tready(m_axis_tready),
261+
.m_axis_tlast(m_axis_tlast),
262+
.m_axis_tid(m_axis_tid),
263+
.m_axis_tdest(m_axis_tdest),
264+
.m_axis_tuser(m_axis_tuser)
265+
);
266+
267+
end
268+
269+
endgenerate
270+
271+
axis_async_fifo #(
272+
.ADDR_WIDTH(ADDR_WIDTH),
273+
.DATA_WIDTH(DATA_WIDTH),
274+
.KEEP_ENABLE(EXPAND_BUS ? M_KEEP_ENABLE : S_KEEP_ENABLE),
275+
.KEEP_WIDTH(KEEP_WIDTH),
276+
.LAST_ENABLE(1),
277+
.ID_ENABLE(ID_ENABLE),
278+
.ID_WIDTH(ID_WIDTH),
279+
.DEST_ENABLE(DEST_ENABLE),
280+
.DEST_WIDTH(DEST_WIDTH),
281+
.USER_ENABLE(USER_ENABLE),
282+
.USER_WIDTH(USER_WIDTH),
283+
.FRAME_FIFO(FRAME_FIFO),
284+
.USER_BAD_FRAME_VALUE(USER_BAD_FRAME_VALUE),
285+
.USER_BAD_FRAME_MASK(USER_BAD_FRAME_MASK),
286+
.DROP_BAD_FRAME(DROP_BAD_FRAME),
287+
.DROP_WHEN_FULL(DROP_WHEN_FULL)
288+
)
289+
fifo_inst (
290+
// Common reset
291+
.async_rst(s_rst | m_rst),
292+
// AXI input
293+
.s_clk(s_clk),
294+
.s_axis_tdata(pre_fifo_axis_tdata),
295+
.s_axis_tkeep(pre_fifo_axis_tkeep),
296+
.s_axis_tvalid(pre_fifo_axis_tvalid),
297+
.s_axis_tready(pre_fifo_axis_tready),
298+
.s_axis_tlast(pre_fifo_axis_tlast),
299+
.s_axis_tid(pre_fifo_axis_tid),
300+
.s_axis_tdest(pre_fifo_axis_tdest),
301+
.s_axis_tuser(pre_fifo_axis_tuser),
302+
// AXI output
303+
.m_clk(m_clk),
304+
.m_axis_tdata(post_fifo_axis_tdata),
305+
.m_axis_tkeep(post_fifo_axis_tkeep),
306+
.m_axis_tvalid(post_fifo_axis_tvalid),
307+
.m_axis_tready(post_fifo_axis_tready),
308+
.m_axis_tlast(post_fifo_axis_tlast),
309+
.m_axis_tid(post_fifo_axis_tid),
310+
.m_axis_tdest(post_fifo_axis_tdest),
311+
.m_axis_tuser(post_fifo_axis_tuser),
312+
// Status
313+
.s_status_overflow(s_status_overflow),
314+
.s_status_bad_frame(s_status_bad_frame),
315+
.s_status_good_frame(s_status_good_frame),
316+
.m_status_overflow(m_status_overflow),
317+
.m_status_bad_frame(m_status_bad_frame),
318+
.m_status_good_frame(m_status_good_frame)
319+
);
320+
321+
endmodule

lib/axis/rtl/axis_fifo.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ always @* begin
207207
wr_ptr_cur_next = wr_ptr_cur_reg + 1;
208208
if (s_axis_tlast) begin
209209
// end of frame
210-
if (DROP_BAD_FRAME && (USER_BAD_FRAME_MASK & s_axis_tuser == USER_BAD_FRAME_VALUE)) begin
210+
if (DROP_BAD_FRAME && USER_BAD_FRAME_MASK & ~(s_axis_tuser ^ USER_BAD_FRAME_VALUE)) begin
211211
// bad packet, reset write pointer
212212
wr_ptr_cur_next = wr_ptr_reg;
213213
bad_frame_next = 1'b1;

0 commit comments

Comments
 (0)