@@ -85,156 +85,172 @@ module axis_pipeline_fifo #
85
85
86
86
parameter FIFO_ADDR_WIDTH = LENGTH < 2 ? 3 : $clog2(LENGTH* 4 );
87
87
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
161
124
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 }};
162
127
axis_tvalid_reg[i] = 1'b0 ;
163
128
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 }};
164
133
end
165
134
end
166
- end
167
135
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
221
158
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
231
165
end
232
166
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
237
237
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
+
238
252
end
239
253
254
+ endgenerate
255
+
240
256
endmodule
0 commit comments