]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
ibuf header retransmit and eob logic working, Ingo
authorhadaq <hadaq>
Fri, 25 Aug 2006 14:08:24 +0000 (14:08 +0000)
committerhadaq <hadaq>
Fri, 25 Aug 2006 14:08:24 +0000 (14:08 +0000)
testbench/in_ibuf.txt [new file with mode: 0644]
testbench/in_ibuf_overflow.txt [new file with mode: 0644]
testbench/out_ibuf.txt [new file with mode: 0644]
testbench/testbench_howto.txt [new file with mode: 0644]
testbench/trb_net_fifo_testbench_beh.prj [new file with mode: 0644]
testbench/trb_net_ibuf_testbench.vhd
testbench/trb_net_ibuf_testbench_beh.prj [new file with mode: 0644]
trb_net_ibuf.vhd [new file with mode: 0644]
trb_net_std.vhd
xilinx/trb_net_fifo_arch.vhd

diff --git a/testbench/in_ibuf.txt b/testbench/in_ibuf.txt
new file mode 100644 (file)
index 0000000..6e47fed
--- /dev/null
@@ -0,0 +1,14 @@
+0:000:0000:0000
+0:000:0000:0000
+0:000:0000:0000
+0:000:0000:0000
+1:001:0000:0001 --hdr
+1:000:0000:0010 --dat
+1:000:0000:0011 --dat
+1:000:0000:0100 --dat
+1:011:0000:0000 --eob
+1:000:0000:0001 --dat  
+1:000:0000:0010 --dat
+1:000:0000:0011 --dat
+1:010:0000:0000 --trm
+0:000:0000:0000
\ No newline at end of file
diff --git a/testbench/in_ibuf_overflow.txt b/testbench/in_ibuf_overflow.txt
new file mode 100644 (file)
index 0000000..a376624
--- /dev/null
@@ -0,0 +1,24 @@
+0:000:0000
+0:000:0000
+0:000:0000
+0:000:0000
+0:000:0000
+1:100:0000    -- 1:101:0111 -- send ack
+1:100:0001
+1:100:0010
+1:100:0011
+1:100:0100
+1:100:0101
+1:100:0110
+1:100:0111
+1:100:1000
+1:100:1001
+1:100:1010
+1:100:1011
+1:100:1100
+1:100:1101
+1:100:1110
+1:100:1111
+1:000:0001
+0:000:0000
+0:000:0000
diff --git a/testbench/out_ibuf.txt b/testbench/out_ibuf.txt
new file mode 100644 (file)
index 0000000..3841342
--- /dev/null
@@ -0,0 +1,12 @@
+1:0
+1:0
+1:0
+1:0
+1:1 -- hdr retransmit
+1:0
+1:0
+0:0 -- add waitstates
+0:0
+1:0
+1:0
+0:0
\ No newline at end of file
diff --git a/testbench/testbench_howto.txt b/testbench/testbench_howto.txt
new file mode 100644 (file)
index 0000000..9961613
--- /dev/null
@@ -0,0 +1,21 @@
+start fuse
+fuse -prj trbnet/testbench/trb_net_ibuf_testbench_beh.prj  -top trb_net_ibuf_testbench -o trb_net_ibuf_testbench
+
+
+ln -s trbnet/testbench/in_ibuf.txt in_ibuf.txt
+
+
+simulate
+trb_net_ibuf_testbench -tclbatch testsim.tcl
+
+the tcl file could look like this:
+
+# ntrace select -o on -m /trb_net_ibuf_testbench/IBUF/ -l this
+ntrace select -o on -m / -l this
+ntrace start
+run 500 ns
+quit
+
+isimwave  isimwavedata.xwv
+
+isimwave starts with the full length, change the time above to the ideal time...
diff --git a/testbench/trb_net_fifo_testbench_beh.prj b/testbench/trb_net_fifo_testbench_beh.prj
new file mode 100644 (file)
index 0000000..f4b4462
--- /dev/null
@@ -0,0 +1,5 @@
+vhdl work "../trb_net_std.vhd"
+vhdl work "../trb_net_fifo.vhd"
+vhdl work "../xilinx/trb_net_fifo_arch.vhd"
+vhdl work "../xilinx/shift_lut_x16.vhd"
+vhdl work "trb_net_fifo_testbench.vhd"
index fb65f25fcb079ad825ef54675e1b736d6e4ffc1c..c07daa62f455078757d7340dbaa62f435bff5b35 100644 (file)
@@ -27,9 +27,14 @@ architecture trb_net_ibuf_testbench_arch of trb_net_ibuf_testbench is
   signal int_data_out     : std_logic_vector(50 downto 0) := (others => '0');
   signal int_read_in     : std_logic := '0';
 
