]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
added xilinx lut fifo, Ingo
authorhadaq <hadaq>
Thu, 24 Aug 2006 13:47:18 +0000 (13:47 +0000)
committerhadaq <hadaq>
Thu, 24 Aug 2006 13:47:18 +0000 (13:47 +0000)
trb_net_fifo.vhd [new file with mode: 0644]
trb_net_fifo_testbench.vhd [new file with mode: 0644]
trb_net_std.vhd [new file with mode: 0644]
trbfifo.vhd [deleted file]
xilinx/shift_lut_x16.vhd [new file with mode: 0644]
xilinx/trb_net_fifo_arch.vhd [new file with mode: 0644]

diff --git a/trb_net_fifo.vhd b/trb_net_fifo.vhd
new file mode 100644 (file)
index 0000000..b0d2813
--- /dev/null
@@ -0,0 +1,34 @@
+-- http://hades-wiki.gsi.de/cgi-bin/view/DaqSlowControl/TrbNetFifo
+
+library ieee;
+
+use ieee.std_logic_1164.all;
+
+USE ieee.std_logic_signed.ALL;
+
+USE ieee.std_logic_arith.ALL;
+
+
+
+entity trb_net_fifo is
+  
+  generic (WIDTH : integer := 8;       -- FIFO word width
+           DEPTH : integer := 4);     -- Depth of the FIFO, 2^(n+1)
+
+  port (CLK    : in std_logic;                 
+        RESET  : in std_logic;         
+        CLK_EN : in std_logic;
+        
+        DATA_IN         : in  std_logic_vector(WIDTH - 1 downto 0);  -- Input data
+        WRITE_ENABLE_IN : in  std_logic;               
+        DATA_OUT        : out std_logic_vector(WIDTH - 1 downto 0);  -- Output data
+        READ_ENABLE_IN  : in  std_logic; 
+        FULL_OUT        : out std_logic;       -- Full Flag
+        EMPTY_OUT       : out std_logic;
+        DEPTH_OUT       : out std_logic_vector(7 downto 0)
+        );     
+
+end trb_net_fifo;
+
+
+
diff --git a/trb_net_fifo_testbench.vhd b/trb_net_fifo_testbench.vhd
new file mode 100644 (file)
index 0000000..d92caec
--- /dev/null
@@ -0,0 +1,133 @@
+-- http://hades-wiki.gsi.de/cgi-bin/view/DaqSlowControl/TrbNetFifo
+
+library ieee;
+
+use ieee.std_logic_1164.all;
+
+USE ieee.std_logic_signed.ALL;
+
+USE ieee.std_logic_arith.ALL;
+
+USE std.textio.ALL;
+USE ieee.std_logic_textio.ALL;
+
+entity trb_net_fifo_testbench is
+
+end trb_net_fifo_testbench;
+
+architecture trb_net_fifo_testbench_arch of trb_net_fifo_testbench is
+
+  signal clk : std_logic := '0';
+  signal reset : std_logic := '1';
+  signal mydata_input: std_logic_vector(3 downto 0) := x"0";
+  signal mywrite  : std_logic := '1';
+  signal myread : std_logic := '0';
+  signal mydata_output: std_logic_vector(3 downto 0) := x"0";
+  signal myfull: std_logic := '0';
+  signal myempty: std_logic := '0';
+  signal mydepth: std_logic_vector(7 downto 0) := x"00";
+  
+  component trb_net_fifo 
+    
+    generic (WIDTH : integer := 8;     -- FIFO word width
+             DEPTH : integer := 4);     -- Depth of the FIFO, 2^(n+1)
+
+    port (CLK    : in std_logic;               
+          RESET  : in std_logic;       
+          CLK_EN : in std_logic;
+          
+          DATA_IN         : in  std_logic_vector(WIDTH - 1 downto 0);  -- Input data
+          WRITE_ENABLE_IN : in  std_logic;             
+          DATA_OUT        : out std_logic_vector(WIDTH - 1 downto 0);  -- Output data
+          READ_ENABLE_IN  : in  std_logic; 
+          FULL_OUT        : out std_logic;     -- Full Flag
+          EMPTY_OUT       : out std_logic;
+          DEPTH_OUT       : out std_logic_vector(7 downto 0)
+          );     
+  end component;
+  
+begin
+
+  FIFO : trb_net_fifo
+    generic map (
+      WIDTH => 4,
+      DEPTH => 3)
+    port map (
+      CLK             => clk,
+      RESET           => reset,
+      CLK_EN          => '1',
+      DATA_IN         => mydata_input,
+      WRITE_ENABLE_IN => mywrite,
+      READ_ENABLE_IN  => myread,
+      DATA_OUT        => mydata_output,
+      FULL_OUT        => myfull,
+      EMPTY_OUT       => myempty,
+      DEPTH_OUT       => mydepth);
+  
+  clk <= not clk after 10ns;
+
+  DO_RESET : process
+  begin
+    reset <= '1';
+    wait for 30ns;
+    reset <= '0';
+    wait;
+  end process DO_RESET;
+
+  STIMULI: process (clk)
+    file protokoll : text open read_mode is "in_fifo.txt";
+    variable myoutline : line;
+    variable leer : character;
+    variable var1, var2 : std_logic;
+    variable varx : std_logic_vector(3 downto 0);
+    begin
+    if falling_edge(CLK) then
+      if (not endfile(protokoll)) then
+        readline(protokoll,myoutline);
+        read(myoutline,var1);
+        mywrite <= var1;
+        read(myoutline,leer);
+        read(myoutline,var2);
+        myread  <= var2;
+        read(myoutline,leer);
+        read(myoutline,varx);
+        mydata_input <= varx;
+      end if;
+    end if;
+ end process STIMULI;
+      
+  
+  RESPONSE: process (clk)
+    file protokoll : text open write_mode is "out_fifo.txt";
+    variable myoutline : line;
+    
+  begin  -- process RESPONSE
+    if rising_edge(CLK) then  -- rising clock edge
+
+      hwrite (myoutline, mydepth);
+      writeline(protokoll, myoutline);
+    end if;
+  end process RESPONSE;
+  
+  
+end trb_net_fifo_testbench_arch;
+
+
+-- fuse -prj trb_net_fifo_testbench_beh.prj  -top trb_net_fifo_testbench -o trb_net_fifo_testbench
+
+-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/trb_net_std.vhd" 
+-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/trb_net_fifo.vhd"
+-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/xilinx/arch_trb_net_fifo.vhd"
+-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/xilinx/generic_fifo.vhd"   
+-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/xilinx/generic_shift.vhd"  
+-- vhdl work "/home/hadaq/acromag/design/DX2002test/trbnet/trb_net_fifo_testbench.vhd"
+
+-- trb_net_fifo_testbench -tclbatch testsim.tcl
+
+-- ntrace select -o on -m / -l this
+-- ntrace start
+-- run 1000 ns
+-- quit
+
+-- isimwave isimwavedata.xwv
+
diff --git a/trb_net_std.vhd b/trb_net_std.vhd
new file mode 100644 (file)
index 0000000..22b565b
--- /dev/null
@@ -0,0 +1,54 @@
+-- std package
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+
+package trb_net_std is
+
+  function and_all (arg : std_logic_vector)
+    return std_logic;
+  function or_all  (arg : std_logic_vector)
+    return std_logic;
+  function all_zero (arg : std_logic_vector)
+    return std_logic;
+  
+end package trb_net_std;
+
+package body trb_net_std is
+
+  function and_all (arg : std_logic_vector)
+    return std_logic is
+    variable tmp : std_logic := '1';
+    begin
+      tmp := '1';
+      for i in arg'range loop
+        tmp := tmp and arg(i);
+      end loop;  -- i
+      return tmp;
+  end function and_all;
+
+  function or_all (arg : std_logic_vector)
+    return std_logic is
+    variable tmp : std_logic := '1';
+    begin
+      tmp := '0';
+      for i in arg'range loop
+        tmp := tmp or arg(i);
+      end loop;  -- i
+      return tmp;
+  end function or_all;
+  
+  function all_zero (arg : std_logic_vector)
+    return std_logic is
+        variable tmp : std_logic := '1';
+        begin
+      for i in arg'range loop
+                 tmp := not arg(i);
+        exit when tmp = '0';
+      end loop;  -- i
+      return tmp;
+  end function all_zero;
+  
+end package body trb_net_std;
+
diff --git a/trbfifo.vhd b/trbfifo.vhd
deleted file mode 100644 (file)
index b1011ab..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-library ieee;
-
-use ieee.std_logic_1164.all;
-
-USE ieee.std_logic_signed.ALL;
-
-USE ieee.std_logic_arith.ALL;
-
-
-
-entity FIFO is
-    
-    generic (WIDTH : integer := 8;     -- FIFO word width
-            DEPTH : integer := 8);     -- Depth of the FIFO
-
-    port (DATA_IN  : in std_logic_vector(WIDTH - 1 downto 0);  -- Input data
-         DATA_OUT : out std_logic_vector(WIDTH - 1 downto 0);  -- Out put data
-         CLK : in std_logic;           -- System Clock
-         RESET : in std_logic;         -- System global Reset
-         RE : in std_logic;            -- Read Enable
-         WE : in std_logic;            -- Write Enable
-         FULL : buffer std_logic;      -- Full Flag
-         EMPTY : buffer std_logic);    -- Empty Flag
-
-end FIFO;
-
-
-architecture arch_FIFO of FIFO is
-  signal DATA : std_logic_vector(WIDTH - 1 downto 0);
-begin
-
-  DATA_OUT <= DATA;
-  FULL <= '0';
-  EMPTY <= '1';
-  
-  process (CLK)
-  begin
-      if (CLK'event and CLK = '1') then
-         if (WE = '1') then
-           DATA <= DATA_IN;
-          --DATA <= DATA + 1;
-         else
-           DATA <= DATA;
-         end if;
-      end if;
-  end process;
-end arch_FIFO;
-
-
-
diff --git a/xilinx/shift_lut_x16.vhd b/xilinx/shift_lut_x16.vhd
new file mode 100644 (file)
index 0000000..e26b758
--- /dev/null
@@ -0,0 +1,80 @@
+-- taken from xapp256 and changed to be more
+-- flexible (Ingo)
+
+library IEEE;
+use IEEE.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
+--
+-- pragma translate_off
+library UNISIM;
+use UNISIM.VCOMPONENTS.ALL;
+-- pragma translate_on
+--
+entity shift_lut_x16 is
+  generic (
+    ADDRESS_WIDTH : integer := 0
+    );      
+  port (
+       D    : in std_logic;
+        CE   : in std_logic; 
+        CLK  : in std_logic;
+        A    : in std_logic_vector (ADDRESS_WIDTH+3 downto 0);
+        Q    : out std_logic
+       ); 
+end shift_lut_x16;
+--
+architecture shift_lut_x16_arch of shift_lut_x16 is
+--
+-- Components Declarations:
+component SRLC16E 
+  port (
+       D    : in std_logic;
+        CE   : in std_logic;
+        CLK  : in std_logic;
+        A0   : in std_logic;
+        A1   : in std_logic;
+        A2   : in std_logic;
+        A3   : in std_logic;
+        Q    : out std_logic;
+        Q15  : out std_logic
+       ); 
+end component;
+
+--
+-- signal declarations
+signal SHIFT_CHAIN : std_logic_vector ((2**ADDRESS_WIDTH)+1 downto 0);
+signal SHIFT_OUT : std_logic_vector ((2**ADDRESS_WIDTH) downto 0);
+--
+begin
+--
+SHIFT_CHAIN(0) <= D;
+--
+-- ShiftRegister Instantiations
+U_SRLC16E_INST: for i in 0 to (2**ADDRESS_WIDTH) generate
+-- 
+U_SRLC16E: SRLC16E
+  port map (
+       D      => SHIFT_CHAIN(i),
+       CE     => CE, 
+       CLK    => CLK, 
+       A0     => A(0), 
+       A1     => A(1), 
+       A2     => A(2), 
+       A3     => A(3), 
+       Q      => SHIFT_OUT(i),
+       Q15    => SHIFT_CHAIN (i+1)  
+       );
+end generate;
+
+CHECK_WIDTH1: if ADDRESS_WIDTH>0 generate
+  Q <= SHIFT_OUT(conv_integer(A(ADDRESS_WIDTH+3 downto 4)));
+end generate CHECK_WIDTH1;
+CHECK_WIDTH2: if ADDRESS_WIDTH=0 generate
+  Q <= SHIFT_OUT(0);          
+end generate CHECK_WIDTH2;
+
+                
+end shift_lut_x16_arch;
+------------------------------------------------------------------------------------------------
+
+
diff --git a/xilinx/trb_net_fifo_arch.vhd b/xilinx/trb_net_fifo_arch.vhd
new file mode 100644 (file)
index 0000000..06c2363
--- /dev/null
@@ -0,0 +1,164 @@
+-- http://hades-wiki.gsi.de/cgi-bin/view/DaqSlowControl/TrbNetFifo
+
+-- taken example from xapp256, but rewritten most of the parts
+-- output fully synchonized with a "look-ahead" logic
+
+library ieee;
+
+use ieee.std_logic_1164.all;
+USE ieee.std_logic_signed.ALL;
+USE IEEE.numeric_std.ALL;
+use work.trb_net_std.all;
+
+
+architecture arch_trb_net_fifo of trb_net_fifo is
+
+component shift_lut_x16 
+  generic (
+    ADDRESS_WIDTH : integer := 0
+    );      
+  port (
+       D    : in std_logic;
+        CE   : in std_logic; 
+        CLK  : in std_logic;
+        A    : in std_logic_vector (ADDRESS_WIDTH+3 downto 0);
+        Q    : out std_logic
+       ); 
+end component;
+  
+signal current_ADDRESS_SRL : std_logic_vector(DEPTH+1 downto 0);
+signal next_ADDRESS_SRL : std_logic_vector(DEPTH+1 downto 0);
+signal real_ADDRESS_SRL : std_logic_vector(DEPTH+1 downto 0);
+signal current_DOUT : std_logic_vector(WIDTH -1 downto 0);
+signal next_DOUT : std_logic_vector(WIDTH -1 downto 0);
+
+signal current_FULL, next_FULL : std_logic;
+signal current_EMPTY, next_EMPTY : std_logic;
+signal do_shift, do_shift_internal : std_logic;
+
+begin
+
+  FULL_OUT  <= current_FULL;
+  EMPTY_OUT <= current_EMPTY;
+  do_shift  <= do_shift_internal and CLK_EN;
+
+  
+-- generate the shift registers
+  
+  inst_SRLC256E_MACRO : for i in 0 to (WIDTH - 1) generate
+    U1 :  shift_lut_x16
+      generic map (
+        ADDRESS_WIDTH  => DEPTH - 3
+        )
+      port map (
+        D    => DATA_IN(i),
+        CE   => do_shift,
+        CLK  => CLK,
+        A    => real_ADDRESS_SRL(DEPTH downto 0),
+        Q    => next_DOUT(i));
+  end generate;
+
+  reg_counter: process(CLK)
+  begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        current_ADDRESS_SRL <= (others => '0');
+      elsif CLK_EN = '1' then
+        current_ADDRESS_SRL <= next_ADDRESS_SRL;
+      else
+        current_ADDRESS_SRL <= current_ADDRESS_SRL;
+      end if;
+    end if;
+  end process;
+
+-- adress logic
+  comb_counter: process(WRITE_ENABLE_IN, READ_ENABLE_IN, current_ADDRESS_SRL)
+  begin
+-- no activity
+    if WRITE_ENABLE_IN = '0' and READ_ENABLE_IN = '0' then
+      do_shift_internal <= '0';
+      next_ADDRESS_SRL <= current_ADDRESS_SRL;
+      real_ADDRESS_SRL <= current_ADDRESS_SRL - 1;
+-- read from FIFO
+    elsif WRITE_ENABLE_IN = '0' and READ_ENABLE_IN = '1' and current_EMPTY = '0' then
+      do_shift_internal <= '0';
+      next_ADDRESS_SRL <= current_ADDRESS_SRL - 1;
+      real_ADDRESS_SRL <= current_ADDRESS_SRL - 2;
+-- write into FIFO     
+    elsif WRITE_ENABLE_IN = '1' and READ_ENABLE_IN = '0' and current_FULL = '0' then
+      do_shift_internal <= '1';
+      next_ADDRESS_SRL <= current_ADDRESS_SRL + 1;
+      real_ADDRESS_SRL <= current_ADDRESS_SRL - 1;
+-- read and write can be done in all cases
+    elsif WRITE_ENABLE_IN = '1' and READ_ENABLE_IN = '1' then
+      do_shift_internal <= '1';
+      next_ADDRESS_SRL <= current_ADDRESS_SRL;
+      real_ADDRESS_SRL <= current_ADDRESS_SRL - 1;
+    else
+      do_shift_internal <= '0';
+      next_ADDRESS_SRL <= current_ADDRESS_SRL;
+      real_ADDRESS_SRL <= current_ADDRESS_SRL - 1;
+      end if;
+    end process;
+
+-- registered read from FIFO    
+  reg_output: process(CLK)
+  begin
+    if rising_edge(CLK) then
+    if RESET = '1' then
+      current_DOUT <= (others => '0');
+    elsif CLK_EN = '1' then
+      if current_EMPTY = '1' then
+        current_DOUT <= DATA_IN;
+      else
+        current_DOUT <= next_DOUT;
+      end if;
+    else
+      current_DOUT <= current_DOUT;
+    end if;
+        end if;
+  end process;
+
+-- Comparator Block
+  next_FULL <= next_ADDRESS_SRL(DEPTH+1);
+ -- Empty flag is generated when reading from the last location 
+  next_EMPTY <= not or_all(next_ADDRESS_SRL(DEPTH+1 downto 0));
+
+  reg_empty: process(CLK)
+  begin
+    if rising_edge(CLK) then
+    if RESET = '1' then
+      current_EMPTY <= '1';
+      current_FULL <= '0';
+    elsif CLK_EN = '1' then
+      current_EMPTY <= next_EMPTY;
+      current_FULL  <= next_FULL;
+    else
+      current_EMPTY <= current_EMPTY;
+      current_FULL  <= current_FULL;
+      
+    end if;
+    end if;
+  end process;
+
+  FULL_OUT <= current_FULL;
+  EMPTY_OUT <= current_EMPTY;
+  DATA_OUT <= current_DOUT;
+
+  
+  -- generate the real depth which is at least 3
+  -- 0 -> 2
+  -- 1 -> 4
+  -- 2 -> 8
+  -- 3 -> 16
+  CHECK_DEPTH1:   if DEPTH>=3 generate
+    DEPTH_OUT <= std_logic_vector(to_unsigned(DEPTH,8));    
+  end generate CHECK_DEPTH1;
+  CHECK_DEPTH2:   if DEPTH<3 generate
+    DEPTH_OUT <= x"03";    
+  end generate CHECK_DEPTH2;
+  
+end arch_trb_net_fifo;
+
+
+