--- /dev/null
+
+---------------------------------------------------------------------------
+-- --
+-- Module : fifoctlr_cc_v2.vhd Last Update: 01/07/05 --
+-- --
+-- Description : FifO controller top level. --
+-- Implements a 511x36 FifO w/common read/write clocks. --
+-- --
+-- The following VHDL code implements a 511x36 FifO in a Virtex2 --
+-- device. The inputs are a Clock, a Read Enable, a Write Enable, --
+-- Write Data, and a FifO_gsr signal as an initial reset. The outputs --
+-- are Read Data, Full, Empty, and the FifOcount outputs, which --
+-- indicate how full the FifO is. --
+-- --
+-- Designer : Nick Camilleri --
+-- --
+-- Company : Xilinx, Inc. --
+-- --
+-- Disclaimer : THESE DESIGNS ARE PROVIDED "AS IS" WITH NO WARRANTY --
+-- WHATSOEVER AND XILINX SPECifICALLY DISCLAIMS ANY --
+-- IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR --
+-- A PARTICULAR PURPOSE, OR AGAINST INFRINGEMENT. --
+-- THEY ARE ONLY INTendED TO BE USED BY XILINX --
+-- CUSTOMERS, AND WITHIN XILINX DEVICES. --
+-- --
+-- Copyright (c) 2000 Xilinx, Inc. --
+-- All rights reserved --
+-- --
+---------------------------------------------------------------------------
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+use work.trb_net_std.all;
+library unisim;
+use UNISIM.VComponents.all;
+
+entity trb_net16_bram_fifo is
+ port (clock_in: IN std_logic;
+ read_enable_in: IN std_logic;
+ write_enable_in: IN std_logic;
+ write_data_in: IN std_logic_vector(17 downto 0);
+ fifo_gsr_in: IN std_logic;
+ read_data_out: OUT std_logic_vector(17 downto 0);
+ full_out: OUT std_logic;
+ empty_out: OUT std_logic;
+ fifocount_out: OUT std_logic_vector(3 downto 0));
+end trb_net16_bram_fifo;
+
+architecture trb_net16_bram_fifo_arch of trb_net16_bram_fifo is
+ signal clock: std_logic;
+ signal read_enable: std_logic;
+ signal write_enable: std_logic;
+ signal fifo_gsr: std_logic;
+ signal read_data: std_logic_vector(17 downto 0) := "000000000000000000";
+ signal write_data: std_logic_vector(17 downto 0);
+ signal full: std_logic;
+ signal empty: std_logic;
+ signal read_addr: std_logic_vector(9 downto 0) := "0000000000";
+ signal write_addr: std_logic_vector(9 downto 0) := "0000000000";
+ signal fcounter: std_logic_vector(9 downto 0) := "0000000000";
+ signal read_allow: std_logic;
+ signal write_allow: std_logic;
+ signal fcnt_allow: std_logic;
+ signal fcntandout: std_logic_vector(3 downto 0);
+ signal ra_or_fcnt0: std_logic;
+ signal wa_or_fcnt0: std_logic;
+ signal emptyg: std_logic;
+ signal fullg: std_logic;
+ signal gnd_bus: std_logic_vector(17 downto 0);
+ signal gnd: std_logic;
+ signal pwr: std_logic;
+ signal last_write_data: std_logic_vector(17 downto 0);
+ signal not_read_since_emtpy: std_logic;
+
+component BUFG
+ port (
+ I: IN std_logic;
+ O: OUT std_logic);
+end component;
+
+component RAMB16_S18_S18
+ port (
+ ADDRA: IN std_logic_vector(9 downto 0);
+ ADDRB: IN std_logic_vector(9 downto 0);
+ DIA: IN std_logic_vector(15 downto 0);
+ DIB: IN std_logic_vector(15 downto 0);
+ DIPA: IN std_logic_vector(1 downto 0);
+ DIPB: IN std_logic_vector(1 downto 0);
+ WEA: IN std_logic;
+ WEB: IN std_logic;
+ CLKA: IN std_logic;
+ CLKB: IN std_logic;
+ SSRA: IN std_logic;
+ SSRB: IN std_logic;
+ ENA: IN std_logic;
+ ENB: IN std_logic;
+ DOA: OUT std_logic_vector(15 downto 0);
+ DOB: OUT std_logic_vector(15 downto 0);
+ DOPA: OUT std_logic_vector(1 downto 0);
+ DOPB: OUT std_logic_vector(1 downto 0));
+end component;
+
+begin
+ read_enable <= read_enable_in;
+ write_enable <= write_enable_in;
+ fifo_gsr <= fifo_gsr_in;
+ write_data <= write_data_in;
+ read_data_out <= write_data_in when empty = '1' else
+ last_write_data when not_read_since_emtpy = '1' else
+ read_data;
+ full_out <= full;
+ -- empty_out <= empty;
+ gnd_bus <= "000000000000000000";
+ gnd <= '0';
+ pwr <= '1';
+
+ process(clock_in)
+ begin
+ if rising_edge(clock_in) then
+ if fifo_gsr = '1' then
+ empty_out <= '0';
+ else
+ empty_out <= empty;
+ end if;
+ end if;
+ end process;
+
+ process(clock_in)
+ begin
+ if rising_edge(clock_in) then
+ if fifo_gsr = '1' then
+ last_write_data <= (others => '0');
+ elsif write_enable = '1' and empty = '1' then
+ last_write_data <= write_data_in;
+ end if;
+ end if;
+ end process;
+
+ process(clock_in)
+ begin
+ if rising_edge(clock_in) then
+ if fifo_gsr = '1' then
+ not_read_since_emtpy <= '1';
+ else
+ if empty = '1' then
+ not_read_since_emtpy <= '1';
+ end if;
+ if read_enable = '1' then
+ not_read_since_emtpy <= '0';
+ end if;
+ end if;
+ end if;
+ end process;
+
+--------------------------------------------------------------------------
+-- --
+-- A global buffer is instantianted to avoid skew problems. --
+-- --
+--------------------------------------------------------------------------
+
+--gclk1: BUFG port map (I => clock_in, O => clock);
+clock <= clock_in;
+--------------------------------------------------------------------------
+-- --
+-- Block RAM instantiation for FifO. Module is 1024x18, of which one --
+-- address location is sacrificed for the overall speed of the design. --
+-- --
+--------------------------------------------------------------------------
+
+bram1: RAMB16_S18_S18 port map (ADDRA => read_addr, ADDRB => write_addr,
+ DIA => gnd_bus(17 downto 2), DIPA => gnd_bus(1 downto 0),
+ DIB => write_data(17 downto 2), DIPB => write_data(1 downto 0),
+ WEA => gnd, WEB => pwr, CLKA => clock, CLKB => clock,
+ SSRA => gnd, SSRB => gnd, ENA => read_allow, ENB => write_allow,
+ DOA => read_data(17 downto 2), DOPA => read_data(1 downto 0),
+ DOB => open, DOPB => open );
+
+---------------------------------------------------------------
+-- --
+-- Set allow flags, which control the clock enables for --
+-- read, write, and count operations. --
+-- --
+---------------------------------------------------------------
+
+-- proc1: process (clock, fifo_gsr)
+-- begin
+-- if (fifo_gsr = '1') then
+-- read_allow <= '0';
+-- read_active <= '0';
+-- elsif (clock'EVENT AND clock = '1') then
+-- read_allow <= read_enable AND NOT emptyg;
+-- read_active <= read_enable and not (emptyg or (empty and write_enable));
+-- end if;
+-- end process proc1;
+--
+-- proc2: process (clock, fifo_gsr)
+-- begin
+-- if (fifo_gsr = '1') then
+-- write_allow <= '0';
+-- elsif (clock'EVENT AND clock = '1') then
+-- write_allow <= write_enable AND NOT fullg;
+-- end if;
+-- end process proc2;
+
+write_allow <= write_enable AND NOT fullg;
+read_allow <= (read_enable AND NOT empty);
+
+fcnt_allow <= (write_allow XOR read_allow) or (write_enable and empty) ;
+
+---------------------------------------------------------------
+-- --
+-- Empty flag is set on fifo_gsr (initial), or when on the --
+-- next clock cycle, Write Enable is low, and either the --
+-- FifOcount is equal to 0, or it is equal to 1 and Read --
+-- Enable is high (about to go Empty). --
+-- --
+---------------------------------------------------------------
+
+ra_or_fcnt0 <= (read_allow OR NOT fcounter(0));
+--fcntandout(0) <= NOT (fcounter(4) OR fcounter(3) OR fcounter(2) OR fcounter(1));
+--fcntandout(1) <= NOT (fcounter(8) OR fcounter(7) OR fcounter(6) OR fcounter(5));
+emptyg <= (not or_all(fcounter(9 downto 1)) AND ra_or_fcnt0 AND NOT write_allow);
+
+proc3: process (clock, fifo_gsr)
+begin
+ if (fifo_gsr = '1') then
+ empty <= '1';
+ elsif (clock'EVENT AND clock = '1') then
+ empty <= emptyg;
+ end if;
+end process proc3;
+
+---------------------------------------------------------------
+-- --
+-- Full flag is set on fifo_gsr (but it is cleared on the --
+-- first valid clock edge after fifo_gsr is removed), or --
+-- when on the next clock cycle, Read Enable is low, and --
+-- either the FifOcount is equal to 3FF (hex), or it is --
+-- equal to 1FE and the Write Enable is high (about to go --
+-- Full). --
+-- --
+---------------------------------------------------------------
+
+wa_or_fcnt0 <= (write_allow OR fcounter(0));
+--fcntandout(2) <= (fcounter(4) AND fcounter(3) AND fcounter(2) AND fcounter(1));
+--fcntandout(3) <= (fcounter(8) AND fcounter(7) AND fcounter(6) AND fcounter(5));
+fullg <= (and_all(fcounter(9 downto 1)) AND NOT read_allow); -- AND wa_or_fcnt0
+
+proc4: process (clock, fifo_gsr)
+begin
+ if (fifo_gsr = '1') then
+ full <= '1';
+ elsif (clock'EVENT AND clock = '1') then
+ full <= fullg;
+ end if;
+end process proc4;
+
+----------------------------------------------------------------
+-- --
+-- Generation of Read and Write address pointers. They now --
+-- use binary counters, because it is simpler in simulation, --
+-- and the previous LFSR implementation wasn't in the --
+-- critical path. --
+-- --
+----------------------------------------------------------------
+
+proc5: process (clock, fifo_gsr)
+begin
+ if (fifo_gsr = '1') then
+ read_addr <= "0000000000";
+ elsif (clock'EVENT AND clock = '1') then
+ if (read_allow = '1') then -- or(write_enable='1' and empty='1')
+ read_addr <= read_addr + '1';
+ end if;
+ end if;
+end process proc5;
+
+proc6: process (clock, fifo_gsr)
+begin
+ if (fifo_gsr = '1') then
+ write_addr <= "0000000000";
+ elsif (clock'EVENT AND clock = '1') then
+ if (write_allow = '1') then
+ write_addr <= write_addr + '1';
+ end if;
+ end if;
+end process proc6;
+
+----------------------------------------------------------------
+-- --
+-- Generation of FifOcount outputs. Used to determine how --
+-- full FifO is, based on a counter that keeps track of how --
+-- many words are in the FifO. Also used to generate Full --
+-- and Empty flags. Only the upper four bits of the counter --
+-- are sent outside the module. --
+-- --
+----------------------------------------------------------------
+
+proc7: process (clock, fifo_gsr)
+begin
+ if (fifo_gsr = '1') then
+ fcounter <= "0000000000";
+ elsif (clock'EVENT AND clock = '1') then
+ if (fcnt_allow = '1') then
+ if (read_allow = '0') then
+ fcounter <= fcounter + '1';
+ elsE
+ fcounter <= fcounter - '1';
+ end if;
+ end if;
+ end if;
+end process proc7;
+
+fifocount_out <= fcounter(9 downto 6);
+
+end architecture;
+