+  signal write_data_out     : std_logic_vector(51 downto 0) := (others => '0');
+  
   signal read_type : std_logic_vector(2 downto 0) := (others => '0');
   signal read_f2   : std_logic_vector(3 downto 0) := (others => '0');
+  signal read_f1   : std_logic_vector(3 downto 0) := (others => '0');
   signal stat_buffer  : std_logic_vector(31 downto 0) := (others => '0');
+
+  signal waiter : std_logic := '0';
   
   
   component trb_net_ibuf 
@@ -84,6 +89,7 @@ begin
   --med_data_in <= (others => '0');
   med_data_in(50 downto 48) <= read_type;
   med_data_in(19 downto 16) <= read_f2;
+  med_data_in(3 downto 0) <= read_f1;
   
 
   
@@ -102,7 +108,7 @@ begin
     variable leer : character;
     variable var1, var2 : std_logic;
     variable varx1 : std_logic_vector(2 downto 0);
-    variable varx2 : std_logic_vector(3 downto 0);
+    variable varx2, varx3 : std_logic_vector(3 downto 0);
     begin
     if falling_edge(CLK) then
       if (not endfile(protokoll)) then
@@ -111,31 +117,81 @@ begin
         read(myoutline,var1);
         med_dataready_in <= var1;
         read(myoutline,leer);
-
+        
         read(myoutline,varx1);
         read_type <= varx1;
         read(myoutline,leer);
 
         read(myoutline,varx2);
         read_f2 <= varx2;
---        read(myoutline,leer);
+        read(myoutline,leer);
+
+        read(myoutline,varx3);
+        read_f1 <= varx3;
         
       end if;
     end if;
  end process STIMULI;
-      
-  
---   RESPONSE: process (clk)
---     file protokoll : text open write_mode is "out_ibuf.txt";
---     variable myoutline : line;
+
+--    int_read_in <= int_dataready_out after 5ns;
     
---   begin  -- process RESPONSE
---     if rising_edge(CLK) then  -- rising clock edge
+READ_BUF: process
+    file protokoll : text open read_mode is "out_ibuf.txt";
+    variable myoutline : line;
+    variable leer : character;
+    variable var1, var2 : std_logic;
+    variable varx1 : std_logic_vector(2 downto 0);
+    variable varx2, varx3 : std_logic_vector(3 downto 0);
+    begin
+      wait on CLK;
+      if rising_edge(CLK) then
+        wait for 5ns;
+        if (not endfile(protokoll)) then
+          readline(protokoll,myoutline);
+          read(myoutline,var1);
+          read(myoutline,leer);
+          read(myoutline,var2);
+
+          if var1 = '1' and var2 = '0' then
+
+            if int_dataready_out = '0' then
+              int_read_in <= '0';
+              waiter <= '1';
+              wait until int_dataready_out = '1';
+              waiter <= '0';
+            end if;
+            wait for 5ns;
+            int_read_in <= '1';
+            int_header_in <= '0';
+
+          elsif var1 = '1' and var2 = '1' then
+            wait for 5ns;
+            int_read_in <= '1';
+            int_header_in <= '1';
+          else
+            int_read_in <= '0';
+            int_header_in <= '0';
+          end if;
+          
+        end if;
+    end if;
+ end process;
 
---       hwrite (myoutline, mydepth);
---       writeline(protokoll, myoutline);
---     end if;
---   end process RESPONSE;
+
+    write_data_out(50 downto 0)<= int_data_out;
+    write_data_out(51) <=  '0';
+    
+    RESPONSE: process (clk)
+     file protokoll : text open write_mode is "result_out_ibuf.txt";
+     variable myoutline : line;
+   
+   begin  -- process RESPONSE
+     if rising_edge(CLK) and int_read_in='1' then  -- rising clock edge and I'm
+                                                   -- reading
+       hwrite (myoutline, write_data_out(51 downto 0));
+       writeline(protokoll, myoutline);
+     end if;
+   end process RESPONSE;
   
   
 end trb_net_ibuf_testbench_arch;
