From 172925e15685f761bab9bd68e7aa3306c3b54ea3 Mon Sep 17 00:00:00 2001 From: hadaq Date: Thu, 24 Aug 2006 13:47:18 +0000 Subject: [PATCH] added xilinx lut fifo, Ingo --- trb_net_fifo.vhd | 34 ++++++++ trb_net_fifo_testbench.vhd | 133 ++++++++++++++++++++++++++++ trb_net_std.vhd | 54 ++++++++++++ trbfifo.vhd | 50 ----------- xilinx/shift_lut_x16.vhd | 80 +++++++++++++++++ xilinx/trb_net_fifo_arch.vhd | 164 +++++++++++++++++++++++++++++++++++ 6 files changed, 465 insertions(+), 50 deletions(-) create mode 100644 trb_net_fifo.vhd create mode 100644 trb_net_fifo_testbench.vhd create mode 100644 trb_net_std.vhd delete mode 100644 trbfifo.vhd create mode 100644 xilinx/shift_lut_x16.vhd create mode 100644 xilinx/trb_net_fifo_arch.vhd diff --git a/trb_net_fifo.vhd b/trb_net_fifo.vhd new file mode 100644 index 0000000..b0d2813 --- /dev/null +++ b/trb_net_fifo.vhd @@ -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 index 0000000..d92caec --- /dev/null +++ b/trb_net_fifo_testbench.vhd @@ -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 index 0000000..22b565b --- /dev/null +++ b/trb_net_std.vhd @@ -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 index b1011ab..0000000 --- a/trbfifo.vhd +++ /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 index 0000000..e26b758 --- /dev/null +++ b/xilinx/shift_lut_x16.vhd @@ -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 index 0000000..06c2363 --- /dev/null +++ b/xilinx/trb_net_fifo_arch.vhd @@ -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; + + + -- 2.43.0