SURF  1.0
FifoSyncBuiltIn.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 -- File : FifoAsyncBuiltIn.vhd
3 -- Company : SLAC National Accelerator Laboratory
4 -- Created : 2013-07-28
5 -- Last update: 2014-07-14
6 -------------------------------------------------------------------------------
7 -- Description: Wrapper for Xilinx's built-in SYNC FIFO module
8 -------------------------------------------------------------------------------
9 -- This file is part of 'SLAC Firmware Standard Library'.
10 -- It is subject to the license terms in the LICENSE.txt file found in the
11 -- top-level directory of this distribution and at:
12 -- https://confluence.slac.stanford.edu/display/ppareg/LICENSE.html.
13 -- No part of 'SLAC Firmware Standard Library', including this file,
14 -- may be copied, modified, propagated, or distributed except according to
15 -- the terms contained in the LICENSE.txt file.
16 -------------------------------------------------------------------------------
17 
18 library ieee;
19 use ieee.std_logic_1164.all;
20 use ieee.std_logic_unsigned.all;
21 use ieee.std_logic_arith.all;
22 
23 use work.StdRtlPkg.all;
24 
25 library UNISIM;
26 use UNISIM.vcomponents.all;
27 
28 library UNIMACRO;
29 use UNIMACRO.vcomponents.all;
30 
31 --! @see entity
32  --! @ingroup base_fifo
33 entity FifoSyncBuiltIn is
34  generic (
35  TPD_G : time := 1 ns;
36  RST_POLARITY_G : sl := '1'; -- '1' for active high rst, '0' for active low
37  FWFT_EN_G : boolean := false;
38  USE_DSP48_G : string := "no";
39  XIL_DEVICE_G : string := "7SERIES"; -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES"
40  PIPE_STAGES_G : natural range 0 to 16 := 0;
41  DATA_WIDTH_G : integer range 1 to 72 := 18;
42  ADDR_WIDTH_G : integer range 9 to 13 := 10;
43  FULL_THRES_G : integer range 1 to 8190 := 1;
44  EMPTY_THRES_G : integer range 1 to 8190 := 1);
45  port (
46  rst : in sl := '0';
47  clk : in sl;
48  wr_en : in sl;
49  rd_en : in sl;
50  din : in slv(DATA_WIDTH_G-1 downto 0);
51  dout : out slv(DATA_WIDTH_G-1 downto 0);
52  data_count : out slv(ADDR_WIDTH_G-1 downto 0);
53  wr_ack : out sl;
54  valid : out sl;
55  overflow : out sl;
56  underflow : out sl;
57  prog_full : out sl;
58  prog_empty : out sl;
59  almost_full : out sl;
61  not_full : out sl;
62  full : out sl;
63  empty : out sl);
64 end FifoSyncBuiltIn;
65 
66 architecture mapping of FifoSyncBuiltIn is
67 
68  function GetFifoType (d_width : in integer; a_width : in integer) return string is
69  begin
70  if ((d_width >= 37) and (d_width <= 72) and (a_width = 9)) then
71  return "36Kb";
72  elsif ((d_width >= 19) and (d_width <= 36) and (a_width = 10)) then
73  return "36Kb";
74  elsif ((d_width >= 19) and (d_width <= 36) and (a_width = 9)) then
75  return "18Kb";
76  elsif ((d_width >= 10) and (d_width <= 18) and (a_width = 11)) then
77  return "36Kb";
78  elsif ((d_width >= 10) and (d_width <= 18) and (a_width = 10)) then
79  return "18Kb";
80  elsif ((d_width >= 5) and (d_width <= 9) and (a_width = 12)) then
81  return "36Kb";
82  elsif ((d_width >= 5) and (d_width <= 9) and (a_width = 11)) then
83  return "18Kb";
84  elsif ((d_width >= 1) and (d_width <= 4) and (a_width = 13)) then
85  return "36Kb";
86  elsif ((d_width >= 1) and (d_width <= 4) and (a_width = 12)) then
87  return "18Kb";
88  else
89  return "???Kb"; -- Generate error in Xilinx marco
90  end if;
91  end;
92 
93  constant FIFO_LENGTH_C : integer := ((2**ADDR_WIDTH_G)- 1);
94  constant ALMOST_FULL_OFFSET_C : bit_vector := to_bitvector(toSlv((FIFO_LENGTH_C-FULL_THRES_G), 16));
95  constant ALMOST_EMPTY_OFFSET_C : bit_vector := to_bitvector(toSlv(EMPTY_THRES_G, 16));
96  constant FIFO_SIZE_C : string := GetFifoType(DATA_WIDTH_G, ADDR_WIDTH_G);
97 
99  record
103  end record;
105  prog_empty => '1',
106  almost_empty => '1',
107  empty => '1');
109 
110  signal wrAddrPntr,
111  rdAddrPntr,
112  cnt : slv(ADDR_WIDTH_G-1 downto 0) := (others => '0');
113  signal buildInFull,
114  buildInEmpty,
115  progEmpty,
116  progFull,
117  readEnable,
118  rstFlags,
119  fifoRst,
120  wrEn,
121  dummyWRERR,
122  sValid,
123  sRdEn,
124  rstDet : sl := '0';
125 
126  signal dataOut : slv(DATA_WIDTH_G-1 downto 0);
127 
128  -- Attribute for XST
129  attribute use_dsp48 : string;
130  attribute use_dsp48 of cnt : signal is USE_DSP48_G;
131 
132 begin
133 
134  -- Check ADDR_WIDTH_G and DATA_WIDTH_G when USE_BUILT_IN_G = true
135  assert (((DATA_WIDTH_G >= 37) and (DATA_WIDTH_G <= 72) and (ADDR_WIDTH_G = 9))
136  or ((DATA_WIDTH_G >= 19) and (DATA_WIDTH_G <= 36) and (ADDR_WIDTH_G = 10))
137  or ((DATA_WIDTH_G >= 19) and (DATA_WIDTH_G <= 36) and (ADDR_WIDTH_G = 9))
138  or ((DATA_WIDTH_G >= 10) and (DATA_WIDTH_G <= 18) and (ADDR_WIDTH_G = 11))
139  or ((DATA_WIDTH_G >= 10) and (DATA_WIDTH_G <= 18) and (ADDR_WIDTH_G = 10))
140  or ((DATA_WIDTH_G >= 5) and (DATA_WIDTH_G <= 9) and (ADDR_WIDTH_G = 12))
141  or ((DATA_WIDTH_G >= 5) and (DATA_WIDTH_G <= 9) and (ADDR_WIDTH_G = 11))
142  or ((DATA_WIDTH_G >= 1) and (DATA_WIDTH_G <= 4) and (ADDR_WIDTH_G = 13))
143  or ((DATA_WIDTH_G >= 1) and (DATA_WIDTH_G <= 4) and (ADDR_WIDTH_G = 12)))
144  report "Invalid DATA_WIDTH_G or ADDR_WIDTH_G for built-in FIFO configuration"
145  severity failure;
146  -----------------------------------------------------------------
147  -- DATA_WIDTH | FIFO_SIZE | FIFO Depth | RDCOUNT/WRCOUNT Width --
148  -- ===========|===========|============|=======================--
149  -- 37-72 | "36Kb" | 512 | 9-bit --
150  -- 19-36 | "36Kb" | 1024 | 10-bit --
151  -- 19-36 | "18Kb" | 512 | 9-bit --
152  -- 10-18 | "36Kb" | 2048 | 11-bit --
153  -- 10-18 | "18Kb" | 1024 | 10-bit --
154  -- 5-9 | "36Kb" | 4096 | 12-bit --
155  -- 5-9 | "18Kb" | 2048 | 11-bit --
156  -- 1-4 | "36Kb" | 8192 | 13-bit --
157  -- 1-4 | "18Kb" | 4096 | 12-bit --
158  -----------------------------------------------------------------
159  -- FULL_THRES_G upper range check
160  assert (FULL_THRES_G <= ((2**ADDR_WIDTH_G)-2))
161  report "FULL_THRES_G must be <= ((2**ADDR_WIDTH_G)-2)"
162  severity failure;
163  -- EMPTY_THRES_G upper range check
164  assert (EMPTY_THRES_G <= ((2**ADDR_WIDTH_G)-2))
165  report "EMPTY_THRES_G must be <= ((2**ADDR_WIDTH_G)-2)"
166  severity failure;
167  -- USE_DSP48_G check
168  assert ((USE_DSP48_G = "yes") or (USE_DSP48_G = "no") or (USE_DSP48_G = "auto") or (USE_DSP48_G = "automax"))
169  report "USE_DSP48_G must be either yes, no, auto, or automax"
170  severity failure;
171 
172  RstSync_FULL : entity work.RstSync
173  generic map (
174  TPD_G => TPD_G,
176  RELEASE_DELAY_G => 10)
177  port map (
178  clk => clk,
179  asyncRst => rst,
180  syncRst => rstFlags);
181 
182  SynchronizerEdge_FULL : entity work.SynchronizerEdge
183  generic map (
184  TPD_G => TPD_G)
185  port map (
186  clk => clk,
187  dataIn => rstFlags,
188  risingEdge => rstDet);
189 
190  RstSync_FIFO : entity work.RstSync
191  generic map (
192  TPD_G => TPD_G,
193  RELEASE_DELAY_G => 6)
194  port map (
195  clk => clk,
196  asyncRst => rstDet,
197  syncRst => fifoRst);
198 
199  FIFO_SYNC_MACRO_Inst : FIFO_SYNC_MACRO
200  generic map (
201  DO_REG => 0, --DO_REG must be set to 0 for flags and data to follow a standard synchronous FIFO operation
202  DEVICE => XIL_DEVICE_G, -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES"
203  ALMOST_FULL_OFFSET => ALMOST_FULL_OFFSET_C, -- Sets almost full threshold
204  ALMOST_EMPTY_OFFSET => ALMOST_EMPTY_OFFSET_C, -- Sets the almost empty threshold
205  DATA_WIDTH => DATA_WIDTH_G, -- Valid values are 1-72 (37-72 only valid when FIFO_SIZE="36Kb")
206  FIFO_SIZE => FIFO_SIZE_C) -- Target BRAM, "18Kb" or "36Kb"
207  port map (
208  RST => fifoRst, -- 1-bit input reset
209  CLK => clk, -- 1-bit input clock
210  WREN => wrEn, -- 1-bit input write enable
211  RDEN => readEnable, -- 1-bit input read enable
212  DI => din, -- Input data, width defined by DATA_WIDTH parameter
213  DO => dataOut, -- Output data, width defined by DATA_WIDTH parameter
214  RDCOUNT => rdAddrPntr, -- Output read count, width determined by FIFO depth
215  WRCOUNT => wrAddrPntr, -- Output write count, width determined by FIFO depth
216  WRERR => dummyWRERR, -- 1-bit output write error
217  RDERR => underflow, -- 1-bit output read error
218  ALMOSTFULL => progFull, -- 1-bit output almost full
219  ALMOSTEMPTY => progEmpty, -- 1-bit output almost empty
220  FULL => buildInFull, -- 1-bit output full
221  EMPTY => buildInEmpty); -- 1-bit output empty
222 
223  -- Calculate data count
225  data_count <= cnt;
226 
227  -- Write signals
228  wrEn <= wr_en and not(rstFlags) and not(buildInFull);
229  full <= buildInFull or rstFlags;
230  not_full <= not(buildInFull or rstFlags);
232  almost_full <= '1' when (cnt = (FIFO_LENGTH_C-1)) else (buildInFull or rstFlags);
233 
234  process(clk)
235  begin
236  if rising_edge(clk) then
237  wr_ack <= '0' after TPD_G;
238  if wr_en = '1' then
239  wr_ack <= not(buildInFull) after TPD_G;
240  end if;
241  end if;
242  end process;
243 
244  process(clk)
245  begin
246  if rising_edge(clk) then
247  overflow <= '0' after TPD_G;
248  if (wr_en = '1') and (buildInFull = '1') then
249  overflow <= '1' after TPD_G; -- Error strobe
250  end if;
251  end if;
252  end process;
253 
254  -- Read signals
256  fifoStatus.almost_empty <= '1' when (cnt = 1) else (buildInEmpty or rstFlags);
258 
259  FIFO_Gen : if (FWFT_EN_G = false) generate
260  readEnable <= rd_en;
264  dout <= dataOut;
265 
266  process(clk)
267  begin
268  if rising_edge(clk) then
269  valid <= '0' after TPD_G;
270  if rd_en = '1' then
271  valid <= not(buildInEmpty) after TPD_G;
272  end if;
273  end if;
274  end process;
275 
276  end generate;
277 
278  FWFT_Gen : if (FWFT_EN_G = true) generate
279 
280  FifoOutputPipeline_Inst : entity work.FifoOutputPipeline
281  generic map (
282  TPD_G => TPD_G,
286  port map (
287  -- Slave Port
288  sData => dataOut,
289  sValid => sValid,
290  sRdEn => sRdEn,
291  -- Master Port
292  mData => dout,
293  mValid => valid,
294  mRdEn => rd_en,
295  -- Clock and Reset
296  clk => clk,
297  rst => rst);
298 
299  readEnable <= (sRdEn or fwftStatus.empty) and not(fifoStatus.empty);
300  sValid <= not(fwftStatus.empty);
301 
305  process (clk) is
306  begin
307  if rising_edge(clk) then
308  if rstFlags = '1'then
310  else
314  end if;
315  end if;
316  end process;
317  end generate;
318 
319 end architecture mapping;
out syncRstsl
Definition: RstSync.vhd:36
IN_POLARITY_Gsl := '1'
Definition: RstSync.vhd:28
std_logic sl
Definition: StdRtlPkg.vhd:28
_library_ ieeeieee
Definition: FifoSync.vhd:18
bit_vector := to_bitvector(toSlv(( FIFO_LENGTH_C- FULL_THRES_G), 16) ) ALMOST_FULL_OFFSET_C
string GetFifoTyped_width,a_width,
out doutslv( DATA_WIDTH_G- 1 downto 0)
in asyncRstsl
Definition: RstSync.vhd:35
ADDR_WIDTH_Ginteger range 9 to 13:= 10
PIPE_STAGES_Gnatural range 0 to 16:= 0
ReadStatusType :=(prog_empty => '1',almost_empty => '1',empty => '1') READ_STATUS_INIT_C
in clksl
Definition: RstSync.vhd:34
FWFT_EN_Gboolean := false
RELEASE_DELAY_Ginteger range 3 to positive'high:= 3
Definition: RstSync.vhd:31
slv( DATA_WIDTH_G- 1 downto 0) dataOut
in dinslv( DATA_WIDTH_G- 1 downto 0)
out data_countslv( ADDR_WIDTH_G- 1 downto 0)
FULL_THRES_Ginteger range 1 to 8190:= 1
XIL_DEVICE_Gstring := "7SERIES"
RST_POLARITY_Gsl := '1'
EMPTY_THRES_Ginteger range 1 to 8190:= 1
ReadStatusType := READ_STATUS_INIT_C fifoStatus
DATA_WIDTH_Ginteger range 1 to 72:= 18
TPD_Gtime := 1 ns
Definition: RstSync.vhd:27
integer :=(( 2** ADDR_WIDTH_G)- 1) FIFO_LENGTH_C
slv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0') wrAddrPntr
in rstsl :=not RST_POLARITY_G
PIPE_STAGES_Gnatural range 0 to 16:= 1
ReadStatusType := READ_STATUS_INIT_C fwftStatus
string := GetFifoType( DATA_WIDTH_G, ADDR_WIDTH_G) FIFO_SIZE_C
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
in sDataslv( DATA_WIDTH_G- 1 downto 0)
TPD_Gtime := 1 ns
out mDataslv( DATA_WIDTH_G- 1 downto 0)
USE_DSP48_Gstring := "no"
std_logic_vector slv
Definition: StdRtlPkg.vhd:29
slv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0') rdAddrPntr
bit_vector := to_bitvector(toSlv( EMPTY_THRES_G, 16) ) ALMOST_EMPTY_OFFSET_C
slv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0') cnt