diff --git a/testbench/trb_net_ibuf_testbench_beh.prj b/testbench/trb_net_ibuf_testbench_beh.prj
new file mode 100644 (file)
index 0000000..140c2e9
--- /dev/null
@@ -0,0 +1,6 @@
+vhdl work "../trb_net_std.vhd"
+vhdl work "../trb_net_fifo.vhd"
+vhdl work "../xilinx/trb_net_fifo_arch.vhd"
+vhdl work "../xilinx/shift_lut_x16.vhd"
+vhdl work "../trb_net_ibuf.vhd"
+vhdl work "trb_net_ibuf_testbench.vhd"
diff --git a/trb_net_ibuf.vhd b/trb_net_ibuf.vhd
new file mode 100644 (file)
index 0000000..bc0de5a
--- /dev/null
@@ -0,0 +1,265 @@
+-- for a description see HADES wiki
+-- http://hades-wiki.gsi.de/cgi-bin/view/DaqSlowControl/TrbNetIBUF
+
+LIBRARY IEEE;
+USE IEEE.STD_LOGIC_1164.ALL;
+USE IEEE.STD_LOGIC_ARITH.ALL;
+USE IEEE.STD_LOGIC_UNSIGNED.ALL;
+
+use work.trb_net_std.all;
+
+--Entity decalaration for clock generator
+entity trb_net_ibuf is
+
+  generic (DEPTH : integer := 3);     -- Depth of the FIFO, 2^(n+1)
+
+  port(
+    --  Misc
+    CLK    : in std_logic;             
+    RESET  : in std_logic;     
+    CLK_EN : in std_logic;
+    --  Media direction port
+    MED_DATAREADY_IN:  in  STD_LOGIC; -- Data word is offered by the Media (the IOBUF MUST read)
+    MED_DATA_IN:       in  STD_LOGIC_VECTOR (50 downto 0); -- Data word
+    MED_READ_OUT:      out STD_LOGIC; -- buffer reads a word from media
+    MED_ERROR_IN:      in  STD_LOGIC_VECTOR (2 downto 0);  -- Status bits
+    -- Internal direction port
+    INT_HEADER_IN:     in  STD_LOGIC; -- Concentrator kindly asks to resend the last header
+    INT_DATAREADY_OUT: out STD_LOGIC;
+    INT_DATA_OUT:      out STD_LOGIC_VECTOR (50 downto 0); -- Data word
+    INT_READ_IN:       in  STD_LOGIC; 
+    INT_ERROR_OUT:     out STD_LOGIC_VECTOR (2 downto 0);  -- Status bits
+    -- Status and control port
+    STAT_LOCKED:       out STD_LOGIC_VECTOR (15 downto 0);
+    CTRL_LOCKED:       in  STD_LOGIC_VECTOR (15 downto 0);
+    STAT_BUFFER:       out STD_LOGIC_VECTOR (31 downto 0)
+    );
+END trb_net_ibuf;
+
+architecture trb_net_ibuf_arch of trb_net_ibuf is
+
+component 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 component;
+
+signal fifo_data_in : std_logic_vector(50 downto 0);
+signal fifo_data_out : std_logic_vector(50 downto 0);
+signal fifo_write, fifo_read : std_logic;
+signal fifo_full, fifo_empty : std_logic;
+signal fifo_depth : std_logic_vector(7 downto 0);
+
+signal filtered_dataready : std_logic;
+signal filtered_read_out : std_logic;
+
+signal got_ack_internal, reg_ack_internal : std_logic;    --should be raised for 1 cycle when ack
+                                        --arrived
+signal is_locked, got_locked : std_logic;
+signal got_eob_out, reg_eob_out: std_logic;
+signal tmp_INT_DATAREADY_OUT: std_logic;
+signal current_last_header, next_last_header : std_logic_vector(50 downto 0);
+
+type ERROR_STATE is (IDLE, GOT_OVERFLOW_ERROR, GOT_LOCKED_ERROR, GOT_UNDEFINED_ERROR);
+signal current_error_state, next_error_state : ERROR_STATE;
+
+signal next_rec_buffer_size_out, current_rec_buffer_size_out
+  : std_logic_vector(3 downto 0);       -- buffer size control
+
+  begin
+
+    FIFO: trb_net_fifo
+      generic map (
+        WIDTH => 51,
+        DEPTH => DEPTH)
+      port map (
+        CLK       => CLK,
+        RESET     => RESET,
+        CLK_EN    => CLK_EN,
+        DATA_IN   => fifo_data_in,
+        WRITE_ENABLE_IN => fifo_write,
+        DATA_OUT  => fifo_data_out,
+        READ_ENABLE_IN => fifo_read,
+        FULL_OUT  => fifo_full,
+        EMPTY_OUT => fifo_empty,
+        DEPTH_OUT => fifo_depth
+        );
+
+    fifo_data_in <= MED_DATA_IN;
+    
+-- this process controls the writing of the media into the fifo
+    FILTER_DATAREADY_IN : process(MED_DATA_IN, MED_DATAREADY_IN, MED_ERROR_IN,
+                                  fifo_full, is_locked, current_rec_buffer_size_out,
+                                  current_error_state)
+    begin  -- process
+      filtered_dataready <= '0';
+      got_ack_internal <=   '0';
+      filtered_read_out <=  '0';
+      fifo_write <=  '0';
+      next_rec_buffer_size_out <= current_rec_buffer_size_out;
+      next_error_state <= current_error_state;
+      
+      if MED_DATAREADY_IN = '1' then
+        if MED_DATA_IN(TYPE_POSITION) = TYPE_ACK then
+          got_ack_internal <=   '1';    
+          filtered_read_out <=  '1';    -- read from media in any case
+          if MED_DATA_IN(F1_POSITION) = F1_CHECK_ACK then
+            next_rec_buffer_size_out <= MED_DATA_IN(BUFFER_SIZE_POSITION);
+          end if;
+        elsif fifo_full = '0' and is_locked = '0' then
+          fifo_write <=  '1';
+        elsif fifo_full = '1' then
+          next_error_state <= GOT_OVERFLOW_ERROR;
+        elsif is_locked = '1' then
+          next_error_state <= GOT_LOCKED_ERROR;
+        else
+          next_error_state <= GOT_UNDEFINED_ERROR;
+        end if;                         -- end TYPE
+
+      end if;                           -- end MED_DATAREADY_IN
+    end process;
+
+    -- unregistered reaction, because it has to be fast!!!
+    MED_READ_OUT <= filtered_read_out; 
+    
+reg_buffer: process(CLK)
+    begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        current_rec_buffer_size_out <= (others => '0');
+        reg_ack_internal <='0';
+        current_error_state <= IDLE;
+      elsif CLK_EN = '1' then
+        current_rec_buffer_size_out <= next_rec_buffer_size_out;
+        reg_ack_internal <= got_ack_internal;
+        current_error_state <= next_error_state;
+      else
+        current_rec_buffer_size_out <= current_rec_buffer_size_out;
+        reg_ack_internal <= reg_ack_internal;
+        current_error_state <= current_error_state;
+      end if;
+    end if;
+  end process;
+
+-- this process controls what will be forwarded to the internal point
+  FILTER_DATA_OUT : process (INT_HEADER_IN, fifo_data_out,
+                       current_last_header, tmp_INT_DATAREADY_OUT)
+  begin
+    INT_DATA_OUT <= (others => '0');
+    if INT_HEADER_IN = '1' then
+      INT_DATA_OUT <= current_last_header;
+    elsif tmp_INT_DATAREADY_OUT ='1' then
+      INT_DATA_OUT <= fifo_data_out;
+    else
+      INT_DATA_OUT(TYPE_POSITION) <= TYPE_ILLEGAL;
+    end if;
+  end process;
+
+-- calculate the INT_DATAREADY_OUT
+  CALC_INT_DATAREADY_OUT: process (fifo_empty, fifo_data_out)
+  begin
+    if fifo_empty = '0' and not (fifo_data_out(TYPE_POSITION) = TYPE_EOB) then
+      tmp_INT_DATAREADY_OUT <= '1';
+    else
+      tmp_INT_DATAREADY_OUT <= '0';
+    end if;
+  end process;
+
+INT_DATAREADY_OUT <= tmp_INT_DATAREADY_OUT;
+  
+-- this process control the read of the internal point from the fifo
+  FILTER_OUT: process (INT_READ_IN, INT_HEADER_IN, fifo_data_out,
+                       current_last_header)
+    
+  begin  -- process
+    got_locked  <= '0';
+    fifo_read   <= '0';
+    got_eob_out <= '0';
+    next_last_header <= current_last_header;
+    
+    if INT_READ_IN = '1' then
+
+      if fifo_data_out(TYPE_POSITION) = TYPE_TRM then
+        got_eob_out <= '1';
+        fifo_read   <= '1';
+        
+      else                          -- no TRM, normal read
+        got_eob_out <= '0';
+        fifo_read   <= '1';
+        
+        if fifo_data_out(TYPE_POSITION) = TYPE_HDR then
+          next_last_header <= fifo_data_out;
+        end if;
+      end if;
+      
+      
+    else                                -- no external read
+      if fifo_data_out(TYPE_POSITION) = TYPE_EOB then
+        got_eob_out <= '1';
+        fifo_read   <= '1';           -- autodestroy EOB
+      end if;
+    end if;                           -- INT_READ_IN
+  end process;
+  
+
+
+
+  
+reg_locked: process(CLK)
+    begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        is_locked <= '0';
+        reg_eob_out <= '0';
+        current_last_header <= (others => '0');
+      elsif CLK_EN = '1' then
+        is_locked <= got_locked;
+        reg_eob_out <= got_eob_out;
+        current_last_header <= next_last_header;
+      else
+        is_locked <= is_locked;
+        reg_eob_out <= reg_eob_out;
+        current_last_header <= current_last_header;
+      end if;
+    end if;
+  end process;
+
+
+  
+-- make STAT_BUFFER
+  STAT_BUFFER(3 downto 0) <= fifo_depth(3 downto 0);
+  STAT_BUFFER(7 downto 4) <= current_rec_buffer_size_out;
+  STAT_BUFFER(8) <= reg_eob_out;
+  STAT_BUFFER(9) <= reg_ack_internal;
+
+  MAKE_ERROR_BITS : process(current_error_state)
+    begin
+      if current_error_state = IDLE then
+        STAT_BUFFER(11 downto 10) <= "00";
+      elsif current_error_state = GOT_OVERFLOW_ERROR then
+        STAT_BUFFER(11 downto 10) <= "01";
+      elsif current_error_state = GOT_LOCKED_ERROR then
+        STAT_BUFFER(11 downto 10) <= "10";
+      else
+        STAT_BUFFER(11 downto 10) <= "11";
+      end if;
+    end process;
+
+  STAT_BUFFER(31 downto 12) <= (others => '0');  
+  
+end trb_net_ibuf_arch;
+  
index 1679b577a84e26bbb3de0154474bc3fcf2329e5c..137d3840c5c1e7d1e1534184d61b2a0d38acc7a4 100644 (file)
@@ -14,12 +14,14 @@ package trb_net_std is
     return std_logic;
 
   subtype TYPE_POSITION is integer range 50 downto 48;      
