);
end entity;
+
+architecture trb_net16_fifo_arch of trb_net16_fifo is
+
+ signal din, dout : std_logic_vector(DATA_WIDTH + NUM_WIDTH-1 downto 0);
+ component trb_net_fifo is
+ generic (WIDTH : integer := DATA_WIDTH + NUM_WIDTH; -- FIFO word width
+ DEPTH : integer := DEPTH); -- 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
+ din(DATA_WIDTH - 1 downto 0) <= DATA_IN;
+ din(DATA_WIDTH + NUM_WIDTH -1 downto DATA_WIDTH) <= PACKET_NUM_IN;
+ DATA_OUT <= dout(DATA_WIDTH - 1 downto 0);
+ PACKET_NUM_OUT <= dout(DATA_WIDTH + NUM_WIDTH - 1 downto DATA_WIDTH);
+
+ fifo : trb_net_fifo
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ DATA_IN => din,
+ WRITE_ENABLE_IN => WRITE_ENABLE_IN,
+ DATA_OUT => dout,
+ READ_ENABLE_IN => READ_ENABLE_IN,
+ FULL_OUT => FULL_OUT,
+ EMPTY_OUT => EMPTY_OUT,
+ DEPTH_OUT => DEPTH_OUT
+ );
+
+end architecture;
-- the input read signal is stalled until the buffer is empty.
-- Maybe enough for trigger and slow control channels
--
--- The only difference of sbuf16 to the original sbuf is the division
--- into a data and a num port - no change in logic, just for easier use.
+-- This is a wrapper for the normal sbuf that provides two data ports sharing
+-- the same logic.
-------------------------------------------------------------------------------
architecture trb_net16_sbuf_arch of trb_net16_sbuf is
+component trb_net_sbuf is
+ generic (DATA_WIDTH : integer := DATA_WIDTH + NUM_WIDTH;
+ VERSION: integer := 1);
+ port(
+ -- Misc
+ CLK : in std_logic;
+ RESET : in std_logic;
+ CLK_EN : in std_logic;
+ -- port to combinatorial logic
+ COMB_DATAREADY_IN: in STD_LOGIC; --comb logic provides data word
+ COMB_next_READ_OUT: out STD_LOGIC; --sbuf can read in NEXT cycle
+ COMB_READ_IN: in STD_LOGIC; --comb logic IS reading
+ -- the COMB_next_READ_OUT should be connected via comb. logic to a register
+ -- to provide COMB_READ_IN (feedback path with 1 cycle delay)
+ -- The "REAL" READ_OUT can be constructed in the comb via COMB_next_READ_
+ -- OUT and the READ_IN: If one of these is ='1', no problem to read in next
+ -- step.
+ COMB_DATA_IN: in STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0); -- Data word
+ -- Port to synchronous output.
+ SYN_DATAREADY_OUT: out STD_LOGIC;
+ SYN_DATA_OUT: out STD_LOGIC_VECTOR (DATA_WIDTH-1 downto 0); -- Data word
+ SYN_READ_IN: in STD_LOGIC;
+ -- Status and control port
+ STAT_BUFFER: out STD_LOGIC
+ );
+end trb_net_sbuf;
+
+signal comb_in, syn_out : std_logic_vector (DATA_WIDTH + NUM_WIDTH - 1);
begin
+comb_in(DATA_WIDTH - 1 downto 0) <= COMB_DATA_IN;
+comb_in(DATA_WIDTH + NUM_WIDTH -1 downto DATA_WIDTH) <= COMB_PACKET_NUM_IN;
+SYN_DATA_OUT <= syn_out(DATA_WIDTH - 1 downto 0);
+SYN_PACKET_NUM_OUT <= syn_out(DATA_WIDTH + NUM_WIDTH - 1 downto DATA_WIDTH);
+
+sbuf: trb_net_sbuf
+ port map(
+ CLK => CLK,
+ RESET => RESET,
+ CLK_EN => CLK_EN,
+ COMB_DATAREADY_IN => COMB_DATAREADY_IN,
+ COMB_next_READ_OUT => COMB_next_READ_OUT,
+ COMB_READ_IN => COMB_READ_IN,
+ COMB_DATA_IN => comb_in,
+ SYN_DATAREADY_OUT => SYN_DATAREADY_OUT,
+ SYN_DATA_OUT => syn_out,
+ SYN_READ_IN => SYN_READ_IN,
+ STAT_BUFFER => STAT_BUFFER,
+ );
+
end architecture;
+++ /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 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