@@ -26,27 +26,27 @@ module axi_fifo_delay_dyn #(
2626 // AXI request & response types
2727 parameter type axi_req_t = logic ,
2828 parameter type axi_resp_t = logic ,
29- // delay parameters
29+ // Delay parameters
3030 parameter int unsigned DepthAR = 4 , // Power of two
3131 parameter int unsigned DepthAW = 4 , // Power of two
3232 parameter int unsigned DepthR = 4 , // Power of two
3333 parameter int unsigned DepthW = 4 , // Power of two
34- parameter int unsigned DepthB = 4 , // Power of two
34+ parameter int unsigned DepthB = 4 , // Power of two
3535 parameter int unsigned MaxDelay = 1024 ,
3636 // DO NOT EDIT, derived parameters
3737 localparam int unsigned DelayWidth = $clog2(MaxDelay) + 1
3838) (
3939 input logic clk_i, // Clock
4040 input logic rst_ni, // Asynchronous reset active low
41- input logic [DelayWidth- 1 : 0 ] aw_delay_i,
42- input logic [DelayWidth- 1 : 0 ] w_delay_i,
43- input logic [DelayWidth- 1 : 0 ] b_delay_i,
44- input logic [DelayWidth- 1 : 0 ] ar_delay_i,
45- input logic [DelayWidth- 1 : 0 ] r_delay_i,
46- // slave port
41+ input logic [DelayWidth- 1 : 0 ] aw_delay_i, // Delay of AW channel
42+ input logic [DelayWidth- 1 : 0 ] w_delay_i, // Delay of W channel
43+ input logic [DelayWidth- 1 : 0 ] b_delay_i, // Delay of B channel
44+ input logic [DelayWidth- 1 : 0 ] ar_delay_i, // Delay of AR channel
45+ input logic [DelayWidth- 1 : 0 ] r_delay_i, // Delay of R channel
46+ // Slave port
4747 input axi_req_t slv_req_i,
4848 output axi_resp_t slv_resp_o,
49- // master port
49+ // Master port
5050 output axi_req_t mst_req_o,
5151 input axi_resp_t mst_resp_i
5252);
@@ -168,33 +168,31 @@ module axi_fifo_delay_dyn #(
168168
169169endmodule
170170
171-
172-
173171// / Delay and buffer an AXI bus interface wrapper
174172module axi_fifo_delay_dyn_intf # (
175173 // Synopsys DC requires a default value for parameters.
176- parameter int unsigned AXI_ID_WIDTH = 0 ,
177- parameter int unsigned AXI_ADDR_WIDTH = 0 ,
178- parameter int unsigned AXI_DATA_WIDTH = 0 ,
179- parameter int unsigned AXI_USER_WIDTH = 0 ,
180- parameter int unsigned DEPTH_AR = 4 , // Power of two
181- parameter int unsigned DEPTH_AW = 4 , // Power of two
182- parameter int unsigned DEPTH_R = 4 , // Power of two
183- parameter int unsigned DEPTH_W = 4 , // Power of two
184- parameter int unsigned DEPTH_B = 4 , // Power of two
185- parameter int unsigned MAX_DELAY = 0 ,
174+ parameter int unsigned AXI_ID_WIDTH = 0 ,
175+ parameter int unsigned AXI_ADDR_WIDTH = 0 ,
176+ parameter int unsigned AXI_DATA_WIDTH = 0 ,
177+ parameter int unsigned AXI_USER_WIDTH = 0 ,
178+ parameter int unsigned DEPTH_AR = 4 , // Power of two
179+ parameter int unsigned DEPTH_AW = 4 , // Power of two
180+ parameter int unsigned DEPTH_R = 4 , // Power of two
181+ parameter int unsigned DEPTH_W = 4 , // Power of two
182+ parameter int unsigned DEPTH_B = 4 , // Power of two
183+ parameter int unsigned MAX_DELAY = 0 ,
186184 // DO NOT EDIT, derived parameters
187- parameter int unsigned DELAY_WIDTH = $clog2(MAX_DELAY ) + 1
185+ parameter int unsigned DELAY_WIDTH = $clog2(MAX_DELAY ) + 1
188186) (
189- input logic clk_i,
190- input logic rst_ni,
191- input logic [MAX_DELAY - 1 : 0 ] aw_delay_i,
192- input logic [MAX_DELAY - 1 : 0 ] w_delay_i,
193- input logic [MAX_DELAY - 1 : 0 ] b_delay_i,
194- input logic [MAX_DELAY - 1 : 0 ] ar_delay_i,
195- input logic [MAX_DELAY - 1 : 0 ] r_delay_i,
196- AXI_BUS .Slave slv,
197- AXI_BUS .Master mst
187+ input logic clk_i, // Clock
188+ input logic rst_ni, // Asynchronous reset active low
189+ input logic [MAX_DELAY - 1 : 0 ] aw_delay_i, // Delay of AW channel
190+ input logic [MAX_DELAY - 1 : 0 ] w_delay_i, // Delay of W channel
191+ input logic [MAX_DELAY - 1 : 0 ] b_delay_i, // Delay of B channel
192+ input logic [MAX_DELAY - 1 : 0 ] ar_delay_i, // Delay of AR channel
193+ input logic [MAX_DELAY - 1 : 0 ] r_delay_i, // Delay of R channel
194+ AXI_BUS .Slave slv, // Slave port
195+ AXI_BUS .Master mst // Master port
198196);
199197
200198 typedef logic [AXI_ID_WIDTH - 1 : 0 ] id_t ;
@@ -260,25 +258,23 @@ module axi_fifo_delay_dyn_intf #(
260258// pragma translate_on
261259endmodule
262260
263-
264-
265261// / Delay and buffer a stream with AXI-like handshaking
266262module stream_fifo_delay_dyn # (
267- parameter type payload_t = logic ,
268- parameter int unsigned MaxDelay = 1024 ,
269- parameter int unsigned Depth = 4 , // Power of two
263+ parameter type payload_t = logic ,
264+ parameter int unsigned MaxDelay = 1024 ,
265+ parameter int unsigned Depth = 4 , // Power of two
270266 // DO NOT EDIT, derived parameters
271267 parameter int unsigned CounterWidth = $clog2(MaxDelay) + 1
272268)(
273- input logic clk_i,
274- input logic rst_ni,
275- input logic [CounterWidth- 1 : 0 ] delay_i,
276- input payload_t payload_i,
277- output logic ready_o,
278- input logic valid_i,
279- output payload_t payload_o,
280- input logic ready_i,
281- output logic valid_o
269+ input logic clk_i,
270+ input logic rst_ni,
271+ input logic [CounterWidth- 1 : 0 ] delay_i,
272+ input payload_t payload_i,
273+ output logic ready_o,
274+ input logic valid_i,
275+ output payload_t payload_o,
276+ input logic ready_i,
277+ output logic valid_o
282278);
283279
284280 `ifdef SYNTHESIS
@@ -291,151 +287,161 @@ module stream_fifo_delay_dyn #(
291287 $fatal (1 , " Depth must be a power of two" );
292288
293289 localparam int unsigned BookeepingBits = $clog2 (Depth) + 1 ;
294- logic [BookeepingBits- 1 : 0 ] dead_count_d, dead_count_q;
295290
296- // head_deadline : latest element's deadline
297- // tail_deadline : next element's deadline
298- logic [CounterWidth- 1 : 0 ] count_val;
299- logic [CounterWidth- 1 : 0 ] head_deadline, tail_deadline;
291+ // Number of elements that have been held in the data FIFO
292+ // for at least the amount of cycles specified by delay_i.
293+ logic [BookeepingBits- 1 : 0 ] ready_count_d, ready_count_q;
294+
295+ logic [CounterWidth- 1 : 0 ] count_val; // Counter value
296+ logic [CounterWidth- 1 : 0 ] head_deadline; // Last element's deadline
297+ logic [CounterWidth- 1 : 0 ] tail_deadline; // Next element's deadline
300298 payload_t head_data;
301299
302300 logic fifo_dead_full, fifo_dead_empty, fifo_dead_push, fifo_dead_pop;
303301 logic fifo_data_full, fifo_data_empty, fifo_data_push, fifo_data_pop;
304302
305- `FF (dead_count_q, dead_count_d , '0 , clk_i, rst_ni);
303+ `FF (ready_count_q, ready_count_d , '0 , clk_i, rst_ni);
306304
307305 always_comb begin
308- dead_count_d = dead_count_q ;
309- if (fifo_dead_pop)
310- dead_count_d + = 1 ;
311- if (fifo_data_pop)
312- dead_count_d - = 1 ;
306+ ready_count_d = ready_count_q ;
307+ if (fifo_dead_pop) // A new element timed out
308+ ready_count_d + = 1 ;
309+ if (fifo_data_pop) // A ready element was popped from the downstream interface
310+ ready_count_d - = 1 ;
313311 end
314312
313+ // The deadline of a new incoming data is calculated by adding
314+ // the input delay value to the current counter value.
315315 assign tail_deadline = count_val + delay_i + 1 ;
316316
317317 assign fifo_data_push = ~ fifo_data_full & valid_i;
318318 assign fifo_dead_push = fifo_data_push;
319319
320+ // Pop value from deadline FIFO once the counter reaches the deadline
321+ // value of the first element in the queue.
320322 assign fifo_dead_pop = (count_val == head_deadline) & ~ fifo_dead_empty;
321323 assign fifo_data_pop = valid_o & ready_i;
322324
323- assign valid_o = (dead_count_q > 0 );
325+ assign valid_o = (ready_count_q > 0 );
324326 assign ready_o = ~ fifo_data_full;
325327
326328 assign payload_o = head_data;
327329
328330 counter # (
329- .WIDTH ( CounterWidth )
331+ .WIDTH ( CounterWidth )
330332 ) i_counter (
331- .clk_i,
332- .rst_ni,
333- .clear_i ( 1'b0 ),
334- .en_i ( 1'b1 ),
335- .load_i ( 1'b0 ),
336- .down_i ( 1'b0 ),
337- .d_i ( '0 ),
338- .q_o ( count_val ),
339- .overflow_o ( )
333+ .clk_i ( clk_i ) ,
334+ .rst_ni ( rst_ni ) ,
335+ .clear_i ( 1'b0 ),
336+ .en_i ( 1'b1 ),
337+ .load_i ( 1'b0 ),
338+ .down_i ( 1'b0 ),
339+ .d_i ( '0 ),
340+ .q_o ( count_val ),
341+ .overflow_o ( ) // Not used
340342 );
341343
344+ // Data FIFO
345+ // Buffers the payload data
342346`ifdef TARGET_XILINX
343347 xpm_fifo_sync # (
344- .FIFO_MEMORY_TYPE ( " auto" ) , // string; "auto", "block", "distributed", or "ultra";
345- .ECC_MODE ( " no_ecc" ) , // string; "no_ecc" or "en_ecc";
346- .FIFO_WRITE_DEPTH ( Depth ) , // positive integer
347- .WRITE_DATA_WIDTH ( $bits (payload_t) ) , // positive integer
348- .WR_DATA_COUNT_WIDTH ( $clog2 (Depth)+ 1 ) , // positive integer, not used
349- .PROG_FULL_THRESH ( 10 ) , // positive integer, not used
350- .FULL_RESET_VALUE ( 1 ) , // positive integer; 0 or 1
351- .USE_ADV_FEATURES ( " 1F1F" ) , // string; "0000" to "1F1F";
352- .READ_MODE ( " std" ) , // string; "std" or "fwft";
353- .FIFO_READ_LATENCY ( 0 ) , // positive integer;
354- .READ_DATA_WIDTH ( $bits (payload_t) ) , // positive integer
355- .RD_DATA_COUNT_WIDTH ( $clog2 (Depth)+ 1 ) , // positive integer, not used
356- .PROG_EMPTY_THRESH ( 10 ) , // positive integer, not used
357- .DOUT_RESET_VALUE ( " 0" ) , // string, don't care
358- .WAKEUP_TIME ( 0 ) // positive integer; 0 or 2;
348+ .FIFO_MEMORY_TYPE ( " auto" ), // string; "auto", "block", "distributed", or "ultra";
349+ .ECC_MODE ( " no_ecc" ), // string; "no_ecc" or "en_ecc";
350+ .FIFO_WRITE_DEPTH ( Depth ), // positive integer
351+ .WRITE_DATA_WIDTH ( $bits (payload_t) ), // positive integer
352+ .WR_DATA_COUNT_WIDTH ( $clog2 (Depth)+ 1 ), // positive integer, not used
353+ .PROG_FULL_THRESH ( 10 ), // positive integer, not used
354+ .FULL_RESET_VALUE ( 1 ), // positive integer; 0 or 1
355+ .USE_ADV_FEATURES ( " 1F1F" ), // string; "0000" to "1F1F";
356+ .READ_MODE ( " std" ), // string; "std" or "fwft";
357+ .FIFO_READ_LATENCY ( 0 ), // positive integer;
358+ .READ_DATA_WIDTH ( $bits (payload_t) ), // positive integer
359+ .RD_DATA_COUNT_WIDTH ( $clog2 (Depth)+ 1 ), // positive integer, not used
360+ .PROG_EMPTY_THRESH ( 10 ), // positive integer, not used
361+ .DOUT_RESET_VALUE ( " 0" ), // string, don't care
362+ .WAKEUP_TIME ( 0 ) // positive integer; 0 or 2;
359363 ) data_fifo (
360- .sleep ( '0 ),
361- .injectsbiterr ( '0 ),
362- .injectdbiterr ( '0 ),
363- .wr_clk ( clk_i),
364- .rst ( ~ rst_ni),
365- .wr_en ( fifo_data_push),
366- .rd_en ( fifo_data_pop),
367- .full ( fifo_data_full),
368- .empty ( fifo_data_empty),
369- .din ( payload_i),
370- .dout ( head_data)
364+ .sleep ( '0 ),
365+ .injectsbiterr ( '0 ),
366+ .injectdbiterr ( '0 ),
367+ .wr_clk ( clk_i ),
368+ .rst ( ~ rst_ni ),
369+ .wr_en ( fifo_data_push ),
370+ .rd_en ( fifo_data_pop ),
371+ .full ( fifo_data_full ),
372+ .empty ( fifo_data_empty ),
373+ .din ( payload_i ),
374+ .dout ( head_data )
371375 );
372376`else
373377 fifo_v3 # (
374- .DATA_WIDTH ( $bits (payload_t) ),
375- .DEPTH ( Depth ),
376- .FALL_THROUGH ( 1'b0 )
378+ .DATA_WIDTH ( $bits (payload_t) ),
379+ .DEPTH ( Depth ),
380+ .FALL_THROUGH ( 1'b0 )
377381 ) data_fifo (
378- .clk_i (clk_i ),
379- .rst_ni (rst_ni ),
380- .flush_i ( 1'b0 ),
381- .testmode_i ( 1'b0 ),
382- .data_i (payload_i ),
383- .push_i (fifo_data_push ),
384- .full_o (fifo_data_full ),
385- .data_o (head_data ),
386- .pop_i (fifo_data_pop ),
387- .empty_o (fifo_data_empty ),
388- .usage_o ( /* Unused */ )
382+ .clk_i ( clk_i ),
383+ .rst_ni ( rst_ni ),
384+ .flush_i ( 1'b0 ),
385+ .testmode_i ( 1'b0 ),
386+ .data_i ( payload_i ),
387+ .push_i ( fifo_data_push ),
388+ .full_o ( fifo_data_full ),
389+ .data_o ( head_data ),
390+ .pop_i ( fifo_data_pop ),
391+ .empty_o ( fifo_data_empty ),
392+ .usage_o ( ) // Not used
389393 );
390394`endif
391395
396+ // Deadline FIFO
397+ // Buffers the deadline for each buffered payload data
392398`ifdef TARGET_XILINX
393399 xpm_fifo_sync # (
394- .FIFO_MEMORY_TYPE ( " auto" ) , // string; "auto", "block", "distributed", or "ultra";
395- .ECC_MODE ( " no_ecc" ) , // string; "no_ecc" or "en_ecc";
396- .FIFO_WRITE_DEPTH ( Depth ) , // positive integer
397- .WRITE_DATA_WIDTH ( CounterWidth ) , // positive integer
398- .WR_DATA_COUNT_WIDTH ( $clog2 (Depth)+ 1 ) , // positive integer, not used
399- .PROG_FULL_THRESH ( 10 ) , // positive integer, not used
400- .FULL_RESET_VALUE ( 1 ) , // positive integer; 0 or 1
401- .USE_ADV_FEATURES ( " 1F1F" ) , // string; "0000" to "1F1F";
402- .READ_MODE ( " std" ) , // string; "std" or "fwft";
403- .FIFO_READ_LATENCY ( 0 ) , // positive integer;
404- .READ_DATA_WIDTH ( CounterWidth ) , // positive integer
405- .RD_DATA_COUNT_WIDTH ( $clog2 (Depth)+ 1 ) , // positive integer, not used
406- .PROG_EMPTY_THRESH ( 10 ) , // positive integer, not used
407- .DOUT_RESET_VALUE ( " 0" ) , // string, don't care
408- .WAKEUP_TIME ( 0 ) // positive integer; 0 or 2;
400+ .FIFO_MEMORY_TYPE ( " auto" ), // string; "auto", "block", "distributed", or "ultra";
401+ .ECC_MODE ( " no_ecc" ), // string; "no_ecc" or "en_ecc";
402+ .FIFO_WRITE_DEPTH ( Depth ), // positive integer
403+ .WRITE_DATA_WIDTH ( CounterWidth ), // positive integer
404+ .WR_DATA_COUNT_WIDTH ( $clog2 (Depth)+ 1 ), // positive integer, not used
405+ .PROG_FULL_THRESH ( 10 ), // positive integer, not used
406+ .FULL_RESET_VALUE ( 1 ), // positive integer; 0 or 1
407+ .USE_ADV_FEATURES ( " 1F1F" ), // string; "0000" to "1F1F";
408+ .READ_MODE ( " std" ), // string; "std" or "fwft";
409+ .FIFO_READ_LATENCY ( 0 ), // positive integer;
410+ .READ_DATA_WIDTH ( CounterWidth ), // positive integer
411+ .RD_DATA_COUNT_WIDTH ( $clog2 (Depth)+ 1 ), // positive integer, not used
412+ .PROG_EMPTY_THRESH ( 10 ), // positive integer, not used
413+ .DOUT_RESET_VALUE ( " 0" ), // string, don't care
414+ .WAKEUP_TIME ( 0 ) // positive integer; 0 or 2;
409415 ) deadline_fifo (
410- .sleep ( '0 ),
411- .injectsbiterr ( '0 ),
412- .injectdbiterr ( '0 ),
413- .wr_clk ( clk_i),
414- .rst ( ~ rst_ni),
415- .wr_en ( fifo_dead_push),
416- .rd_en ( fifo_dead_pop),
417- .full ( fifo_dead_full),
418- .empty ( fifo_dead_empty),
419- .din ( tail_deadline),
420- .dout ( head_deadline)
416+ .sleep ( '0 ),
417+ .injectsbiterr ( '0 ),
418+ .injectdbiterr ( '0 ),
419+ .wr_clk ( clk_i ),
420+ .rst ( ~ rst_ni ),
421+ .wr_en ( fifo_dead_push ),
422+ .rd_en ( fifo_dead_pop ),
423+ .full ( fifo_dead_full ),
424+ .empty ( fifo_dead_empty ),
425+ .din ( tail_deadline ),
426+ .dout ( head_deadline )
421427 );
422428`else
423429 fifo_v3 # (
424- .DATA_WIDTH ( CounterWidth ),
425- .DEPTH ( Depth ),
426- .FALL_THROUGH ( 1'b0 )
430+ .DATA_WIDTH ( CounterWidth ),
431+ .DEPTH ( Depth ),
432+ .FALL_THROUGH ( 1'b0 )
427433 ) deadline_fifo (
428- .clk_i (clk_i ),
429- .rst_ni (rst_ni ),
430- .flush_i ( 1'b0 ),
431- .testmode_i ( 1'b0 ),
432- .data_i (tail_deadline ),
433- .push_i (fifo_dead_push ),
434- .full_o (fifo_dead_full ),
435- .data_o (head_deadline ),
436- .pop_i (fifo_dead_pop ),
437- .empty_o (fifo_dead_empty ),
438- .usage_o ( /* Unused */ )
434+ .clk_i ( clk_i ),
435+ .rst_ni ( rst_ni ),
436+ .flush_i ( 1'b0 ),
437+ .testmode_i ( 1'b0 ),
438+ .data_i ( tail_deadline ),
439+ .push_i ( fifo_dead_push ),
440+ .full_o ( fifo_dead_full ),
441+ .data_o ( head_deadline ),
442+ .pop_i ( fifo_dead_pop ),
443+ .empty_o ( fifo_dead_empty ),
444+ .usage_o ( ) // Not used
439445 );
440446`endif
441447
0 commit comments