1 ------------------------------------------------------------------------------- 3 -- Company : SLAC National Accelerator Laboratory 4 -- Created : 2013-07-10 5 -- Last update: 2016-10-27 6 ------------------------------------------------------------------------------- 7 -- Description: 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 ------------------------------------------------------------------------------- 19 use ieee.std_logic_1164.
all;
20 use ieee.std_logic_arith.
all;
21 use ieee.std_logic_unsigned.
all;
26 --! @ingroup base_fifo 79 signal portA, portB : RamPortType;
81 type ReadStatusType is 87 constant READ_STATUS_INIT_C : ReadStatusType := ( 91 signal fifoStatus, fwftStatus : ReadStatusType := READ_STATUS_INIT_C;
99 signal overflowStatus : sl;
100 signal underflowStatus : sl;
101 signal fullStatus : sl;
102 signal readEnable : sl;
103 signal rstStatus : sl;
109 attribute use_dsp48 : ;
110 attribute use_dsp48 of raddr : signal is USE_DSP48_G;
111 attribute use_dsp48 of waddr : signal is USE_DSP48_G;
112 attribute use_dsp48 of cnt : signal is USE_DSP48_G;
116 -- FULL_THRES_G upper range check 118 report "FULL_THRES_G must be <= ((2**ADDR_WIDTH_G)-1)" 120 -- EMPTY_THRES_G upper range check 122 report "EMPTY_THRES_G must be <= ((2**ADDR_WIDTH_G)-2)" 126 report "USE_DSP48_G must be either yes, no, auto, or automax" 128 -- INIT_G length check 130 "INIT_G must either be ""0"" or the same length as DATA_WIDTH_G" severity failure;
142 -- Asynchronous reset 147 fullStatus <= '1' after TPD_G;
148 elsif rising_edge(clk) then 154 fullStatus <= '1' after TPD_G;
164 if (cnt = (RAM_DEPTH_C-1)) or (cnt = (RAM_DEPTH_C-2)) or (cnt = (RAM_DEPTH_C-3)) then 170 if (cnt = (RAM_DEPTH_C-1)) or (cnt = (RAM_DEPTH_C-2)) then 171 fullStatus <= '1' after TPD_G;
173 fullStatus <= '0' after TPD_G;
184 fifoStatus.empty <= '1' when (cnt = 0) else rstStatus;
186 FIFO_Gen : if (FWFT_EN_G = false) generate 195 FWFT_Gen : if (FWFT_EN_G = true) generate 217 readEnable <= (sRdEn or fwftStatus.empty) and not(fifoStatus.empty);
218 sValid <= not(fwftStatus.empty);
225 -- Asynchronous reset 227 fwftStatus <= READ_STATUS_INIT_C after TPD_G;
228 elsif rising_edge(clk) then 231 fwftStatus <= READ_STATUS_INIT_C after TPD_G;
243 -- Asynchronous reset 245 writeAck <= '0' after TPD_G;
246 readAck <= '0' after TPD_G;
247 waddr <= (others => '0') after TPD_G;
248 raddr <= (others => '0') after TPD_G;
249 cnt <= (others => '0') after TPD_G;
250 overflowStatus <= '0' after TPD_G;
251 underflowStatus <= '0' after TPD_G;
252 elsif rising_edge(clk) then 253 writeAck <= '0' after TPD_G;
254 readAck <= '0' after TPD_G;
255 overflowStatus <= '0' after TPD_G;
256 underflowStatus <= '0' after TPD_G;
259 waddr <= (others => '0') after TPD_G;
260 raddr <= (others => '0') after TPD_G;
261 cnt <= (others => '0') after TPD_G;
264 -- Check for write operation 266 if fullStatus = '0' then 267 -- Increment the write address pointer 268 waddr <= waddr + 1 after TPD_G;
269 writeAck <= '1' after TPD_G;
271 overflowStatus <= '1' after TPD_G;
275 -- Check for read operation 276 if readEnable = '1' then 277 if fifoStatus.empty = '0' then 278 -- Increment the read address pointer 279 raddr <= raddr + 1 after TPD_G;
280 readAck <= '1' after TPD_G;
282 underflowStatus <= '1' after TPD_G;
286 -- Increment the FIFO counter 287 if (readEnable = '1') and (wr_en = '0') and (fifoStatus.empty = '0') then 288 cnt <= cnt - 1 after TPD_G;
289 elsif (readEnable = '0') and (wr_en = '1') and (fullStatus = '0') then 290 cnt <= cnt + 1 after TPD_G;
297 -- RAM Port A Mapping 300 portA.we <= wr_en and not(fullStatus);
304 -- RAM Port B Mapping 306 portB.en <= readEnable and not(fifoStatus.empty);
307 portB.rst <= rstStatus;
310 portB.din <= (others => '0');
313 portB.dout <= (others => '0');
316 GEN_RAM : if (BYP_RAM_G = false) generate 320 RST_POLARITY_G => '1',
-- portB.rst already converted to active high 337 rstb => '0',
-- Rely on rd/wr ptrs 339 doutb => portB.dout
);
ADDR_WIDTH_Ginteger range 4 to 48:= 4
USE_DSP48_Gstring := "no"
in addrbslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
in rstbsl :=not ( RST_POLARITY_G)
RST_ASYNC_Gboolean := false
ALTERA_RAM_Gstring := "M9K"
out doutbslv( DATA_WIDTH_G- 1 downto 0)
in rstsl :=not RST_POLARITY_G
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
out data_countslv( ADDR_WIDTH_G- 1 downto 0)
PIPE_STAGES_Gnatural range 0 to 16:= 0
ALTERA_RAM_Gstring := "M9K"
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
in dinslv( DATA_WIDTH_G- 1 downto 0)
FULL_THRES_Ginteger range 1 to ( 2** 24):= 1
ADDR_WIDTH_Ginteger range 1 to ( 2** 24):= 4
in addraslv( ADDR_WIDTH_G- 1 downto 0) :=( others => '0')
out doutslv( DATA_WIDTH_G- 1 downto 0)
in rstsl :=not RST_POLARITY_G
ALTERA_SYN_Gboolean := false
PIPE_STAGES_Gnatural range 0 to 16:= 1
ALTERA_SYN_Gboolean := false
RST_ASYNC_Gboolean := false
FWFT_EN_Gboolean := false
DATA_WIDTH_Ginteger range 1 to ( 2** 24):= 16
in sDataslv( DATA_WIDTH_G- 1 downto 0)
out mDataslv( DATA_WIDTH_G- 1 downto 0)
BYP_RAM_Gboolean := false
EMPTY_THRES_Ginteger range 1 to ( 2** 24):= 1
in dinaslv( DATA_WIDTH_G- 1 downto 0) :=( others => '0')