+  constant TYPE_DAT : std_logic_vector(2 downto 0) := "000";
   constant TYPE_HDR : std_logic_vector(2 downto 0) := "001";
   constant TYPE_TRM : std_logic_vector(2 downto 0) := "010";
   constant TYPE_EOB : std_logic_vector(2 downto 0) := "011";
-  constant TYPE_DAT : std_logic_vector(2 downto 0) := "100";
   constant TYPE_ACK : std_logic_vector(2 downto 0) := "101";
-
+  constant TYPE_ILLEGAL : std_logic_vector(2 downto 0) := "111";
+  
+  
   subtype F1_POSITION is integer range 47 downto 32;
   subtype F2_POSITION is integer range 31 downto 16;
   subtype F3_POSITION is integer range 15 downto 0;
index 06c2363d43f202ef0cd0545f45c74ceb5f52fff6..f768a65ca13f28aa53138b12790bc54eaf03fa53 100644 (file)
@@ -93,7 +93,7 @@ begin
     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;
+      real_ADDRESS_SRL <= current_ADDRESS_SRL - 2;
     else
       do_shift_internal <= '0';
       next_ADDRESS_SRL <= current_ADDRESS_SRL;
@@ -108,7 +108,7 @@ begin
     if RESET = '1' then
       current_DOUT <= (others => '0');
     elsif CLK_EN = '1' then
-      if current_EMPTY = '1' then
+      if current_EMPTY = '1' or real_ADDRESS_SRL(DEPTH+1) = '1' then
         current_DOUT <= DATA_IN;
       else
         current_DOUT <= next_DOUT;