]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
trbnet16 fifo added, Jan
authorhadeshyp <hadeshyp>
Sun, 23 Sep 2007 17:51:23 +0000 (17:51 +0000)
committerhadeshyp <hadeshyp>
Sun, 23 Sep 2007 17:51:23 +0000 (17:51 +0000)
trb_net16_fifo.vhd
xilinx/trb_net16_fifo_arch.vhd [new file with mode: 0644]

index 26f9c9c948e7e3b5a6542be1d52baec76525b38d..28eac7b8022175ae0b1921becfec76ad66d6c799 100644 (file)
@@ -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 (file)
index 0000000..5ec3517
--- /dev/null
@@ -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