--- /dev/null
+-- 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;
+
+
+
--- /dev/null
+-- 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
+
--- /dev/null
+-- 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;
+
+++ /dev/null
-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;
-
-
-
--- /dev/null
+-- 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;
+------------------------------------------------------------------------------------------------
+
+
--- /dev/null
+-- 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;
+
+
+