]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
added bram fifo, Jan
authorhadeshyp <hadeshyp>
Wed, 10 Oct 2007 13:50:56 +0000 (13:50 +0000)
committerhadeshyp <hadeshyp>
Wed, 10 Oct 2007 13:50:56 +0000 (13:50 +0000)
xilinx/trb_net16_bram_fifo.vhd [new file with mode: 0644]

diff --git a/xilinx/trb_net16_bram_fifo.vhd b/xilinx/trb_net16_bram_fifo.vhd
new file mode 100644 (file)
index 0000000..e1ae212
--- /dev/null
@@ -0,0 +1,318 @@
+
+---------------------------------------------------------------------------
+--                                                                       --
+--  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;
+