@@ -85,156 +85,172 @@ module axis_pipeline_fifo #
8585
8686parameter FIFO_ADDR_WIDTH = LENGTH < 2 ? 3 : $clog2(LENGTH* 4 );
8787
88- initial begin
89- if (LENGTH < 1 ) begin
90- $error("Error: LENGTH must be at least 1 (instance %m)" );
91- $finish ;
92- end
93- end
94-
95- // pipeline
96- (* shreg_extract = "no" * )
97- reg [DATA_WIDTH- 1 :0 ] axis_tdata_reg[0 :LENGTH- 1 ];
98- (* shreg_extract = "no" * )
99- reg [KEEP_WIDTH- 1 :0 ] axis_tkeep_reg[0 :LENGTH- 1 ];
100- (* shreg_extract = "no" * )
101- reg axis_tvalid_reg[0 :LENGTH- 1 ];
102- (* shreg_extract = "no" * )
103- reg axis_tready_reg[0 :LENGTH- 1 ];
104- (* shreg_extract = "no" * )
105- reg axis_tlast_reg[0 :LENGTH- 1 ];
106- (* shreg_extract = "no" * )
107- reg [ID_WIDTH- 1 :0 ] axis_tid_reg[0 :LENGTH- 1 ];
108- (* shreg_extract = "no" * )
109- reg [DEST_WIDTH- 1 :0 ] axis_tdest_reg[0 :LENGTH- 1 ];
110- (* shreg_extract = "no" * )
111- reg [USER_WIDTH- 1 :0 ] axis_tuser_reg[0 :LENGTH- 1 ];
112-
113- wire [DATA_WIDTH- 1 :0 ] m_axis_tdata_int = axis_tdata_reg[LENGTH- 1 ];
114- wire [KEEP_WIDTH- 1 :0 ] m_axis_tkeep_int = axis_tkeep_reg[LENGTH- 1 ];
115- wire m_axis_tvalid_int = axis_tvalid_reg[LENGTH- 1 ];
116- wire m_axis_tready_int;
117- wire m_axis_tlast_int = axis_tlast_reg[LENGTH- 1 ];
118- wire [ID_WIDTH- 1 :0 ] m_axis_tid_int = axis_tid_reg[LENGTH- 1 ];
119- wire [DEST_WIDTH- 1 :0 ] m_axis_tdest_int = axis_tdest_reg[LENGTH- 1 ];
120- wire [USER_WIDTH- 1 :0 ] m_axis_tuser_int = axis_tuser_reg[LENGTH- 1 ];
121-
122- assign s_axis_tready = axis_tready_reg[0 ];
123-
124- integer i;
125-
126- initial begin
127- for (i = 0 ; i < LENGTH; i = i + 1 ) begin
128- axis_tdata_reg[i] = {DATA_WIDTH{1'b0 }};
129- axis_tkeep_reg[i] = {KEEP_WIDTH{1'b0 }};
130- axis_tvalid_reg[i] = 1'b0 ;
131- axis_tready_reg[i] = 1'b0 ;
132- axis_tlast_reg[i] = 1'b0 ;
133- axis_tid_reg[i] = {ID_WIDTH{1'b0 }};
134- axis_tdest_reg[i] = {DEST_WIDTH{1'b0 }};
135- axis_tuser_reg[i] = {USER_WIDTH{1'b0 }};
136- end
137- end
138-
139- always @(posedge clk) begin
140- axis_tdata_reg[0 ] <= s_axis_tdata;
141- axis_tkeep_reg[0 ] <= s_axis_tkeep;
142- axis_tvalid_reg[0 ] <= s_axis_tvalid && s_axis_tready;
143- axis_tready_reg[LENGTH- 1 ] <= m_axis_tready_int;
144- axis_tlast_reg[0 ] <= s_axis_tlast;
145- axis_tid_reg[0 ] <= s_axis_tid;
146- axis_tdest_reg[0 ] <= s_axis_tdest;
147- axis_tuser_reg[0 ] <= s_axis_tuser;
148-
149- for (i = 0 ; i < LENGTH- 1 ; i = i + 1 ) begin
150- axis_tdata_reg[i+ 1 ] <= axis_tdata_reg[i];
151- axis_tkeep_reg[i+ 1 ] <= axis_tkeep_reg[i];
152- axis_tvalid_reg[i+ 1 ] <= axis_tvalid_reg[i];
153- axis_tready_reg[i] <= axis_tready_reg[i+ 1 ];
154- axis_tlast_reg[i+ 1 ] <= axis_tlast_reg[i];
155- axis_tid_reg[i+ 1 ] <= axis_tid_reg[i];
156- axis_tdest_reg[i+ 1 ] <= axis_tdest_reg[i];
157- axis_tuser_reg[i+ 1 ] <= axis_tuser_reg[i];
158- end
159-
160- if (rst) begin
88+ generate
89+
90+ if (LENGTH > 0 ) begin
91+
92+ // pipeline
93+ (* shreg_extract = "no" * )
94+ reg [DATA_WIDTH- 1 :0 ] axis_tdata_reg[0 :LENGTH- 1 ];
95+ (* shreg_extract = "no" * )
96+ reg [KEEP_WIDTH- 1 :0 ] axis_tkeep_reg[0 :LENGTH- 1 ];
97+ (* shreg_extract = "no" * )
98+ reg axis_tvalid_reg[0 :LENGTH- 1 ];
99+ (* shreg_extract = "no" * )
100+ reg axis_tready_reg[0 :LENGTH- 1 ];
101+ (* shreg_extract = "no" * )
102+ reg axis_tlast_reg[0 :LENGTH- 1 ];
103+ (* shreg_extract = "no" * )
104+ reg [ID_WIDTH- 1 :0 ] axis_tid_reg[0 :LENGTH- 1 ];
105+ (* shreg_extract = "no" * )
106+ reg [DEST_WIDTH- 1 :0 ] axis_tdest_reg[0 :LENGTH- 1 ];
107+ (* shreg_extract = "no" * )
108+ reg [USER_WIDTH- 1 :0 ] axis_tuser_reg[0 :LENGTH- 1 ];
109+
110+ wire [DATA_WIDTH- 1 :0 ] m_axis_tdata_int = axis_tdata_reg[LENGTH- 1 ];
111+ wire [KEEP_WIDTH- 1 :0 ] m_axis_tkeep_int = axis_tkeep_reg[LENGTH- 1 ];
112+ wire m_axis_tvalid_int = axis_tvalid_reg[LENGTH- 1 ];
113+ wire m_axis_tready_int;
114+ wire m_axis_tlast_int = axis_tlast_reg[LENGTH- 1 ];
115+ wire [ID_WIDTH- 1 :0 ] m_axis_tid_int = axis_tid_reg[LENGTH- 1 ];
116+ wire [DEST_WIDTH- 1 :0 ] m_axis_tdest_int = axis_tdest_reg[LENGTH- 1 ];
117+ wire [USER_WIDTH- 1 :0 ] m_axis_tuser_int = axis_tuser_reg[LENGTH- 1 ];
118+
119+ assign s_axis_tready = axis_tready_reg[0 ];
120+
121+ integer i;
122+
123+ initial begin
161124 for (i = 0 ; i < LENGTH; i = i + 1 ) begin
125+ axis_tdata_reg[i] = {DATA_WIDTH{1'b0 }};
126+ axis_tkeep_reg[i] = {KEEP_WIDTH{1'b0 }};
162127 axis_tvalid_reg[i] = 1'b0 ;
163128 axis_tready_reg[i] = 1'b0 ;
129+ axis_tlast_reg[i] = 1'b0 ;
130+ axis_tid_reg[i] = {ID_WIDTH{1'b0 }};
131+ axis_tdest_reg[i] = {DEST_WIDTH{1'b0 }};
132+ axis_tuser_reg[i] = {USER_WIDTH{1'b0 }};
164133 end
165134 end
166- end
167135
168- // output datapath logic
169- reg [DATA_WIDTH- 1 :0 ] m_axis_tdata_reg = {DATA_WIDTH{1'b0 }};
170- reg [KEEP_WIDTH- 1 :0 ] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0 }};
171- reg m_axis_tvalid_reg = 1'b0 ;
172- reg m_axis_tlast_reg = 1'b0 ;
173- reg [ID_WIDTH- 1 :0 ] m_axis_tid_reg = {ID_WIDTH{1'b0 }};
174- reg [DEST_WIDTH- 1 :0 ] m_axis_tdest_reg = {DEST_WIDTH{1'b0 }};
175- reg [USER_WIDTH- 1 :0 ] m_axis_tuser_reg = {USER_WIDTH{1'b0 }};
176-
177- reg [FIFO_ADDR_WIDTH+ 1 - 1 :0 ] out_fifo_wr_ptr_reg = 0 ;
178- reg [FIFO_ADDR_WIDTH+ 1 - 1 :0 ] out_fifo_rd_ptr_reg = 0 ;
179- reg out_fifo_half_full_reg = 1'b0 ;
180-
181- wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1 , {FIFO_ADDR_WIDTH{1'b0 }}});
182- wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg;
183-
184- (* ram_style = "distributed" * )
185- reg [DATA_WIDTH- 1 :0 ] out_fifo_tdata[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
186- (* ram_style = "distributed" * )
187- reg [KEEP_WIDTH- 1 :0 ] out_fifo_tkeep[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
188- (* ram_style = "distributed" * )
189- reg out_fifo_tlast[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
190- (* ram_style = "distributed" * )
191- reg [ID_WIDTH- 1 :0 ] out_fifo_tid[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
192- (* ram_style = "distributed" * )
193- reg [DEST_WIDTH- 1 :0 ] out_fifo_tdest[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
194- (* ram_style = "distributed" * )
195- reg [USER_WIDTH- 1 :0 ] out_fifo_tuser[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
196-
197- assign m_axis_tready_int = ! out_fifo_half_full_reg;
198-
199- assign m_axis_tdata = m_axis_tdata_reg;
200- assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1 }};
201- assign m_axis_tvalid = m_axis_tvalid_reg;
202- assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1 ;
203- assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0 }};
204- assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0 }};
205- assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0 }};
206-
207- always @(posedge clk) begin
208- m_axis_tvalid_reg <= m_axis_tvalid_reg && ! m_axis_tready;
209-
210- out_fifo_half_full_reg <= $unsigned (out_fifo_wr_ptr_reg - out_fifo_rd_ptr_reg) >= 2 ** (FIFO_ADDR_WIDTH- 1 );
211-
212- if (! out_fifo_full && m_axis_tvalid_int) begin
213- out_fifo_tdata[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tdata_int;
214- out_fifo_tkeep[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tkeep_int;
215- out_fifo_tlast[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tlast_int;
216- out_fifo_tid[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tid_int;
217- out_fifo_tdest[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tdest_int;
218- out_fifo_tuser[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tuser_int;
219- out_fifo_wr_ptr_reg <= out_fifo_wr_ptr_reg + 1 ;
220- end
136+ always @(posedge clk) begin
137+ axis_tdata_reg[0 ] <= s_axis_tdata;
138+ axis_tkeep_reg[0 ] <= s_axis_tkeep;
139+ axis_tvalid_reg[0 ] <= s_axis_tvalid && s_axis_tready;
140+ axis_tlast_reg[0 ] <= s_axis_tlast;
141+ axis_tid_reg[0 ] <= s_axis_tid;
142+ axis_tdest_reg[0 ] <= s_axis_tdest;
143+ axis_tuser_reg[0 ] <= s_axis_tuser;
144+
145+ axis_tready_reg[LENGTH- 1 ] <= m_axis_tready_int;
146+
147+ for (i = 0 ; i < LENGTH- 1 ; i = i + 1 ) begin
148+ axis_tdata_reg[i+ 1 ] <= axis_tdata_reg[i];
149+ axis_tkeep_reg[i+ 1 ] <= axis_tkeep_reg[i];
150+ axis_tvalid_reg[i+ 1 ] <= axis_tvalid_reg[i];
151+ axis_tlast_reg[i+ 1 ] <= axis_tlast_reg[i];
152+ axis_tid_reg[i+ 1 ] <= axis_tid_reg[i];
153+ axis_tdest_reg[i+ 1 ] <= axis_tdest_reg[i];
154+ axis_tuser_reg[i+ 1 ] <= axis_tuser_reg[i];
155+
156+ axis_tready_reg[i] <= axis_tready_reg[i+ 1 ];
157+ end
221158
222- if (! out_fifo_empty && (! m_axis_tvalid_reg || m_axis_tready)) begin
223- m_axis_tdata_reg <= out_fifo_tdata[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
224- m_axis_tkeep_reg <= out_fifo_tkeep[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
225- m_axis_tvalid_reg <= 1'b1 ;
226- m_axis_tlast_reg <= out_fifo_tlast[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
227- m_axis_tid_reg <= out_fifo_tid[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
228- m_axis_tdest_reg <= out_fifo_tdest[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
229- m_axis_tuser_reg <= out_fifo_tuser[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
230- out_fifo_rd_ptr_reg <= out_fifo_rd_ptr_reg + 1 ;
159+ if (rst) begin
160+ for (i = 0 ; i < LENGTH; i = i + 1 ) begin
161+ axis_tvalid_reg[i] = 1'b0 ;
162+ axis_tready_reg[i] = 1'b0 ;
163+ end
164+ end
231165 end
232166
233- if (rst) begin
234- out_fifo_wr_ptr_reg <= 0 ;
235- out_fifo_rd_ptr_reg <= 0 ;
236- m_axis_tvalid_reg <= 1'b0 ;
167+ // output datapath logic
168+ reg [DATA_WIDTH- 1 :0 ] m_axis_tdata_reg = {DATA_WIDTH{1'b0 }};
169+ reg [KEEP_WIDTH- 1 :0 ] m_axis_tkeep_reg = {KEEP_WIDTH{1'b0 }};
170+ reg m_axis_tvalid_reg = 1'b0 ;
171+ reg m_axis_tlast_reg = 1'b0 ;
172+ reg [ID_WIDTH- 1 :0 ] m_axis_tid_reg = {ID_WIDTH{1'b0 }};
173+ reg [DEST_WIDTH- 1 :0 ] m_axis_tdest_reg = {DEST_WIDTH{1'b0 }};
174+ reg [USER_WIDTH- 1 :0 ] m_axis_tuser_reg = {USER_WIDTH{1'b0 }};
175+
176+ reg [FIFO_ADDR_WIDTH+ 1 - 1 :0 ] out_fifo_wr_ptr_reg = 0 ;
177+ reg [FIFO_ADDR_WIDTH+ 1 - 1 :0 ] out_fifo_rd_ptr_reg = 0 ;
178+ reg out_fifo_half_full_reg = 1'b0 ;
179+
180+ wire out_fifo_full = out_fifo_wr_ptr_reg == (out_fifo_rd_ptr_reg ^ {1'b1 , {FIFO_ADDR_WIDTH{1'b0 }}});
181+ wire out_fifo_empty = out_fifo_wr_ptr_reg == out_fifo_rd_ptr_reg;
182+
183+ (* ram_style = "distributed" * )
184+ reg [DATA_WIDTH- 1 :0 ] out_fifo_tdata[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
185+ (* ram_style = "distributed" * )
186+ reg [KEEP_WIDTH- 1 :0 ] out_fifo_tkeep[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
187+ (* ram_style = "distributed" * )
188+ reg out_fifo_tlast[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
189+ (* ram_style = "distributed" * )
190+ reg [ID_WIDTH- 1 :0 ] out_fifo_tid[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
191+ (* ram_style = "distributed" * )
192+ reg [DEST_WIDTH- 1 :0 ] out_fifo_tdest[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
193+ (* ram_style = "distributed" * )
194+ reg [USER_WIDTH- 1 :0 ] out_fifo_tuser[2 ** FIFO_ADDR_WIDTH- 1 :0 ];
195+
196+ assign m_axis_tready_int = ! out_fifo_half_full_reg;
197+
198+ assign m_axis_tdata = m_axis_tdata_reg;
199+ assign m_axis_tkeep = KEEP_ENABLE ? m_axis_tkeep_reg : {KEEP_WIDTH{1'b1 }};
200+ assign m_axis_tvalid = m_axis_tvalid_reg;
201+ assign m_axis_tlast = LAST_ENABLE ? m_axis_tlast_reg : 1'b1 ;
202+ assign m_axis_tid = ID_ENABLE ? m_axis_tid_reg : {ID_WIDTH{1'b0 }};
203+ assign m_axis_tdest = DEST_ENABLE ? m_axis_tdest_reg : {DEST_WIDTH{1'b0 }};
204+ assign m_axis_tuser = USER_ENABLE ? m_axis_tuser_reg : {USER_WIDTH{1'b0 }};
205+
206+ always @(posedge clk) begin
207+ m_axis_tvalid_reg <= m_axis_tvalid_reg && ! m_axis_tready;
208+
209+ out_fifo_half_full_reg <= $unsigned (out_fifo_wr_ptr_reg - out_fifo_rd_ptr_reg) >= 2 ** (FIFO_ADDR_WIDTH- 1 );
210+
211+ if (! out_fifo_full && m_axis_tvalid_int) begin
212+ out_fifo_tdata[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tdata_int;
213+ out_fifo_tkeep[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tkeep_int;
214+ out_fifo_tlast[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tlast_int;
215+ out_fifo_tid[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tid_int;
216+ out_fifo_tdest[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tdest_int;
217+ out_fifo_tuser[out_fifo_wr_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]] <= m_axis_tuser_int;
218+ out_fifo_wr_ptr_reg <= out_fifo_wr_ptr_reg + 1 ;
219+ end
220+
221+ if (! out_fifo_empty && (! m_axis_tvalid_reg || m_axis_tready)) begin
222+ m_axis_tdata_reg <= out_fifo_tdata[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
223+ m_axis_tkeep_reg <= out_fifo_tkeep[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
224+ m_axis_tvalid_reg <= 1'b1 ;
225+ m_axis_tlast_reg <= out_fifo_tlast[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
226+ m_axis_tid_reg <= out_fifo_tid[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
227+ m_axis_tdest_reg <= out_fifo_tdest[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
228+ m_axis_tuser_reg <= out_fifo_tuser[out_fifo_rd_ptr_reg[FIFO_ADDR_WIDTH- 1 :0 ]];
229+ out_fifo_rd_ptr_reg <= out_fifo_rd_ptr_reg + 1 ;
230+ end
231+
232+ if (rst) begin
233+ out_fifo_wr_ptr_reg <= 0 ;
234+ out_fifo_rd_ptr_reg <= 0 ;
235+ m_axis_tvalid_reg <= 1'b0 ;
236+ end
237237 end
238+
239+ end else begin
240+ // bypass
241+
242+ assign m_axis_tdata = s_axis_tdata;
243+ assign m_axis_tkeep = KEEP_ENABLE ? s_axis_tkeep : {KEEP_WIDTH{1'b1 }};
244+ assign m_axis_tvalid = s_axis_tvalid;
245+ assign m_axis_tlast = LAST_ENABLE ? s_axis_tlast : 1'b1 ;
246+ assign m_axis_tid = ID_ENABLE ? s_axis_tid : {ID_WIDTH{1'b0 }};
247+ assign m_axis_tdest = DEST_ENABLE ? s_axis_tdest : {DEST_WIDTH{1'b0 }};
248+ assign m_axis_tuser = USER_ENABLE ? s_axis_tuser : {USER_WIDTH{1'b0 }};
249+
250+ assign s_axis_tready = m_axis_tready;
251+
238252end
239253
254+ endgenerate
255+
240256endmodule
0 commit comments