SURF  1.0
AxiStreamFifo.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : AxiStreamFifo.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2014-04-25
5 -- Last update: 2016-08-31
6 -------------------------------------------------------------------------------
7 -- Description:
8 -- Block to serve as an async FIFO for AXI Streams. This block also allows the
9 -- bus to be compress/expanded, allowing different standard sizes on each side
10 -- of the FIFO. Re-sizing is always little endian.
11 -------------------------------------------------------------------------------
12 -- This file is part of 'SLAC Firmware Standard Library'.
13 -- It is subject to the license terms in the LICENSE.txt file found in the
14 -- top-level directory of this distribution and at:
15 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
16 -- No part of 'SLAC Firmware Standard Library', including this file,
17 -- may be copied, modified, propagated, or distributed except according to
18 -- the terms contained in the LICENSE.txt file.
19 -------------------------------------------------------------------------------
20 
21 library ieee;
22 use ieee.std_logic_1164.all;
23 use ieee.std_logic_unsigned.all;
24 use ieee.std_logic_arith.all;
25 
26 use work.StdRtlPkg.all;
27 use work.AxiStreamPkg.all;
28 
29 --! @see entity
30  --! @ingroup axi
31 entity AxiStreamFifo is
32  generic (
33 
34  -- General Configurations
35  TPD_G : time := 1 ns;
36  INT_PIPE_STAGES_G : natural range 0 to 16 := 0; -- Internal FIFO setting
37  PIPE_STAGES_G : natural range 0 to 16 := 1;
38  SLAVE_READY_EN_G : boolean := true;
39  VALID_THOLD_G : integer range 0 to (2**24) := 1; -- =1 = normal operation
40  -- =0 = only when frame ready
41  -- >1 = only when frame ready or # entries
42  -- FIFO configurations
43  BRAM_EN_G : boolean := true;
44  XIL_DEVICE_G : string := "7SERIES";
45  USE_BUILT_IN_G : boolean := false;
46  GEN_SYNC_FIFO_G : boolean := false;
47  ALTERA_SYN_G : boolean := false;
48  ALTERA_RAM_G : string := "M9K";
49  CASCADE_SIZE_G : integer range 1 to (2**24) := 1;
50  FIFO_ADDR_WIDTH_G : integer range 4 to 48 := 9;
51  FIFO_FIXED_THRESH_G : boolean := true;
52  FIFO_PAUSE_THRESH_G : integer range 1 to (2**24) := 1;
53 
54  -- If VALID_THOLD_G /=1, FIFO that stores on tLast txns can be smaller.
55  -- Set to 0 for same size as primary fifo (default)
56  -- Set >4 for custom size.
57  -- Use at own risk. Overflow of tLast fifo is not checked
58  LAST_FIFO_ADDR_WIDTH_G : integer range 0 to 48 := 0;
59 
60  -- Index = 0 is output, index = n is input
61  CASCADE_PAUSE_SEL_G : integer range 0 to (2**24) := 0;
62 
63  -- AXI Stream Port Configurations
66  );
67  port (
68 
69  -- Slave Port
70  sAxisClk : in sl;
71  sAxisRst : in sl;
75 
76  -- FIFO status & config , synchronous to sAxisClk
77  fifoPauseThresh : in slv(FIFO_ADDR_WIDTH_G-1 downto 0) := (others => '1');
78 
79  -- Master Port
80  mAxisClk : in sl;
81  mAxisRst : in sl;
84  mTLastTUser : out slv(127 downto 0)); -- when VALID_THOLD_G /= 1, used to look ahead at tLast's tUser
85 end AxiStreamFifo;
86 
87 architecture rtl of AxiStreamFifo is
88 
90 
91  constant LAST_FIFO_ADDR_WIDTH_C : integer range 4 to 48 :=
93 
94  constant WR_BYTES_C : integer := SLAVE_AXI_CONFIG_G.TDATA_BYTES_C;
95  constant RD_BYTES_C : integer := MASTER_AXI_CONFIG_G.TDATA_BYTES_C;
96 
97  -- Use wider of two interfaces
98  constant DATA_BYTES_C : integer := maximum(SLAVE_AXI_CONFIG_G.TDATA_BYTES_C, MASTER_AXI_CONFIG_G.TDATA_BYTES_C);
99  constant DATA_BITS_C : integer := (DATA_BYTES_C * 8);
100 
101  -- Use SLAVE TKEEP Mode
102  constant KEEP_MODE_C : TKeepModeType := SLAVE_AXI_CONFIG_G.TKEEP_MODE_C;
103  constant KEEP_BITS_C : integer := ite(KEEP_MODE_C = TKEEP_NORMAL_C, DATA_BYTES_C,
104  ite(KEEP_MODE_C = TKEEP_COMP_C, bitSize(DATA_BYTES_C-1), 0));
105 
106  -- User user bit mode of slave
107  constant USER_MODE_C : TUserModeType := ite(((WR_BYTES_C = 1) or (RD_BYTES_C = 1)), TUSER_NORMAL_C, SLAVE_AXI_CONFIG_G.TUSER_MODE_C);
108 
109  -- Use whichever interface has the least number of user bits
110  constant SLAVE_USER_BITS_C : integer := SLAVE_AXI_CONFIG_G.TUSER_BITS_C;
111  constant MASTER_USER_BITS_C : integer := MASTER_AXI_CONFIG_G.TUSER_BITS_C;
112  constant FIFO_USER_BITS_C : integer := minimum(SLAVE_USER_BITS_C, MASTER_USER_BITS_C);
113 
114  constant FIFO_USER_TOT_C : integer := ite(USER_MODE_C = TUSER_FIRST_LAST_C, FIFO_USER_BITS_C*2,
115  ite(USER_MODE_C = TUSER_LAST_C, FIFO_USER_BITS_C,
116  ite(USER_MODE_C = TUSER_NORMAL_C, DATA_BYTES_C * FIFO_USER_BITS_C,
117  1)));
118 
119  -- Use SLAVE settings for strobe, dest and ID bit values
120  constant STRB_BITS_C : integer := ite(SLAVE_AXI_CONFIG_G.TSTRB_EN_C, DATA_BYTES_C, 0);
121  constant DEST_BITS_C : integer := SLAVE_AXI_CONFIG_G.TDEST_BITS_C;
122  constant ID_BITS_C : integer := SLAVE_AXI_CONFIG_G.TID_BITS_C;
123 
124  constant FIFO_BITS_C : integer := 1 + DATA_BITS_C + KEEP_BITS_C + FIFO_USER_TOT_C + STRB_BITS_C + DEST_BITS_C + ID_BITS_C;
125 
126 
127 
128  -- Convert record to slv
129  function iAxiToSlv (din : AxiStreamMasterType) return slv is
130  variable retValue : slv(FIFO_BITS_C-1 downto 0) := (others => '0');
131  variable i : integer := 0;
132  begin
133 
134  -- init, pass last
135  assignSlv(i, retValue, din.tLast);
136 
137  -- Pack data
138  assignSlv(i, retValue, din.tData(DATA_BITS_C-1 downto 0));
139 
140  -- Pack keep
141  if KEEP_MODE_C = TKEEP_NORMAL_C then
142  assignSlv(i, retValue, din.tKeep(KEEP_BITS_C-1 downto 0));
143  elsif KEEP_MODE_C = TKEEP_COMP_C then
144  assignSlv(i, retValue, toSlv(getTKeep(din.tKeep(DATA_BYTES_C-1 downto 1)), KEEP_BITS_C)); -- Assume lsb is present
145  end if;
146 
147  -- Pack user bits
148  if USER_MODE_C = TUSER_FIRST_LAST_C then
149  assignSlv(i, retValue, resize(axiStreamGetUserField(FIFO_AXIS_CONFIG_C, din, 0), FIFO_USER_BITS_C)); -- First byte
150  assignSlv(i, retValue, resize(axiStreamGetUserField(FIFO_AXIS_CONFIG_C, din, -1), FIFO_USER_BITS_C)); -- Last valid byte
151 
152  elsif USER_MODE_C = TUSER_LAST_C then
153  assignSlv(i, retValue, resize(axiStreamGetUserField(FIFO_AXIS_CONFIG_C, din, -1), FIFO_USER_BITS_C)); -- Last valid byte
154 
155  else
156  for j in 0 to DATA_BYTES_C-1 loop
157  assignSlv(i, retValue, resize(axiStreamGetUserField(FIFO_AXIS_CONFIG_C, din, j), FIFO_USER_BITS_C));
158  end loop;
159  end if;
160 
161  -- Strobe is optional
162  if STRB_BITS_C > 0 then
163  assignSlv(i, retValue, din.tStrb(STRB_BITS_C-1 downto 0));
164  end if;
165 
166  -- Dest is optional
167  if DEST_BITS_C > 0 then
168  assignSlv(i, retValue, din.tDest(DEST_BITS_C-1 downto 0));
169  end if;
170 
171  -- Id is optional
172  if ID_BITS_C > 0 then
173  assignSlv(i, retValue, din.tId(ID_BITS_C-1 downto 0));
174  end if;
175 
176  return(retValue);
177 
178  end function;
179 
180  -- Convert slv to record
181 - procedure iSlvToAxi (din : in slv(FIFO_BITS_C1 downto 0);
182  valid : in sl;
183  master : inout AxiStreamMasterType;
184  byteCnt : inout integer) is
185  variable i : integer := 0;
186  variable user : slv(FIFO_USER_BITS_C-1 downto 0) := (others => '0');
187  begin
188 
189  master := axiStreamMasterInit(MASTER_AXI_CONFIG_G);
190 
191  -- Set valid,
192  master.tValid := valid;
193 
194  -- Set last
195  assignRecord(i, din, master.tLast);
196 
197  -- Get data
198  assignRecord(i, din, master.tData(DATA_BITS_C-1 downto 0));
199 
200  -- Get keep bits
201  if KEEP_MODE_C = TKEEP_NORMAL_C then
202  assignRecord(i, din, master.tKeep(KEEP_BITS_C-1 downto 0));
203  byteCnt := getTKeep(master.tKeep);
204  elsif KEEP_MODE_C = TKEEP_COMP_C then
205  byteCnt := conv_integer(din((KEEP_BITS_C+i)-1 downto i))+1;
206  master.tKeep := genTKeep(byteCnt);
207  i := i + KEEP_BITS_C;
208  else -- KEEP_MODE_C = TKEEP_FIXED_C
209  master.tKeep := genTKeep(DATA_BYTES_C);
210  byteCnt := DATA_BYTES_C;
211  i := i + KEEP_BITS_C;
212  end if;
213 
214  -- get user bits
215  if USER_MODE_C = TUSER_FIRST_LAST_C then
216  assignRecord(i, din, user);
217  axiStreamSetUserField (MASTER_AXI_CONFIG_G, master, resize(user, MASTER_USER_BITS_C), 0); -- First byte
218 
219  assignRecord(i, din, user);
220  axiStreamSetUserField (MASTER_AXI_CONFIG_G, master, resize(user, MASTER_USER_BITS_C), -1); -- Last valid byte
221 
222  elsif USER_MODE_C = TUSER_LAST_C then
223  assignRecord(i, din, user);
224  axiStreamSetUserField (MASTER_AXI_CONFIG_G, master, resize(user, MASTER_USER_BITS_C), -1); -- Last valid byte
225 
226  else
227  for j in 0 to DATA_BYTES_C-1 loop
228  assignRecord(i, din, user);
229  axiStreamSetUserField (MASTER_AXI_CONFIG_G, master, resize(user, MASTER_USER_BITS_C), j);
230  end loop;
231  end if;
232 
233  -- Strobe is optional
234  if STRB_BITS_C > 0 then
235  assignRecord(i, din, master.tStrb(STRB_BITS_C-1 downto 0));
236  else
237  master.tStrb := master.tKeep; -- Strobe follows keep if unused
238  end if;
239 
240  -- Dest is optional
241  if DEST_BITS_C > 0 then
242  assignRecord(i, din, master.tDest(DEST_BITS_C-1 downto 0));
243  end if;
244 
245  -- ID is optional
246  if ID_BITS_C > 0 then
247  assignRecord(i, din, master.tId(ID_BITS_C-1 downto 0));
248  end if;
249 
250  end iSlvToAxi;
251 
252  ----------------
253  -- Write Signals
254  ----------------
255  constant WR_LOGIC_EN_C : boolean := (WR_BYTES_C < RD_BYTES_C);
256  constant WR_SIZE_C : integer := ite(WR_LOGIC_EN_C, RD_BYTES_C / WR_BYTES_C, 1);
257 
258  type WrRegType is record
259  count : slv(bitSize(WR_SIZE_C)-1 downto 0);
260  wrMaster : AxiStreamMasterType;
261  end record WrRegType;
262 
263  constant WR_REG_INIT_C : WrRegType := (
264  count => (others => '0'),
265  wrMaster => axiStreamMasterInit(SLAVE_AXI_CONFIG_G)
266  );
267 
268  signal wrR : WrRegType := WR_REG_INIT_C;
269  signal wrRin : WrRegType;
270 
271  ----------------
272  -- FIFO Signals
273  ----------------
274  signal fifoDin : slv(FIFO_BITS_C-1 downto 0);
275  signal fifoWrite : sl;
276  signal fifoWriteLast : sl;
277  signal fifoWriteUser : slv(FIFO_USER_TOT_C-1 downto 0);
278  signal fifoWrCount : slv(FIFO_ADDR_WIDTH_G-1 downto 0);
279  signal fifoRdCount : slv(FIFO_ADDR_WIDTH_G-1 downto 0);
280  signal fifoAFull : sl;
281  signal fifoReady : sl;
282  signal fifoPFull : sl;
283  signal fifoPFullVec : slv(CASCADE_SIZE_G-1 downto 0);
284  signal fifoDout : slv(FIFO_BITS_C-1 downto 0);
285  signal fifoRead : sl;
286  signal fifoReadLast : sl;
287  signal fifoReadUser : slv(FIFO_USER_TOT_C-1 downto 0) := (others => '0');
288  signal fifoValidInt : sl;
289  signal fifoValid : sl;
290  signal fifoValidLast : sl;
291  signal fifoInFrame : sl;
292 
293  ---------------
294  -- Read Signals
295  ---------------
296  constant RD_LOGIC_EN_C : boolean := (RD_BYTES_C < WR_BYTES_C);
297  constant RD_SIZE_C : integer := ite(RD_LOGIC_EN_C, WR_BYTES_C / RD_BYTES_C, 1);
298 
299  type RdRegType is record
300  count : slv(bitSize(RD_SIZE_C)-1 downto 0);
301  bytes : slv(bitSize(DATA_BYTES_C)-1 downto 0);
302  rdMaster : AxiStreamMasterType;
303  ready : sl;
304  end record RdRegType;
305 
306  constant RD_REG_INIT_C : RdRegType := (
307  count => (others => '0'),
308  bytes => conv_std_logic_vector(RD_BYTES_C, bitSize(DATA_BYTES_C)),
309  rdMaster => axiStreamMasterInit(MASTER_AXI_CONFIG_G),
310  ready => '0'
311  );
312 
313  signal rdR : RdRegType := RD_REG_INIT_C;
314  signal rdRin : RdRegType;
315 
316  ---------------
317  -- Sync Signals
318  ---------------
319  signal axisMaster : AxiStreamMasterType;
320  signal axisSlave : AxiStreamSlaveType;
321 
322  ---------------
323  -- Debug Signals
324  ---------------
325 
326 begin
327 
330  or
333  report "Data widths must be even number multiples of each other" severity failure;
334 
335  -- Cant use tkeep_fixed on master side when resizing or if not on slave side
336  assert (not (MASTER_AXI_CONFIG_G.TKEEP_MODE_C = TKEEP_FIXED_C and
337  SLAVE_AXI_CONFIG_G.TKEEP_MODE_C /= TKEEP_FIXED_C))
338  report "AxiStreamFifo: Can't have TKEEP_MODE = TKEEP_FIXED on master side if not on slave side"
339  severity error;
340 
341  -------------------------
342  -- Write Logic
343  -------------------------
344  wrComb : process (fifoReady, sAxisMaster, wrR) is
345  variable v : WrRegType;
346  variable idx : integer;
347  begin
348  v := wrR;
349  idx := conv_integer(wrR.count);
350 
351  -- Advance pipeline
352  if fifoReady = '1' then
353 
354  -- init when count = 0
355  if (wrR.count = 0) then
356  v.wrMaster.tKeep := (others => '0');
357  v.wrMaster.tData := (others => '0');
358  v.wrMaster.tStrb := (others => '0');
359  v.wrMaster.tUser := (others => '0');
360  end if;
361 
362  v.wrMaster.tData((WR_BYTES_C*8*idx)+((WR_BYTES_C*8)-1) downto (WR_BYTES_C*8*idx)) := sAxisMaster.tData((WR_BYTES_C*8)-1 downto 0);
363  v.wrMaster.tStrb((WR_BYTES_C*idx)+(WR_BYTES_C-1) downto (WR_BYTES_C*idx)) := sAxisMaster.tStrb(WR_BYTES_C-1 downto 0);
364  v.wrMaster.tKeep((WR_BYTES_C*idx)+(WR_BYTES_C-1) downto (WR_BYTES_C*idx)) := sAxisMaster.tKeep(WR_BYTES_C-1 downto 0);
365 
366  v.wrMaster.tUser((WR_BYTES_C*SLAVE_USER_BITS_C*idx)+((WR_BYTES_C*SLAVE_USER_BITS_C)-1) downto (WR_BYTES_C*SLAVE_USER_BITS_C*idx))
367  := sAxisMaster.tUser((WR_BYTES_C*SLAVE_USER_BITS_C)-1 downto 0);
368 
369  v.wrMaster.tDest := sAxisMaster.tDest;
370  v.wrMaster.tId := sAxisMaster.tId;
371  v.wrMaster.tLast := sAxisMaster.tLast;
372 
373  -- Determine end mode, valid and ready
374  if sAxisMaster.tValid = '1' then
375  if (wrR.count = (WR_SIZE_C-1) or sAxisMaster.tLast = '1') then
376  v.wrMaster.tValid := '1';
377  v.count := (others => '0');
378  else
379  v.wrMaster.tValid := '0';
380  v.count := wrR.count + 1;
381  end if;
382  else
383  v.wrMaster.tValid := '0';
384  end if;
385  end if;
386 
387  wrRin <= v;
388 
389  -- Write logic enabled
390  if WR_LOGIC_EN_C then
391  fifoDin <= iAxiToSlv(wrR.wrMaster);
392  fifoWrite <= wrR.wrMaster.tValid and fifoReady;
393  fifoWriteLast <= wrR.wrMaster.tValid and fifoReady and wrR.wrMaster.tLast;
394  fifoWriteUser <= wrR.wrMaster.tUser(FIFO_USER_TOT_C-1 downto 0);
395  -- Bypass write logic
396  else
397  fifoDin <= iAxiToSlv(sAxisMaster);
398  fifoWrite <= sAxisMaster.tValid and fifoReady;
399  fifoWriteLast <= sAxisMaster.tValid and fifoReady and sAxisMaster.tLast;
400  fifoWriteUser <= sAxisMaster.tUser(FIFO_USER_TOT_C-1 downto 0);
401  end if;
402 
403  sAxisSlave.tReady <= fifoReady;
404 
405  end process wrComb;
406 
407  wrSeq : process (sAxisClk) is
408  begin
409  if (rising_edge(sAxisClk)) then
410  if sAxisRst = '1' or WR_LOGIC_EN_C = false then
411  wrR <= WR_REG_INIT_C after TPD_G;
412  else
413  wrR <= wrRin after TPD_G;
414  end if;
415  end if;
416  end process wrSeq;
417 
418 
419  -------------------------
420  -- FIFO
421  -------------------------
422 
423  -- Pause generation
424  process (fifoPFullVec, sAxisClk) is
425  begin
426  if FIFO_FIXED_THRESH_G then
427  sAxisCtrl.pause <= fifoPFullVec(CASCADE_PAUSE_SEL_G) after TPD_G;
428  elsif (rising_edge(sAxisClk)) then
429  if sAxisRst = '1' or fifoWrCount >= fifoPauseThresh then
430  sAxisCtrl.pause <= '1' after TPD_G;
431  else
432  sAxisCtrl.pause <= '0' after TPD_G;
433  end if;
434  end if;
435  end process;
436 
437  -- Is ready enabled?
438  fifoReady <= (not fifoAFull) when SLAVE_READY_EN_G else '1';
439 
440  U_Fifo : entity work.FifoCascade
441  generic map (
442  TPD_G => TPD_G,
444  LAST_STAGE_ASYNC_G => true,
446  RST_POLARITY_G => '1',
447  RST_ASYNC_G => false,
449  BRAM_EN_G => BRAM_EN_G,
450  FWFT_EN_G => true,
451  USE_DSP48_G => "no",
456  SYNC_STAGES_G => 3,
457  DATA_WIDTH_G => FIFO_BITS_C,
459  INIT_G => "0",
461  EMPTY_THRES_G => 1
462  )
463  port map (
464  rst => sAxisRst,
465  wr_clk => sAxisClk,
466  wr_en => fifoWrite,
467  din => fifoDin,
468  wr_data_count => fifoWrCount,
469  wr_ack => open,
470  overflow => sAxisCtrl.overflow,
471  prog_full => fifoPFull,
472  progFullVec => fifoPFullVec,
473  almost_full => fifoAFull,
474  full => open,
475  not_full => open,
476  rd_clk => mAxisClk,
477  rd_en => fifoRead,
478  dout => fifoDout,
479  rd_data_count => fifoRdCount,
480  valid => fifoValidInt,
481  underflow => open,
482  prog_empty => open,
483  almost_empty => open,
484  empty => open
485  );
486 
487  U_LastFifoEnGen : if VALID_THOLD_G /= 1 generate
488 
489  U_LastFifo : entity work.FifoCascade
490  generic map (
491  TPD_G => TPD_G,
493  LAST_STAGE_ASYNC_G => true,
495  RST_POLARITY_G => '1',
496  RST_ASYNC_G => false,
498  BRAM_EN_G => false,
499  FWFT_EN_G => true,
500  USE_DSP48_G => "no",
503  USE_BUILT_IN_G => false,
505  SYNC_STAGES_G => 3,
506  DATA_WIDTH_G => FIFO_USER_TOT_C,
507  ADDR_WIDTH_G => LAST_FIFO_ADDR_WIDTH_C,
508  INIT_G => "0",
509  FULL_THRES_G => 1,
510  EMPTY_THRES_G => 1
511  )
512  port map (
513  rst => sAxisRst,
514  wr_clk => sAxisClk,
515  wr_en => fifoWriteLast,
516  din => fifoWriteUser(FIFO_USER_TOT_C-1 downto 0),
517  wr_data_count => open,
518  wr_ack => open,
519  overflow => open,
520  prog_full => open,
521  almost_full => open,
522  full => open,
523  not_full => open,
524  rd_clk => mAxisClk,
525  rd_en => fifoReadLast,
526  dout => fifoReadUser(FIFO_USER_TOT_C-1 downto 0),
527  rd_data_count => open,
528  valid => fifoValidLast,
529  underflow => open,
530  prog_empty => open,
531  almost_empty => open,
532  empty => open
533  );
534 
535  process (mAxisClk) is
536  begin
537  if (rising_edge(mAxisClk)) then
538  if mAxisRst = '1' or fifoReadLast = '1' then
539  fifoInFrame <= '0' after TPD_G;
540  elsif fifoValidLast = '1' or (VALID_THOLD_G /= 0 and fifoRdCount >= VALID_THOLD_G) then
541  fifoInFrame <= '1' after TPD_G;
542  end if;
543  end if;
544  end process;
545 
546  fifoValid <= fifoValidInt and fifoInFrame;
547 
548  end generate;
549 
550  U_LastFifoDisGen : if VALID_THOLD_G = 1 generate
551  fifoValidLast <= '0';
552  fifoValid <= fifoValidInt;
553  fifoInFrame <= '0';
554  end generate;
555 
556  mTLastTUser(FIFO_USER_TOT_C-1 downto 0) <= fifoReadUser;
557 
558  -------------------------
559  -- Read Logic
560  -------------------------
561 
562  rdComb : process (axisSlave, fifoDout, fifoValid, rdR) is
563  variable v : RdRegType;
564  variable idx : integer;
565  variable byteCnt : integer;
566  variable fifoMaster : AxiStreamMasterType;
567  begin
568  v := rdR;
569  idx := conv_integer(rdR.count);
570 
571  iSlvToAxi (fifoDout, fifoValid, fifoMaster, byteCnt);
572 
573  -- Advance pipeline
574  if axisSlave.tReady = '1' or rdR.rdMaster.tValid = '0' then
575  v.rdMaster := axiStreamMasterInit(MASTER_AXI_CONFIG_G);
576 
577  v.rdMaster.tData((RD_BYTES_C*8)-1 downto 0) := fifoMaster.tData((RD_BYTES_C*8*idx)+((RD_BYTES_C*8)-1) downto (RD_BYTES_C*8*idx));
578  v.rdMaster.tStrb(RD_BYTES_C-1 downto 0) := fifoMaster.tStrb((RD_BYTES_C*idx)+(RD_BYTES_C-1) downto (RD_BYTES_C*idx));
579  v.rdMaster.tKeep(RD_BYTES_C-1 downto 0) := fifoMaster.tKeep((RD_BYTES_C*idx)+(RD_BYTES_C-1) downto (RD_BYTES_C*idx));
580 
581  v.rdMaster.tUser((RD_BYTES_C*MASTER_USER_BITS_C)-1 downto 0)
582  := fifoMaster.tUser((RD_BYTES_C*MASTER_USER_BITS_C*idx)+((RD_BYTES_C*MASTER_USER_BITS_C)-1) downto (RD_BYTES_C*MASTER_USER_BITS_C*idx));
583 
584  v.rdMaster.tDest := fifoMaster.tDest;
585  v.rdMaster.tId := fifoMaster.tId;
586 
587  -- Reached end of fifo data or no more valid bytes in last word
588  if fifoMaster.tValid = '1' then
589  if (rdR.count = (RD_SIZE_C-1)) or ((rdR.bytes >= byteCnt) and (fifoMaster.tLast = '1')) then
590  v.count := (others => '0');
591  v.bytes := conv_std_logic_vector(RD_BYTES_C, bitSize(DATA_BYTES_C));
592  v.ready := '1';
593  v.rdMaster.tLast := fifoMaster.tLast;
594  else
595  v.count := rdR.count + 1;
596  v.bytes := rdR.bytes + RD_BYTES_C;
597  v.ready := '0';
598  v.rdMaster.tLast := '0';
599  end if;
600  end if;
601 
602  -- Drop transfers with no tKeep bits set, except on tLast
603  v.rdMaster.tValid := fifoMaster.tValid and
604  (uOr(v.rdMaster.tKeep(RD_BYTES_C-1 downto 0)) or
605  v.rdMaster.tLast);
606 
607  else
608  v.ready := '0';
609  end if;
610 
611  rdRin <= v;
612 
613  -- Read logic enabled
614  if RD_LOGIC_EN_C then
615  axisMaster <= rdR.rdMaster;
616  fifoRead <= v.ready and fifoValid;
617  fifoReadLast <= v.ready and fifoValid and fifoMaster.tLast;
618 
619  -- Bypass read logic
620  else
621  axisMaster <= fifoMaster;
622  fifoRead <= axisSlave.tReady and fifoValid;
623  fifoReadLast <= axisSlave.tReady and fifoValid and fifoMaster.tLast;
624  end if;
625 
626  end process rdComb;
627 
628  -- If fifo is asynchronous, must use async reset on rd side.
629  rdSeq : process (mAxisClk) is
630  begin
631  if (rising_edge(mAxisClk)) then
632  if mAxisRst = '1' or RD_LOGIC_EN_C = false then
633  rdR <= RD_REG_INIT_C after TPD_G;
634  else
635  rdR <= rdRin after TPD_G;
636  end if;
637  end if;
638  end process rdSeq;
639 
640  -- Synchronize master side tvalid back to slave side ctrl.idle
641  -- This is a total hack
642  Synchronizer_1 : entity work.Synchronizer
643  generic map (
644  TPD_G => TPD_G,
645  OUT_POLARITY_G => '0') -- invert
646  port map (
647  clk => sAxisClk,
648  rst => sAxisRst,
649  dataIn => axisMaster.tValid,
650  dataOut => sAxisCtrl.idle);
651 
652 
653  -------------------------
654  -- Pipeline Logic
655  -------------------------
656 
657  U_Pipe : entity work.AxiStreamPipeline
658  generic map (
659  TPD_G => TPD_G,
661  )
662  port map (
663  -- Clock and Reset
664  axisClk => mAxisClk,
665  axisRst => mAxisRst,
666  -- Slave Port
667  sAxisMaster => axisMaster,
668  sAxisSlave => axisSlave,
669  -- Master Port
672 
673 end rtl;
674 
675 
FIFO_ADDR_WIDTH_Ginteger range 4 to 48:= 9
out almost_fullsl
Definition: FifoCascade.vhd:59
slv( 7 downto 0) tId
ALTERA_RAM_Gstring := "M9K"
Definition: FifoCascade.vhd:38
out validsl
Definition: FifoCascade.vhd:68
out progFullVecslv( CASCADE_SIZE_G- 1 downto 0)
Definition: FifoCascade.vhd:62
PIPE_STAGES_Gnatural range 0 to 16:= 0
FIFO_FIXED_THRESH_Gboolean := true
natural range 0 to 8 TDEST_BITS_C
out doutslv( DATA_WIDTH_G- 1 downto 0)
Definition: FifoCascade.vhd:66
(TUSER_NORMAL_C,TUSER_FIRST_LAST_C,TUSER_LAST_C,TUSER_NONE_C) TUserModeType
in sAxisMasterAxiStreamMasterType
XIL_DEVICE_Gstring := "7SERIES"
Definition: FifoCascade.vhd:40
CASCADE_SIZE_Ginteger range 1 to ( 2** 24):= 1
RST_ASYNC_Gboolean := false
Definition: FifoCascade.vhd:32
out almost_emptysl
Definition: FifoCascade.vhd:71
INIT_Gslv := "0"
Definition: FifoCascade.vhd:45
std_logic sl
Definition: StdRtlPkg.vhd:28
in rstsl :=not RST_POLARITY_G
SLAVE_READY_EN_Gboolean := true
BRAM_EN_Gboolean := true
Definition: FifoCascade.vhd:34
MASTER_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
BRAM_EN_Gboolean := true
in dinslv( DATA_WIDTH_G- 1 downto 0)
Definition: FifoCascade.vhd:54
out sAxisSlaveAxiStreamSlaveType
slv( 15 downto 0) tStrb
slv( 15 downto 0) tKeep
SLAVE_AXI_CONFIG_GAxiStreamConfigType := AXI_STREAM_CONFIG_INIT_C
VALID_THOLD_Ginteger range 0 to ( 2** 24):= 1
USE_BUILT_IN_Gboolean := false
CASCADE_PAUSE_SEL_Ginteger range 0 to ( 2** 24):= 0
natural range 1 to 16 TDATA_BYTES_C
in mAxisSlaveAxiStreamSlaveType
in rd_clksl
Definition: FifoCascade.vhd:64
out prog_fullsl
Definition: FifoCascade.vhd:58
INT_PIPE_STAGES_Gnatural range 0 to 16:= 0
PIPE_STAGES_Gnatural range 0 to 16:= 0
Definition: FifoCascade.vhd:42
EMPTY_THRES_Ginteger range 1 to ( 2** 24):= 1
Definition: FifoCascade.vhd:47
out mAxisMasterAxiStreamMasterType
ALTERA_SYN_Gboolean := false
Definition: FifoCascade.vhd:37
TkeepModeType TKEEP_MODE_C
out dataOutsl
in rd_ensl := '0'
Definition: FifoCascade.vhd:65
out wr_acksl
Definition: FifoCascade.vhd:56
natural range 0 to 8 TID_BITS_C
in rstsl := '0'
Definition: FifoCascade.vhd:50
slv( 127 downto 0) tData
in wr_clksl
Definition: FifoCascade.vhd:52
out overflowsl
Definition: FifoCascade.vhd:57
out sAxisSlaveAxiStreamSlaveType
FULL_THRES_Ginteger range 1 to ( 2** 24):= 1
Definition: FifoCascade.vhd:46
in sAxisMasterAxiStreamMasterType
SYNC_STAGES_Ginteger range 3 to ( 2** 24):= 3
Definition: FifoCascade.vhd:41
FIFO_PAUSE_THRESH_Ginteger range 1 to ( 2** 24):= 1
LAST_FIFO_ADDR_WIDTH_Ginteger range 0 to 48:= 0
out mTLastTUserslv( 127 downto 0)
boolean TSTRB_EN_C
TPD_Gtime := 1 ns
TUserModeType TUSER_MODE_C
slv( 127 downto 0) tUser
in wr_ensl := '0'
Definition: FifoCascade.vhd:53
out fullsl
Definition: FifoCascade.vhd:60
OUT_POLARITY_Gsl := '1'
natural range 0 to 8 TUSER_BITS_C
out mAxisMasterAxiStreamMasterType
GEN_SYNC_FIFO_Gboolean := false
Definition: FifoCascade.vhd:33
AxiStreamConfigType :=(TSTRB_EN_C => false,TDATA_BYTES_C => 16,TDEST_BITS_C => 4,TID_BITS_C => 0,TKEEP_MODE_C => TKEEP_NORMAL_C,TUSER_BITS_C => 4,TUSER_MODE_C => TUSER_NORMAL_C) AXI_STREAM_CONFIG_INIT_C
TPD_Gtime := 1 ns
Definition: FifoCascade.vhd:28
slv( 7 downto 0) tDest
GEN_SYNC_FIFO_Gboolean := false
(TKEEP_NORMAL_C,TKEEP_COMP_C,TKEEP_FIXED_C) TKeepModeType
in mAxisSlaveAxiStreamSlaveType
USE_DSP48_Gstring := "no"
Definition: FifoCascade.vhd:36
LAST_STAGE_ASYNC_Gboolean := true
Definition: FifoCascade.vhd:30
ALTERA_RAM_Gstring := "M9K"
ADDR_WIDTH_Ginteger range 4 to 48:= 4
Definition: FifoCascade.vhd:44
in fifoPauseThreshslv( FIFO_ADDR_WIDTH_G- 1 downto 0) :=( others => '1')
XIL_DEVICE_Gstring := "7SERIES"
TPD_Gtime := 1 ns
USE_BUILT_IN_Gboolean := false
Definition: FifoCascade.vhd:39
FWFT_EN_Gboolean := false
Definition: FifoCascade.vhd:35
out not_fullsl
Definition: FifoCascade.vhd:61
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
Definition: FifoCascade.vhd:43
out emptysl
Definition: FifoCascade.vhd:72
out underflowsl
Definition: FifoCascade.vhd:69
CASCADE_SIZE_Ginteger range 1 to ( 2** 24):= 1
Definition: FifoCascade.vhd:29
out prog_emptysl
Definition: FifoCascade.vhd:70
out wr_data_countslv( ADDR_WIDTH_G- 1 downto 0)
Definition: FifoCascade.vhd:55
PIPE_STAGES_Gnatural range 0 to 16:= 1
out sAxisCtrlAxiStreamCtrlType
RST_POLARITY_Gsl := '1'
Definition: FifoCascade.vhd:31
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
out rd_data_countslv( ADDR_WIDTH_G- 1 downto 0)
Definition: FifoCascade.vhd:67
ALTERA_SYN_Gboolean := false