From: hadeshyp Date: Sun, 23 Sep 2007 17:51:23 +0000 (+0000) Subject: trbnet16 fifo added, Jan X-Git-Tag: oldGBE~701 X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=f2753246a845ff3c6d83d80d93e52654a1b09e12;p=trbnet.git trbnet16 fifo added, Jan --- diff --git a/trb_net16_fifo.vhd b/trb_net16_fifo.vhd index 26f9c9c..28eac7b 100644 --- a/trb_net16_fifo.vhd +++ b/trb_net16_fifo.vhd @@ -33,5 +33,3 @@ entity trb_net16_fifo is ); end entity; - - diff --git a/xilinx/trb_net16_fifo_arch.vhd b/xilinx/trb_net16_fifo_arch.vhd new file mode 100644 index 0000000..5ec3517 --- /dev/null +++ b/xilinx/trb_net16_fifo_arch.vhd @@ -0,0 +1,174 @@ +-- 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 trb_net16_fifo_arch of trb_net16_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 next_NUMOUT : std_logic_vector(NUM_WIDTH downto 0); +signal current_NUMOUT : std_logic_vector(NUM_WIDTH downto 0); + +signal current_FULL, next_FULL : std_logic; +signal current_EMPTY, next_EMPTY : std_logic; +signal do_shift, do_shift_internal : std_logic; + +signal srl_in, srl_out : std_logic_vector(DATA_WDITH + BUS_WIDTH -1 downto 0); + +begin + + FULL_OUT <= current_FULL; + EMPTY_OUT <= current_EMPTY; + do_shift <= do_shift_internal and CLK_EN; + + +-- generate the shift registers + srl_in(DATA_WIDTH -1 downto 0) <= DATA_IN; + srl_in(DATA_WIDTH + BUS_WIDTH -1 downto DATA_WIDTH) <= PACKET_NUM_IN; + + inst_SRLC256E_MACRO : for i in 0 to (DATA_WIDTH + NUM_WIDTH - 1) generate + U1 : shift_lut_x16 + generic map ( + ADDRESS_WIDTH => DEPTH - 3 + ) + port map ( + D => srl_in(i), + CE => do_shift, + CLK => CLK, + A => real_ADDRESS_SRL(DEPTH downto 0), + Q => srl_out(i)); + end generate; + + next_DOUT <= srl_out(DATA_WIDTH downto 0); + next_NUMOUT <= srl_out(DATA_WIDTH + BUS_WIDTH -1 downto DATA_WIDTH); + + 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, + current_EMPTY, current_FULL) + 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 - 2; + 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'); + currrent_NUMOUT <= (others => '0'); + elsif CLK_EN = '1' then + if current_EMPTY = '1' or real_ADDRESS_SRL(DEPTH+1) = '1' then + current_DOUT <= DATA_IN; + current_NUMOUT <= PACKET_NUM_IN + else + current_DOUT <= next_DOUT; + current_DOUT <= next_PACKET_NUM_OUT; + end if; + 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; + PACKET_NUM_OUT <= current_PACKET_NUM_OUT; + + + -- 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 trb_net16_fifo_arch; \ No newline at end of file