]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
*** empty log message ***
authorhadeshyp <hadeshyp>
Mon, 12 Jan 2009 14:07:20 +0000 (14:07 +0000)
committerhadeshyp <hadeshyp>
Mon, 12 Jan 2009 14:07:20 +0000 (14:07 +0000)
basics/wide_adder.vhd [new file with mode: 0644]
special/trb_net_bridge_etrax_endpoint.vhd
testbench/wide_adder_testbench.vhd [new file with mode: 0644]
trb_net16_endpoint_hades_full.vhd
trb_net16_hub_base.vhd
trb_net16_hub_ipu_logic.vhd [new file with mode: 0644]
trb_net16_ibuf.vhd
trb_net16_iobuf.vhd
trb_net16_obuf.vhd
trb_net_onewire.vhd
trb_net_std.vhd

diff --git a/basics/wide_adder.vhd b/basics/wide_adder.vhd
new file mode 100644 (file)
index 0000000..b0bdd77
--- /dev/null
@@ -0,0 +1,102 @@
+--Adds up a given number of words, distributed over several clock cycles,
+
+
+
+LIBRARY ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+
+
+entity wide_adder is
+  generic(
+    WIDTH : integer := 16;
+    WORDS : integer := 16;   --multiples of 2^parallel_adders only
+    PARALLEL_ADDERS : integer := 2   --2^n
+    );
+   port(
+    CLK    : in std_logic;
+    CLK_EN : in std_logic;
+    RESET  : in std_logic;
+    INPUT_IN     : in  std_logic_vector(WIDTH*WORDS-1 downto 0);
+    START_IN     : in  std_logic;
+    VAL_ENABLE_IN: in  std_logic_vector(WORDS-1 downto 0);
+    RESULT_OUT   : out std_logic_vector(WIDTH-1 downto 0);
+    OVERFLOW_OUT : out std_logic;
+    READY_OUT    : out std_logic
+    );
+end entity;
+
+architecture wide_adder_arch of wide_adder is
+  signal state : integer range 0 to WORDS/2**PARALLEL_ADDERS+2;
+  signal result : integer range 0 to 2**(WIDTH+PARALLEL_ADDERS)-1;
+  signal ready  : std_logic;
+  signal overflow : std_logic;
+
+  signal tmp_result : std_logic_vector(WIDTH+PARALLEL_ADDERS downto 0);
+begin
+
+
+
+  proc_result : process(CLK)
+    variable erg : integer range 0 to 2**(WIDTH+1)-1;
+    variable section : std_logic_vector(WIDTH*2**PARALLEL_ADDERS-1 downto 0);
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          state <= WORDS+PARALLEL_ADDERS;
+          overflow <= '0';
+          ready <= '0';
+        else
+          if START_IN = '1' then
+            state    <= 0;
+            result   <= 0;
+            ready    <= '0';
+            overflow <= '0';
+          end if;
+          if (state) * 2**PARALLEL_ADDERS < WORDS then
+            gen_mux : for i in 0 to WIDTH*2**PARALLEL_ADDERS-1 loop
+              section(i) := INPUT_IN((state*2**PARALLEL_ADDERS)*WIDTH+i);
+            end loop;
+            erg := result;
+--            if (WORDS/2**PARALLEL_ADDERS)*2**PARALLEL_ADDERS = WORDS then
+              gen_adders_simple : for i in 0 to 2**PARALLEL_ADDERS-1 loop
+                if VAL_ENABLE_IN(state*2**PARALLEL_ADDERS+i) = '1' then
+                  erg := erg + to_integer(unsigned(section((i)*WIDTH+WIDTH-1 downto (i)*WIDTH)));
+                else
+                  erg := erg;
+                end if;
+              end loop;
+--             else
+--               gen_adders_odd : for i in 0 to 2**PARALLEL_ADDERS-1 loop
+--                 if (state)*2**PARALLEL_ADDERS + i  < WORDS then
+--                   erg := erg + to_integer(unsigned(section((i)*WIDTH+WIDTH-1 downto (i)*WIDTH)));
+--                 else
+--                   erg := erg;
+--                 end if;
+--               end loop;
+--             end if;
+            result <= erg;
+            state  <= state + 1;
+            if (state*2**PARALLEL_ADDERS >= WORDS - 2**PARALLEL_ADDERS) then
+              ready <= '1';
+            end if;
+            if erg >= 2**WIDTH then
+              overflow <= '1';
+            end if;
+          end if;
+        end if;
+      end if;
+    end process;
+
+tmp_result <= std_logic_vector(to_unsigned(result,WIDTH+PARALLEL_ADDERS+1));
+
+
+OVERFLOW_OUT <= overflow;
+RESULT_OUT   <= tmp_result(WIDTH-1 downto 0);
+READY_OUT    <= ready;
+
+
+end architecture;
\ No newline at end of file
index ea33983984e3f4da7a16154fcfc4dff2f86ee43d..7116010a2fd349ffaaee3c28b7acccfbc92a1dbf 100644 (file)
@@ -211,6 +211,7 @@ architecture trb_net_bridge_etrax_endpoint_arch of trb_net_bridge_etrax_endpoint
       -- APL Control port
       APL_RUN_OUT           : out std_logic;
       APL_MY_ADDRESS_IN     : in  std_logic_vector (15 downto 0);
+      APL_LENGTH_IN         : in  std_logic_vector (15 downto 0);
       APL_SEQNR_OUT         : out std_logic_vector (7 downto 0);
 
       -- Internal direction port
@@ -451,6 +452,7 @@ begin
           -- APL Control port
           APL_RUN_OUT       => APL_RUN_OUT(2*i),
           APL_MY_ADDRESS_IN => APL_MY_ADDRESS_IN,
+          APL_LENGTH_IN     => x"FFFF",
           APL_SEQNR_OUT     => APL_SEQNR_OUT((2*i+1)*8-1 downto 2*i*8),
           -- Internal direction port
           INT_MASTER_DATAREADY_OUT => apl_to_buf_REPLY_DATAREADY(i),
@@ -512,6 +514,7 @@ begin
           -- APL Control port
           APL_RUN_OUT       => APL_RUN_OUT(2*i+1),
           APL_MY_ADDRESS_IN => APL_MY_ADDRESS_IN,
+          APL_LENGTH_IN     => x"FFFF",
           APL_SEQNR_OUT     => APL_SEQNR_OUT((2*i+2)*8-1 downto (2*i+1)*8),
           -- Internal direction port
           INT_MASTER_DATAREADY_OUT => apl_to_buf_INIT_DATAREADY(i),
diff --git a/testbench/wide_adder_testbench.vhd b/testbench/wide_adder_testbench.vhd
new file mode 100644 (file)
index 0000000..00ff5e8
--- /dev/null
@@ -0,0 +1,71 @@
+LIBRARY ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+
+library work;
+use work.trb_net_std.all;
+
+
+entity testbench is
+end entity;
+
+
+architecture test_arch of testbench is
+
+  component wide_adder is
+    generic(
+      WIDTH : integer := 16;
+      WORDS : integer := 16;
+      PARALLEL_ADDERS : integer := 2   --2^n
+      );
+    port(
+      CLK    : in std_logic;
+      CLK_EN : in std_logic;
+      RESET  : in std_logic;
+      INPUT_IN     : in  std_logic_vector(WIDTH*WORDS-1 downto 0);
+      START_IN     : in  std_logic;
+      VAL_ENABLE_IN: in  std_logic_vector(WORDS-1 downto 0);
+      RESULT_OUT   : out std_logic_vector(WIDTH-1 downto 0);
+      OVERFLOW_OUT : out std_logic;
+      READY_OUT    : out std_logic
+      );
+  end component;
+
+signal CLK : std_logic := '1';
+signal CLK_EN : std_logic := '1';
+signal RESET : std_logic := '1';
+
+signal start : std_logic := '0';
+signal overflow : std_logic := '0';
+signal ready : std_logic := '0';
+signal result : std_logic_vector(15 downto 0);
+signal input : std_logic_vector(255 downto 0);
+signal enable : std_logic_vector(15 downto 0);
+
+begin
+RESET <= '0' after 100 ns;
+CLK <= not CLK after 5 ns;
+
+start <= '1' after 145 ns, '0' after 155 ns, '1' after 295 ns, '0' after 305 ns;
+input <= x"8000_4000_2000_1000_0800_0400_0200_0100_0010_0020_0040_0080_0001_0002_0004_0001";
+enable <= "0111111111111111";
+
+ the_adder : wide_adder
+   generic map(
+     WIDTH => 16,
+     WORDS => 16,
+     PARALLEL_ADDERS => 2
+     )
+   port map(
+    CLK => CLK,
+    CLK_EN => CLK_EN,
+    RESET => RESET,
+    INPUT_IN => input,
+    START_IN => start,
+    VAL_ENABLE_IN => enable,
+    RESULT_OUT => result,
+    OVERFLOW_OUT => overflow,
+    READY_OUT => ready
+    );
+
+end architecture;
\ No newline at end of file
index 57c440e7312c5d62c41ea99d60be30c5041e00c0..cc0380596c77818907f2fe9c671dc2f723148649 100644 (file)
@@ -75,7 +75,7 @@ entity trb_net16_endpoint_hades_full is
 
 
     --Data Port
-    IPU_NUMBER_OUT   : out std_logic_vector (15 downto 0);
+    IPU_NUMBER_OUT       : out std_logic_vector (15 downto 0);
     IPU_INFORMATION_OUT  : out std_logic_vector (7 downto 0);
     --start strobe
     IPU_START_READOUT_OUT: out std_logic;
@@ -89,6 +89,7 @@ entity trb_net16_endpoint_hades_full is
     IPU_LENGTH_IN        : in  std_logic_vector (15 downto 0);
     IPU_ERROR_PATTERN_IN : in  std_logic_vector (31 downto 0);
 
+
     -- Slow Control Data Port
     REGIO_COMMON_STAT_REG_IN  : in  std_logic_vector(std_COMSTATREG*32-1 downto 0) := (others => '0');
     REGIO_COMMON_CTRL_REG_OUT : out std_logic_vector(std_COMCTRLREG*32-1 downto 0);
index 3b923cd48ba01570e4bc1607af8977f5ebc19c5a..9973b7e50da9e762e3e56bd9ca8e239789d808fb 100644 (file)
@@ -9,7 +9,7 @@ use work.trb_net16_hub_func.all;
 entity trb_net16_hub_base is
   generic (
   --hub control
-    HUB_CTRL_CHANNELNUM     : integer range 0 to 3 := 0;--c_SLOW_CTRL_CHANNEL;
+    HUB_CTRL_CHANNELNUM     : integer range 0 to 3 := c_SLOW_CTRL_CHANNEL;
     HUB_CTRL_DEPTH          : integer range 0 to 6 := c_FIFO_BRAM;
     HUB_USED_CHANNELS       : hub_channel_config_t := (c_YES,c_YES,c_YES,c_YES);
     USE_CHECKSUM            : hub_channel_config_t := (c_YES,c_YES,c_YES,c_YES);
@@ -184,6 +184,7 @@ architecture trb_net16_hub_base_arch of trb_net16_hub_base is
   signal HUB_CTRL_activepoints        : std_logic_vector (2**(c_MUX_WIDTH-1)*32-1 downto 0);
   signal HUB_CTRL_GEN                 : std_logic_vector (31 downto 0);
   signal HUB_ADDRESS                  : std_logic_vector (15 downto 0);
+  singal HUBLOGIC_IPU_STAT_DEBUG      : std_logic_vector (31 downto 0);
 
   signal IOBUF_STAT_GEN               :  std_logic_vector ((MII_NUMBER*2**(c_MUX_WIDTH-1) + API_NUMBER + TRG_NUMBER)*32-1 downto 0);
   signal IOBUF_IBUF_BUFFER            :  std_logic_vector ((MII_NUMBER*2**(c_MUX_WIDTH-1) + API_NUMBER + TRG_NUMBER)*32-1 downto 0);
@@ -234,6 +235,40 @@ architecture trb_net16_hub_base_arch of trb_net16_hub_base is
       );
   end component;
 
+  component trb_net16_hub_ipu_logic is
+    generic (
+      POINT_NUMBER        : integer range 2 to 32 := 3
+      );
+    port (
+      CLK    : in std_logic;
+      RESET  : in std_logic;
+      CLK_EN : in std_logic;
+      --Internal interfaces to IOBufs
+      INIT_DATAREADY_IN     : in  std_logic_vector (POINT_NUMBER-1 downto 0);
+      INIT_DATA_IN          : in  std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0);
+      INIT_PACKET_NUM_IN    : in  std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0);
+      INIT_READ_OUT         : out std_logic_vector (POINT_NUMBER-1 downto 0);
+      INIT_DATAREADY_OUT    : out std_logic_vector (POINT_NUMBER-1 downto 0);
+      INIT_DATA_OUT         : out std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0);
+      INIT_PACKET_NUM_OUT   : out std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0);
+      INIT_READ_IN          : in  std_logic_vector (POINT_NUMBER-1 downto 0);
+      REPLY_DATAREADY_IN    : in  std_logic_vector (POINT_NUMBER-1 downto 0);
+      REPLY_DATA_IN         : in  std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0);
+      REPLY_PACKET_NUM_IN   : in  std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0);
+      REPLY_READ_OUT        : out std_logic_vector (POINT_NUMBER-1 downto 0);
+      REPLY_DATAREADY_OUT   : out std_logic_vector (POINT_NUMBER-1 downto 0);
+      REPLY_DATA_OUT        : out std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0);
+      REPLY_PACKET_NUM_OUT  : out std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0);
+      REPLY_READ_IN         : in  std_logic_vector (POINT_NUMBER-1 downto 0);
+      --Status ports
+      STAT_DEBUG         : out std_logic_vector (31 downto 0);
+      STAT_POINTS_locked : out std_logic_vector (31 downto 0);
+      STAT_ERRORBITS     : out std_logic_vector (31 downto 0);
+      CTRL               : in  std_logic_vector (15 downto 0);
+      CTRL_activepoints  : in  std_logic_vector (31 downto 0) := (others => '1')
+      );
+  end component;
+
   component trb_net16_io_multiplexer is
     port(
       --  Misc
@@ -1103,38 +1138,73 @@ HUB_MED_CONNECTED(31 downto MII_NUMBER) <= (others => '1');
   begin
     gen_logic : if HUB_USED_CHANNELS(i) = 1 generate
       HUB_CTRL_final_activepoints((i+1)*32-1 downto i*32) <= HUB_CTRL_activepoints((i+1)*32-1 downto i*32) and HUB_MED_CONNECTED;
-      HUBLOGIC : trb_net16_hub_logic
-        generic map (
-        --media interfaces
-          POINT_NUMBER        => point_num
-          )
-        port map(
-          CLK    => CLK,
-          RESET  => RESET,
-          CLK_EN => CLK_EN,
-          INIT_DATAREADY_IN     => HUB_INIT_DATAREADY_IN(next_point_num-1 downto first_point_num),
-          INIT_DATA_IN          => HUB_INIT_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
-          INIT_PACKET_NUM_IN    => HUB_INIT_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
-          INIT_READ_OUT         => HUB_INIT_READ_OUT(next_point_num-1 downto first_point_num),
-          INIT_DATAREADY_OUT    => HUB_INIT_DATAREADY_OUT(next_point_num-1 downto first_point_num),
-          INIT_DATA_OUT         => HUB_INIT_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
-          INIT_PACKET_NUM_OUT   => HUB_INIT_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
-          INIT_READ_IN          => HUB_INIT_READ_IN(next_point_num-1 downto first_point_num),
-          REPLY_HEADER_OUT      => HUB_REPLY_SEND_HEADER_OUT(next_point_num-1 downto first_point_num),
-          REPLY_DATAREADY_IN    => HUB_REPLY_DATAREADY_IN(next_point_num-1 downto first_point_num),
-          REPLY_DATA_IN         => HUB_REPLY_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
-          REPLY_PACKET_NUM_IN   => HUB_REPLY_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
-          REPLY_READ_OUT        => HUB_REPLY_READ_OUT(next_point_num-1 downto first_point_num),
-          REPLY_DATAREADY_OUT   => HUB_REPLY_DATAREADY_OUT(next_point_num-1 downto first_point_num),
-          REPLY_DATA_OUT        => HUB_REPLY_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
-          REPLY_PACKET_NUM_OUT  => HUB_REPLY_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
-          REPLY_READ_IN         => HUB_REPLY_READ_IN(next_point_num-1 downto first_point_num),
-          STAT                  => buf_HUB_STAT_CHANNEL((i+1)*16-1 downto i*16),
-          STAT_POINTS_locked    => buf_STAT_POINTS_locked((i+1)*32-1 downto i*32),
-          STAT_ERRORBITS        => open,
-          CTRL                  => HUB_CTRL_CHANNEL((i+1)*16-1 downto i*16),
-          CTRL_activepoints     => HUB_CTRL_final_activepoints((i+1)*32-1 downto i*32)
-          );
+      gen_select_logic1 : if i /= c_IPU_CHANNEL generate
+        HUBLOGIC : trb_net16_hub_logic
+          generic map (
+          --media interfaces
+            POINT_NUMBER        => point_num
+            )
+          port map(
+            CLK    => CLK,
+            RESET  => RESET,
+            CLK_EN => CLK_EN,
+            INIT_DATAREADY_IN     => HUB_INIT_DATAREADY_IN(next_point_num-1 downto first_point_num),
+            INIT_DATA_IN          => HUB_INIT_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
+            INIT_PACKET_NUM_IN    => HUB_INIT_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
+            INIT_READ_OUT         => HUB_INIT_READ_OUT(next_point_num-1 downto first_point_num),
+            INIT_DATAREADY_OUT    => HUB_INIT_DATAREADY_OUT(next_point_num-1 downto first_point_num),
+            INIT_DATA_OUT         => HUB_INIT_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
+            INIT_PACKET_NUM_OUT   => HUB_INIT_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
+            INIT_READ_IN          => HUB_INIT_READ_IN(next_point_num-1 downto first_point_num),
+            REPLY_HEADER_OUT      => HUB_REPLY_SEND_HEADER_OUT(next_point_num-1 downto first_point_num),
+            REPLY_DATAREADY_IN    => HUB_REPLY_DATAREADY_IN(next_point_num-1 downto first_point_num),
+            REPLY_DATA_IN         => HUB_REPLY_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
+            REPLY_PACKET_NUM_IN   => HUB_REPLY_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
+            REPLY_READ_OUT        => HUB_REPLY_READ_OUT(next_point_num-1 downto first_point_num),
+            REPLY_DATAREADY_OUT   => HUB_REPLY_DATAREADY_OUT(next_point_num-1 downto first_point_num),
+            REPLY_DATA_OUT        => HUB_REPLY_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
+            REPLY_PACKET_NUM_OUT  => HUB_REPLY_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
+            REPLY_READ_IN         => HUB_REPLY_READ_IN(next_point_num-1 downto first_point_num),
+            STAT                  => buf_HUB_STAT_CHANNEL((i+1)*16-1 downto i*16),
+            STAT_POINTS_locked    => buf_STAT_POINTS_locked((i+1)*32-1 downto i*32),
+            STAT_ERRORBITS        => open,
+            CTRL                  => HUB_CTRL_CHANNEL((i+1)*16-1 downto i*16),
+            CTRL_activepoints     => HUB_CTRL_final_activepoints((i+1)*32-1 downto i*32)
+            );
+      end generate;
+      gen_select_logic2 : if i = c_IPU_CHANNEL generate
+        HUBLOGIC : trb_net16_hub_ipu_logic
+          generic map (
+          --media interfaces
+            POINT_NUMBER        => point_num
+            )
+          port map(
+            CLK    => CLK,
+            RESET  => RESET,
+            CLK_EN => CLK_EN,
+            INIT_DATAREADY_IN     => HUB_INIT_DATAREADY_IN(next_point_num-1 downto first_point_num),
+            INIT_DATA_IN          => HUB_INIT_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
+            INIT_PACKET_NUM_IN    => HUB_INIT_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
+            INIT_READ_OUT         => HUB_INIT_READ_OUT(next_point_num-1 downto first_point_num),
+            INIT_DATAREADY_OUT    => HUB_INIT_DATAREADY_OUT(next_point_num-1 downto first_point_num),
+            INIT_DATA_OUT         => HUB_INIT_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
+            INIT_PACKET_NUM_OUT   => HUB_INIT_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
+            INIT_READ_IN          => HUB_INIT_READ_IN(next_point_num-1 downto first_point_num),
+            REPLY_DATAREADY_IN    => HUB_REPLY_DATAREADY_IN(next_point_num-1 downto first_point_num),
+            REPLY_DATA_IN         => HUB_REPLY_DATA_IN(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
+            REPLY_PACKET_NUM_IN   => HUB_REPLY_PACKET_NUM_IN(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
+            REPLY_READ_OUT        => HUB_REPLY_READ_OUT(next_point_num-1 downto first_point_num),
+            REPLY_DATAREADY_OUT   => HUB_REPLY_DATAREADY_OUT(next_point_num-1 downto first_point_num),
+            REPLY_DATA_OUT        => HUB_REPLY_DATA_OUT(next_point_num*c_DATA_WIDTH-1 downto first_point_num*c_DATA_WIDTH),
+            REPLY_PACKET_NUM_OUT  => HUB_REPLY_PACKET_NUM_OUT(next_point_num*c_NUM_WIDTH-1 downto first_point_num*c_NUM_WIDTH),
+            REPLY_READ_IN         => HUB_REPLY_READ_IN(next_point_num-1 downto first_point_num),
+            STAT_DEBUG            => HUBLOGIC_IPU_STAT_DEBUG(31 downto 0),
+            STAT_POINTS_locked    => buf_STAT_POINTS_locked((i+1)*32-1 downto i*32),
+            STAT_ERRORBITS        => open,
+            CTRL                  => HUB_CTRL_CHANNEL((i+1)*16-1 downto i*16),
+            CTRL_activepoints     => HUB_CTRL_final_activepoints((i+1)*32-1 downto i*32)
+            );
+      end generate;
     end generate;
   end generate;
 
diff --git a/trb_net16_hub_ipu_logic.vhd b/trb_net16_hub_ipu_logic.vhd
new file mode 100644 (file)
index 0000000..1bf0e2d
--- /dev/null
@@ -0,0 +1,843 @@
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.std_logic_ARITH.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+
+
+entity trb_net16_hub_ipu_logic is
+  generic (
+  --media interfaces
+    POINT_NUMBER        : integer range 2 to 32 := 3
+    );
+  port (
+    CLK    : in std_logic;
+    RESET  : in std_logic;
+    CLK_EN : in std_logic;
+
+    --Internal interfaces to IOBufs
+    INIT_DATAREADY_IN     : in  std_logic_vector (POINT_NUMBER-1 downto 0);
+    INIT_DATA_IN          : in  std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0);
+    INIT_PACKET_NUM_IN    : in  std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0);
+    INIT_READ_OUT         : out std_logic_vector (POINT_NUMBER-1 downto 0);
+
+    INIT_DATAREADY_OUT    : out std_logic_vector (POINT_NUMBER-1 downto 0);
+    INIT_DATA_OUT         : out std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0);
+    INIT_PACKET_NUM_OUT   : out std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0);
+    INIT_READ_IN          : in  std_logic_vector (POINT_NUMBER-1 downto 0);
+
+    REPLY_DATAREADY_IN    : in  std_logic_vector (POINT_NUMBER-1 downto 0);
+    REPLY_DATA_IN         : in  std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0);
+    REPLY_PACKET_NUM_IN   : in  std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0);
+    REPLY_READ_OUT        : out std_logic_vector (POINT_NUMBER-1 downto 0);
+
+    REPLY_DATAREADY_OUT   : out std_logic_vector (POINT_NUMBER-1 downto 0);
+    REPLY_DATA_OUT        : out std_logic_vector (c_DATA_WIDTH*POINT_NUMBER-1 downto 0);
+    REPLY_PACKET_NUM_OUT  : out std_logic_vector (c_NUM_WIDTH*POINT_NUMBER-1 downto 0);
+    REPLY_READ_IN         : in  std_logic_vector (POINT_NUMBER-1 downto 0);
+
+    MY_ADDRESS_IN         : in  std_logic_vector (15 downto 0);
+    --Status ports
+    STAT_DEBUG         : out std_logic_vector (31 downto 0);
+    STAT_POINTS_locked : out std_logic_vector (31 downto 0);
+    STAT_ERRORBITS     : out std_logic_vector (31 downto 0);
+    CTRL               : in  std_logic_vector (15 downto 0);
+    CTRL_activepoints  : in  std_logic_vector (31 downto 0) := (others => '1')
+    );
+end entity;
+
+architecture trb_net16_hub_ipu_logic_arch of trb_net16_hub_ipu_logic is
+
+  component trb_net16_sbuf is
+    generic (
+      VERSION    : integer := 0
+      );
+    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
+      COMB_DATA_IN      : in  STD_LOGIC_VECTOR (c_DATA_WIDTH-1 downto 0); -- Data word
+      COMB_PACKET_NUM_IN: in  STD_LOGIC_VECTOR (c_NUM_WIDTH-1  downto 0);
+      -- Port to synchronous output.
+      SYN_DATAREADY_OUT : out STD_LOGIC;
+      SYN_DATA_OUT      : out STD_LOGIC_VECTOR (c_DATA_WIDTH-1 downto 0); -- Data word
+      SYN_PACKET_NUM_OUT: out STD_LOGIC_VECTOR (c_NUM_WIDTH-1  downto 0);
+      SYN_READ_IN       : in  STD_LOGIC;
+      -- Status and control port
+      STAT_BUFFER       : out STD_LOGIC
+      );
+  end component;
+  component trb_net_priority_arbiter is
+    generic (
+      WIDTH : integer := POINT_NUMBER
+      );
+    port(
+      --  Misc
+      CLK       : in std_logic;
+      RESET     : in std_logic;
+      CLK_EN    : in std_logic;
+      INPUT_IN  : in  STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+      RESULT_OUT: out STD_LOGIC_VECTOR (WIDTH-1 downto 0);
+      ENABLE    : in std_logic;
+      CTRL      : in  STD_LOGIC_VECTOR (9 downto 0)
+      );
+  end component;
+
+  component trb_net_ram_dp
+    generic(
+      depth : integer := 3;
+      width : integer := 16
+      );
+    port(
+      CLK   : in std_logic;
+      wr1   : in std_logic;
+      a1    : in std_logic_vector(depth-1 downto 0);
+      dout1 : out std_logic_vector(width-1 downto 0);
+      din1  : in std_logic_vector(width-1 downto 0);
+      a2    : in std_logic_vector(depth-1 downto 0);
+      dout2 : out std_logic_vector(width-1 downto 0)
+      );
+  end component;
+
+  component wide_adder is
+    generic(
+      WIDTH : integer := 16;
+      WORDS : integer := 16;   --multiples of 2^parallel_adders only
+      PARALLEL_ADDERS : integer := 2   --2^n
+      );
+    port(
+      CLK    : in std_logic;
+      CLK_EN : in std_logic;
+      RESET  : in std_logic;
+      INPUT_IN     : in  std_logic_vector(WIDTH*WORDS-1 downto 0);
+      START_IN     : in  std_logic;
+      VAL_ENABLE_IN: in  std_logic_vector(WORDS-1 downto 0);
+      RESULT_OUT   : out std_logic_vector(WIDTH-1 downto 0);
+      OVERFLOW_OUT : out std_logic;
+      READY_OUT    : out std_logic
+      );
+  end component;
+
+
+--signals init_pool
+  signal INIT_POOL_DATAREADY                 : std_logic;
+  signal INIT_POOL_READ                      : std_logic;
+  signal INIT_POOL_DATA                      : std_logic_vector(c_DATA_WIDTH-1 downto 0);
+  signal INIT_POOL_PACKET_NUM                : std_logic_vector(c_NUM_WIDTH-1  downto 0);
+  signal init_has_read_from_pool             : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal saved_INIT_TYPE, current_INIT_TYPE  : std_logic_vector(2 downto 0);
+
+  signal buf_INIT_READ_OUT                     : std_logic_vector(POINT_NUMBER-1 downto 0);
+  signal buf_REPLY_READ_OUT                    : std_logic_vector(POINT_NUMBER-1 downto 0);
+  signal REPLY_POOL_DATAREADY                  : std_logic;
+  signal REPLY_POOL_READ                       : std_logic;
+  signal REPLY_POOL_DATA                       : std_logic_vector(c_DATA_WIDTH-1 downto 0);
+  signal REPLY_POOL_PACKET_NUM                 : std_logic_vector(c_NUM_WIDTH-1  downto 0);
+
+  signal current_reply_packet_type : std_logic_vector(2 downto 0);
+  signal saved_reply_packet_type   : std_logic_vector(2 downto 0);
+  signal last_reply_packet_type    : std_logic_vector(2 downto 0);
+  signal current_reply_reading_trm : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal reply_reading_F0          : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal reply_reading_F1          : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal reply_reading_F2          : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal reply_reading_F3          : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal reply_combined_trm_F1     : std_logic_vector(c_DATA_WIDTH-1  downto 0);
+  signal reply_combined_trm_F2     : std_logic_vector(c_DATA_WIDTH-1  downto 0);
+  signal reply_combined_trm_F3     : std_logic_vector(c_DATA_WIDTH-1  downto 0);
+  signal REPLY_MUX_real_reading    : std_logic;
+  signal real_activepoints         : std_logic_vector(POINT_NUMBER-1 downto 0);
+  signal hdrram_write_enable       : std_logic_vector(POINT_NUMBER-1 downto 0);
+  signal hdrram_address            : std_logic_vector(3*POINT_NUMBER-1 downto 0);
+  signal current_waiting_for_reply : std_logic_vector(POINT_NUMBER-1 downto 0);
+  signal next_current_waiting_for_reply : std_logic_vector(POINT_NUMBER-1 downto 0);
+
+  signal reply_reading_HDR                     : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal reply_reading_DHDR                    : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal next_REPLY_reading_hdr                : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal current_REPLY_reading_hdr             : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal last_header_addr : std_logic_vector(c_NUM_WIDTH-1 downto 0);
+  signal last_header_data : std_logic_vector(POINT_NUMBER*c_DATA_WIDTH-1 downto 0);
+  signal reading_last_hdr,next_reading_last_hdr : std_logic_vector(POINT_NUMBER-1 downto 0);
+
+--general signals
+  signal locked, next_locked                 : std_logic;
+  signal get_locked, release_locked          : std_logic;
+  signal got_trm                             : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal locking_point, next_locking_point   : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal send_reply_trm                      : std_logic;
+
+  signal init_locked, next_init_locked       : std_logic;
+  signal get_init_locked, release_init_locked: std_logic;
+
+  signal REPLY_MUX_reading                   : std_logic_vector(POINT_NUMBER-1 downto 0);
+  signal reply_arbiter_result,last_reply_arbiter_result : std_logic_vector(POINT_NUMBER-1 downto 0);
+
+  type state_type is (IDLE, CHECK_DHDR, SENDING_DATA, SENDING_REPLY_TRM);
+  signal current_state, next_state           : state_type;
+  signal packet_counter                      : std_logic_vector(c_NUM_WIDTH-1 downto 0);
+  signal data_counter                        : std_logic_vector(7 downto 0);
+  signal SEQ_NR                              : std_logic_vector(7 downto 0);
+  signal comb_REPLY_POOL_DATAREADY           : std_logic;
+  signal comb_REPLY_POOL_DATA                : std_logic_vector(c_DATA_WIDTH-1 downto 0);
+  signal comb_REPLY_POOL_PACKET_NUM          : std_logic_vector(c_NUM_WIDTH-1 downto 0);
+  signal REPLY_POOL_next_read                : std_logic;
+  signal comb_REPLY_POOL_next_read           : std_logic;
+
+
+  signal reply_point_lock, next_point_lock   : std_logic;
+
+  signal comb_REPLY_muxed_DATAREADY           : std_logic;
+  signal comb_REPLY_muxed_DATA                : std_logic_vector(c_DATA_WIDTH-1 downto 0);
+  signal comb_REPLY_muxed_PACKET_NUM          : std_logic_vector(c_NUM_WIDTH-1 downto 0);
+  signal reply_arbiter_CLK_EN                 : std_logic;
+  signal init_arbiter_CLK_EN                  : std_logic;
+  signal init_arbiter_ENABLE                  : std_logic;
+  signal init_arbiter_read_out                : std_logic_vector(POINT_NUMBER-1 downto 0);
+  signal reply_arbiter_input                  : std_logic_vector(POINT_NUMBER-1 downto 0);
+  signal reply_arbiter_enable                 : std_logic;
+
+  signal INIT_muxed_DATAREADY            : std_logic;
+  signal INIT_muxed_DATA                 : std_logic_vector(c_DATA_WIDTH-1 downto 0);
+  signal INIT_muxed_PACKET_NUM           : std_logic_vector(c_NUM_WIDTH-1 downto 0);
+  signal INIT_muxed_READ                 : std_logic;
+  signal comb_INIT_next_read             : std_logic;
+  signal reply_fsm_state                 : std_logic_vector(7 downto 0);
+
+  signal waiting_for_init_finish, next_waiting_for_init_finish : std_logic;
+
+  signal waiting_for_DHDR_word           : std_logic_vector(POINT_NUMBER-1  downto 0);
+  signal next_waiting_for_DHDR_word      : std_logic_vector(POINT_NUMBER-1  downto 0);
+
+  signal reply_adder_start    : std_logic;
+  signal reply_adder_overflow : std_logic;
+  signal reply_adder_ready    : std_logic;
+  signal reply_adder_val_enable : std_logic_vector(POINT_NUMBER-1 downto 0);
+  signal reply_adder_result   : std_logic_vector(15 downto 0);
+
+
+begin
+
+  INIT_POOL_SBUF: trb_net16_sbuf
+    generic map (
+      Version => std_SBUF_VERSION
+      )
+    port map (
+      CLK   => CLK,
+      RESET  => RESET,
+      CLK_EN => CLK_EN,
+      COMB_DATAREADY_IN => INIT_muxed_DATAREADY,
+      COMB_next_READ_OUT => comb_INIT_next_read,
+      COMB_READ_IN => INIT_muxed_READ,
+      COMB_DATA_IN => INIT_muxed_DATA,
+      COMB_PACKET_NUM_IN => INIT_muxed_PACKET_NUM,
+      SYN_DATAREADY_OUT => INIT_POOL_DATAREADY,
+      SYN_DATA_OUT => INIT_POOL_DATA,
+      SYN_PACKET_NUM_OUT => INIT_POOL_PACKET_NUM,
+      SYN_READ_IN => INIT_POOL_READ
+      );
+
+  process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          INIT_muxed_READ <= '0';
+        else
+          INIT_muxed_READ <= comb_INIT_next_read;
+        end if;
+      end if;
+    end process;
+
+
+--choosing reply point
+  INIT_ARBITER: trb_net_priority_arbiter
+    generic map (WIDTH => POINT_NUMBER)
+    port map (
+      CLK   => CLK,
+      RESET  => RESET,
+      CLK_EN  => init_arbiter_CLK_EN,
+      INPUT_IN  => INIT_DATAREADY_IN,
+      RESULT_OUT => init_arbiter_read_out,
+      ENABLE  => init_arbiter_ENABLE,
+      CTRL => (others => '0')
+      );
+  init_arbiter_CLK_EN <= not locked;
+  init_arbiter_ENABLE <= not init_locked;
+
+--Datapool for Init-Channel
+  INIT_muxed_DATAREADY <= or_all(INIT_DATAREADY_IN and buf_INIT_READ_OUT) and not init_locked and INIT_muxed_READ;
+  INIT_POOL_READ <= and_all(INIT_READ_IN or init_has_read_from_pool or locking_point or not real_activepoints);
+  INIT_READ_OUT <= buf_INIT_READ_OUT;
+
+  gen_iro : for i in 0 to POINT_NUMBER-1 generate
+    buf_INIT_READ_OUT(i) <= init_arbiter_read_out(i) and not init_locked and INIT_muxed_READ;
+  end generate;
+
+  gen_init_pool_data0: for i in 0 to c_DATA_WIDTH-1 generate
+    process(INIT_DATA_IN, buf_INIT_READ_OUT)
+      variable VAR_INIT_POOL_DATA : std_logic;
+      begin
+        VAR_INIT_POOL_DATA := '0';
+        gen_init_pool_data1 : for j in 0 to POINT_NUMBER-1 loop
+          VAR_INIT_POOL_DATA := VAR_INIT_POOL_DATA or (INIT_DATA_IN(j*c_DATA_WIDTH+i) and buf_INIT_READ_OUT(j));
+        end loop;
+        INIT_muxed_DATA(i) <= VAR_INIT_POOL_DATA;
+      end process;
+  end generate;
+
+  gen_init_pool_data2: for i in 0 to c_NUM_WIDTH-1 generate
+    process(INIT_PACKET_NUM_IN, buf_INIT_READ_OUT)
+      variable VAR_INIT_POOL_PACKET_NUM : std_logic;
+      begin
+        VAR_INIT_POOL_PACKET_NUM := '0';
+        gen_init_pool_data3 : for j in 0 to POINT_NUMBER-1 loop
+          VAR_INIT_POOL_PACKET_NUM := VAR_INIT_POOL_PACKET_NUM or (INIT_PACKET_NUM_IN(j*c_NUM_WIDTH+i) and buf_INIT_READ_OUT(j));
+        end loop;
+        INIT_muxed_PACKET_NUM(i) <= VAR_INIT_POOL_PACKET_NUM;
+      end process;
+  end generate;
+
+
+--init_has_read signal
+  gen_hasread: for i in 0 to POINT_NUMBER-1 generate
+    process(CLK)
+      begin
+        if rising_edge(CLK) then
+          if RESET = '1' or INIT_POOL_READ = '1' then
+            init_has_read_from_pool(i) <= '0';
+          elsif INIT_POOL_DATAREADY = '1' and INIT_READ_IN(i) = '1' then
+            init_has_read_from_pool(i) <= '1';
+          end if;
+        end if;
+      end process;
+  end generate;
+
+--signals to obufs
+  gen_init_data_out: for i in 0 to POINT_NUMBER-1 generate
+    INIT_DATAREADY_OUT(i) <= INIT_POOL_DATAREADY and not init_has_read_from_pool(i) and real_activepoints(i) and not locking_point(i);
+    INIT_DATA_OUT((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH) <= INIT_POOL_DATA;
+    INIT_PACKET_NUM_OUT((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH) <= INIT_POOL_PACKET_NUM;
+  end generate;
+
+
+--locked signals
+--locked: transfer is running
+--init_locked: waiting for reply channel to finish
+
+  get_locked     <= INIT_muxed_DATAREADY;
+  next_locked    <= (get_locked or locked) and not release_locked;
+  next_locking_point <= (INIT_DATAREADY_IN) when (locked = '0' and REPLY_POOL_DATAREADY = '0') else locking_point;
+                       --buf_INIT_READ_OUT and
+
+  get_init_locked     <= '1' when saved_INIT_TYPE = TYPE_TRM and INIT_muxed_PACKET_NUM = c_F3 else '0';
+  release_init_locked <= release_locked;
+  next_init_locked    <= (get_init_locked or init_locked) and not release_init_locked;
+
+
+  process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          locked <= '0';
+          locking_point <= (others => '0');
+          init_locked <= '0';
+        else
+          locked <= next_locked;
+          locking_point <= next_locking_point;
+          init_locked <= next_init_locked;
+        end if;
+      end if;
+    end process;
+
+--saving necessary data
+----------------------------------
+  save_INIT_TYPE : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1'  or (INIT_muxed_DATAREADY = '1' and INIT_muxed_PACKET_NUM = c_F3) then
+          saved_INIT_TYPE <= TYPE_ILLEGAL;
+        elsif INIT_muxed_DATAREADY = '1' and INIT_muxed_PACKET_NUM = c_H0 then
+          saved_INIT_TYPE <= INIT_muxed_DATA(2 downto 0);
+        end if;
+      end if;
+    end process;
+  current_INIT_TYPE <= INIT_muxed_DATA(2 downto 0) when INIT_muxed_DATAREADY = '1' and INIT_muxed_PACKET_NUM = c_H0
+                       else saved_INIT_TYPE;
+
+  save_SEQ_NR : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          SEQ_NR <= (others => '0');
+        elsif INIT_POOL_PACKET_NUM = c_F3 and current_INIT_TYPE = TYPE_HDR then
+          SEQ_NR <= INIT_POOL_DATA(11 downto 4);
+        end if;
+      end if;
+    end process;
+
+
+
+
+------------------------------
+--REPLY-----------------------
+------------------------------
+
+  buf_REPLY_READ_OUT <= reply_reading_trm or reply_reading_HDR or reply_reading_DHDR or reply_mux_reading
+                             when REPLY_POOL_next_read = '1'
+                             else reply_reading_trm or reply_reading_HDR or reply_real_reading_DHDR;
+  REPLY_READ_OUT <= buf_REPLY_READ_OUT;
+
+  send_reply_trm <= and_all(got_trm);
+
+
+--save current packet type & number
+-----------------------------------
+
+  gen_reading_trmFn : for i in 0 to POINT_NUMBER-1 generate
+    reply_reading_F0(i) <= not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH)
+                     and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2) and REPLY_DATAREADY_IN(i);
+    reply_reading_F1(i) <= not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) and REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH)
+                     and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2) and REPLY_DATAREADY_IN(i);
+    reply_reading_F2(i) <= REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH)
+                     and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2) and REPLY_DATAREADY_IN(i);
+    reply_reading_F3(i) <= REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+1) and REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH)
+                     and not REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2) and REPLY_DATAREADY_IN(i);
+
+    process(CLK)
+      begin
+        if rising_edge(CLK) then
+          if RESET = '1' then
+            saved_reply_packet_type((i+1)*3-1 downto i*3) <= TYPE_ILLEGAL;
+            last_reply_packet_type((i+1)*3-1 downto i*3)  <= TYPE_ILLEGAL;
+          elsif REPLY_PACKET_NUM_IN((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH) = c_H0 then
+            saved_reply_packet_type((i+1)*3-1 downto i*3) <= REPLY_DATA_IN(2 downto 0);
+            last_reply_packet_type((i+1)*3-1 downto i*3)  <= saved_reply_packet_type;
+          end if;
+        end if;
+      end process;
+    current_reply_packet_type((i+1)*3-1 downto i*3) <= REPLY_DATA_IN(i*c_DATA_WIDTH+2 downto i*c_DATA_WIDTH)
+                  when (REPLY_PACKET_NUM_IN(i*c_NUM_WIDTH+2 downto i*c_NUM_WIDTH) = c_H0)
+                  else saved_reply_packet_type((i+1)*3-1 downto i*3);
+
+    current_reply_reading_HDR(i)  <= '1' when current_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_HDR else '0';
+    current_reply_reading_DHDR(i) <= '1' when current_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_DAT
+                                             and last_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_HDR else '0';
+    current_reply_reading_TRM(i)  <= '1' when current_reply_packet_type((i+1)*3-1 downto i*3) = TYPE_TRM else '0';
+  end generate;
+
+--saving (D)HDR
+-------------------------
+  gen_saving_dhdr : for i in 0 to POINT_NUMBER-1 generate
+    hdrram_write_enable(i) <= current_reply_reading_HDR(i) and
+                          (reply_reading_F0(i) or reply_reading_F1(i) or reply_reading_F2(i) or reply_reading_F3(i));
+    hdrram_address(i*3+2 downto i*3) <= REPLY_PACKET_NUM_IN((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH);
+    hdrram_address(i*3+3) <= '1' when current_reply_reading_DHDR(i) else '0';
+
+    the_last_HDR_RAM : trb_net_ram_dp
+      generic map(
+        depth => 3,
+        width => 16
+        )
+      port map(
+        CLK     => CLK,
+        wr1     => hdrram_write_enable(i),
+        a1      => hdrram_address(i*3+2 downto i*3),
+        din1    => REPLY_DATA_IN((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH),
+        dout1   => open,
+        a2      => last_dhdr_addr,
+        dout2   => last_dhdr_data((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH)
+        );
+  end generate;
+
+  the_ram_output_adder : wide_adder
+    generic map(
+      WIDTH => 16,
+      WORDS => POINT_NUMBER,
+      PARALLEL_ADDERS => 2
+      )
+    port map(
+      CLK          => CLK,
+      CLK_EN       => CLK_EN,
+      RESET        => RESET,
+      INPUT_IN     => last_dhdr_data,
+      START_IN     => adder_start,
+      RESULT_OUT   => adder_result,
+      OVERFLOW_OUT => adder_overflow,
+      READY_OUT    => adder_ready
+      );
+
+
+--reading and merging TRM
+----------------------------------
+
+
+  gen_combining_trm : for j in 0 to c_DATA_WIDTH-1 generate
+    process(CLK)
+      variable tmpF1, tmpF2, tmpF3 : std_logic;
+      begin
+        if rising_edge(CLK) then
+          if RESET = '1' or locked = '0' then
+            reply_combined_trm_F1(j) <= '0';
+            reply_combined_trm_F2(j) <= '0';
+            reply_combined_trm_F3(j) <= '0';
+          else
+            tmpF1 := '0';
+            tmpF2 := '0';
+            tmpF3 := '0';
+            for i in 0 to POINT_NUMBER-1 loop
+              tmpF1 := tmpF1 or (REPLY_DATA_IN(i*c_DATA_WIDTH+j) and reply_reading_F1(i) and reply_reading_trm(i));
+              tmpF2 := tmpF2 or (REPLY_DATA_IN(i*c_DATA_WIDTH+j) and reply_reading_F2(i) and reply_reading_trm(i));
+              tmpF3 := tmpF3 or (REPLY_DATA_IN(i*c_DATA_WIDTH+j) and reply_reading_F3(i) and reply_reading_trm(i));
+            end loop;
+            reply_combined_trm_F1(j) <= reply_combined_trm_F1(j) or tmpF1;
+            reply_combined_trm_F2(j) <= reply_combined_trm_F2(j) or tmpF2;
+            reply_combined_trm_F3(j) <= reply_combined_trm_F3(j) or tmpF3;
+          end if;
+        end if;
+      end process;
+  end generate;
+
+
+--real_activepoints can be set between transfers only, but can be cleared at any time
+----------------------------------
+  gen_real_activepoints : process (CLK)
+    begin
+      if rising_edge(CLK) then
+        if locked = '0' then
+          real_activepoints <= CTRL_activepoints(POINT_NUMBER-1 downto 0);
+        else
+          real_activepoints <= real_activepoints and CTRL_activepoints(POINT_NUMBER-1 downto 0);
+        end if;
+      end if;
+    end process;
+
+
+--count received TRM
+----------------------------------
+  gen_got_trm : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' or send_reply_trm = '1' or locked = '0' then
+          got_trm <= (others => '0');
+        else
+          got_trm <= got_trm or locking_point or reading_trmF2 or not real_activepoints;
+        end if;
+      end if;
+    end process;
+
+
+--REPLY Counters
+----------------------------------
+  --counter for 16bit words
+  gen_packet_counter : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' or locked = '0' then
+          packet_counter <= c_H0;
+        elsif comb_REPLY_POOL_DATAREADY = '1' then
+          if packet_counter = c_max_word_number then
+            packet_counter <= (others => '0');
+          else
+            packet_counter <= packet_counter + 1;
+          end if;
+        end if;
+      end if;
+    end process;
+
+  --counts data packets only
+  gen_data_counter : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' or reply_point_lock = '0' then
+          data_counter <= (others => '0');
+        elsif comb_REPLY_POOL_DATAREADY = '1' and comb_REPLY_POOL_DATA(2 downto 0) = TYPE_DAT then
+          data_counter <= data_counter + 1;
+        end if;
+      end if;
+    end process;
+
+--REPLY select input
+----------------------------------
+  REPLY_ARBITER: trb_net_priority_arbiter
+    generic map (
+      WIDTH => POINT_NUMBER
+      )
+    port map (
+      CLK   => CLK,
+      RESET  => RESET,
+      CLK_EN  => reply_arbiter_CLK_EN,
+      INPUT_IN  => reply_arbiter_input,
+      RESULT_OUT => reply_arbiter_result,
+      ENABLE  => reply_arbiter_enable,  --switched off during DHDR
+      CTRL => (others => '0')
+      );
+
+  reply_arbiter_input  <= REPLY_DATAREADY_IN and not reply_reading_trm and not reply_reading_HDR and not reply_reading_DHDR;
+  reply_arbiter_CLK_EN <= not next_point_lock;
+  REPLY_MUX_reading <= reply_arbiter_result;
+
+
+  -- release is done after first packet of TRM
+  gen_reply_point_lock : process(reply_point_lock, comb_REPLY_muxed_PACKET_NUM,
+                                 REPLY_DATAREADY_IN, comb_REPLY_muxed_DATA, REPLY_MUX_reading)
+    begin
+      next_point_lock <= reply_point_lock;
+      --release lock if TRM is read
+      if comb_REPLY_muxed_PACKET_NUM = c_H0 and or_all(REPLY_MUX_reading and REPLY_DATAREADY_IN) = '1' then
+        if comb_REPLY_muxed_DATA(2 downto 0) = TYPE_TRM then
+          next_point_lock <= '0';
+        else
+          next_point_lock <= '1';
+        end if;
+      end if;
+    end process;
+
+  gen_point_lock : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          reply_point_lock <= '0';
+        else
+          reply_point_lock <=next_point_lock;
+        end if;
+      end if;
+    end process;
+
+
+
+
+
+--REPLY mux
+----------------------------------
+  gen_reply_mux1 : for i in 0 to c_DATA_WIDTH-1 generate
+    data_mux : process(REPLY_DATA_IN, REPLY_MUX_reading,last_header_data, reading_last_hdr)
+      variable tmp_data : std_logic;
+      begin
+        tmp_data := '0';
+        gen_data_mux : for j in 0 to POINT_NUMBER-1 loop
+          tmp_data := tmp_data or (REPLY_DATA_IN(j*c_DATA_WIDTH+i) and REPLY_MUX_reading(j))
+                               or (last_header_data(j*c_DATA_WIDTH+i) and reading_last_hdr(j));
+        end loop;
+        comb_REPLY_muxed_DATA(i) <= tmp_data;
+      end process;
+  end generate;
+
+  gen_reply_mux2 : for i in 0 to c_NUM_WIDTH-1 generate
+    packet_num_mux : process(REPLY_PACKET_NUM_IN, REPLY_MUX_reading,packet_counter, reading_last_hdr)
+      variable tmp_pm : std_logic;
+      begin
+        tmp_pm := '0';
+        gen_pm_mux : for j in 0 to POINT_NUMBER-1 loop
+          tmp_pm := tmp_pm or (REPLY_PACKET_NUM_IN(j*c_NUM_WIDTH+i) and REPLY_MUX_reading(j))
+                           or (packet_counter(i) and reading_last_hdr(j));
+        end loop;
+        comb_REPLY_muxed_PACKET_NUM(i) <= tmp_pm;
+      end process;
+  end generate;
+
+  comb_REPLY_muxed_DATAREADY <= (or_all(reply_arbiter_result and REPLY_DATAREADY_IN and not current_reply_reading_trm  and not current_reply_reading_hdr) or or_all(reading_last_hdr)) and REPLY_POOL_next_read;
+
+
+
+--REPLY POOL state machine
+----------------------------------
+  reply_state_machine : process(REPLY_POOL_next_READ, current_state, packet_counter, REPLY_combined_trm_F0,
+                                send_reply_trm, SEQ_NR, REPLY_combined_trm_F1, REPLY_combined_trm_F2,
+                                comb_REPLY_muxed_DATAREADY, comb_REPLY_muxed_DATA, init_locked,
+                                comb_REPLY_muxed_PACKET_NUM, waiting_for_init_finish, waiting_for_DHDR_word)
+    begin
+      release_locked <= '0';
+      next_state <= current_state;
+      comb_REPLY_POOL_DATAREADY <= '0';
+      comb_REPLY_POOL_PACKET_NUM <= packet_counter;
+      comb_REPLY_POOL_DATA <= (others => '0');
+      next_waiting_for_init_finish <= waiting_for_init_finish;
+      next_waiting_for_DHDR_word <= waiting_for_DHDR_word;
+      hdrram_address <= "000";
+      next_current_waiting_for_reply <= current_waiting_for_reply and not current_reply_reading_HDR;
+      reply_adder_start <= '0';
+      reply_adder_val_enable <= (not locking_point and real_activepoints);
+
+      case current_state is
+        when IDLE =>  --wait for init transfer
+          next_waiting_for_DHDR_word <= not (locking_point or not real_activepoints);
+          if locked = '1' then
+            next_current_waiting_for_reply <= (others => '1');
+            next_state <= WAIT_FOR_HDR_DATA;
+          end if;
+
+        when WAIT_FOR_HDR_DATA =>  --start writing HDR when first reply is received, stop waiting for length
+          case packet_counter is
+            when c_H0 =>
+              comb_REPLY_POOL_DATA <= (others => '0');
+              comb_REPLY_POOL_DATA(2 downto 0) <= TYPE_HDR;
+              comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read and not or_all(current_waiting_for_reply);
+            when c_F0 =>
+              comb_REPLY_POOL_DATA <= MY_ADDRESS_IN;
+              comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read;
+            when c_F1 =>
+              comb_REPLY_POOL_DATA <= x"FFFF"; --sender address is not known!
+              comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read;
+            when c_F2 =>
+              comb_REPLY_POOL_DATAREADY <= '0';
+              hdrram_address <= "011";
+              if or_all(current_reply_reading_HDR or current_waiting_for_reply) = '0' then
+                next_state <= GEN_LENGTH;
+                reply_adder_start <= '1';
+              end if;
+            when others =>
+              null;
+          end case;
+
+        when GEN_LENGTH =>  --now, all HDR are stored, calc sum of HDR lengths
+          hdrram_address <= "011";
+          if reply_adder_ready = '1' then
+            case packet_counter is
+              when c_F2 =>
+                comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read;
+                comb_REPLY_POOL_DATA <= reply_adder_result;
+              when c_F3 =>
+                comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read;
+                comb_REPLY_POOL_DATA <= ????????????????????????????????????????????????????;
+                if REPLY_POOL_next_read = '1' then
+                  next_state <= CHECK_DHDR_0;
+                end if;
+            end case;
+          end if;
+
+        when CHECK_DHDR_0 =>
+          if or_all(waiting_for_DHDR_word) = '0' and REPLY_POOL_next_read = '1' then
+            comb_REPLY_POOL_DATAREADY <= '1';
+            comb_REPLY_POOL_DATA <= combined_DHDR_word;
+            comb_REPLY_POOL_PACKET_NUM <= c_F0;
+            next_waiting_for_DHDR_word <= not (locking_point or not real_activepoints);
+
+          end if;
+        when SENDING_DATA =>
+          comb_REPLY_POOL_DATAREADY  <= comb_REPLY_muxed_DATAREADY;
+          comb_REPLY_POOL_DATA       <= comb_REPLY_muxed_DATA;
+          comb_REPLY_POOL_PACKET_NUM <= comb_REPLY_muxed_PACKET_NUM;
+          if send_reply_trm = '1' then
+            next_state <= SENDING_REPLY_TRM;
+          end if;
+        when SENDING_REPLY_TRM =>
+          comb_REPLY_POOL_DATAREADY <= REPLY_POOL_next_read and not waiting_for_init_finish;
+          if waiting_for_init_finish = '1' and init_locked = '1' then
+            release_locked <= '1';  --release only when init has finished too
+            next_state <= SENDING_DATA;
+            next_waiting_for_init_finish <= '0';
+          end if;
+          case packet_counter is
+            when c_F0 =>
+              comb_REPLY_POOL_DATA <= (others => '0');
+            when c_F1 =>
+              comb_REPLY_POOL_DATA <= REPLY_combined_trm_F1;
+            when c_F2 =>
+              comb_REPLY_POOL_DATA <= REPLY_combined_trm_F2;
+            when c_F3 =>
+              comb_REPLY_POOL_DATA <= REPLY_combined_trm_F3;
+              if REPLY_POOL_next_read = '1' and (init_locked = '1') then
+                release_locked <= '1';  --release only when init has finished too
+                next_state <= IDLE;
+              elsif REPLY_POOL_next_read = '1' and init_locked = '0' then
+                next_waiting_for_init_finish <= '1';
+              end if;
+            when c_H0 | others =>
+              comb_REPLY_POOL_DATA <= (others => '0');
+              comb_REPLY_POOL_DATA(2 downto 0) <= TYPE_TRM;
+            end case;
+      end case;
+    end process;
+
+  reply_fsm_state(0) <= '1' when current_state = IDLE else '0';
+  reply_fsm_state(1) <= '1' when current_state = CHECK_DHDR else '0';
+  reply_fsm_state(2) <= '1' when current_state = SENDING_DATA else '0';
+  reply_fsm_state(3) <= '1' when current_state = SENDING_REPLY_TRM else '0';
+
+  process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          current_state <= SENDING_DATA;
+          REPLY_POOL_next_read <= '0';
+          waiting_for_init_finish <= '0';
+          waiting_for_DHDR_word <= (others => '0');
+          current_waiting_for_reply <= (others => '1');
+        else
+          current_state <= next_state;
+          REPLY_POOL_next_read <= comb_REPLY_POOL_next_read;
+          waiting_for_init_finish <= next_waiting_for_init_finish;
+          waiting_for_DHDR_word <= next_waiting_for_DHDR_word;
+          current_waiting_for_reply <= next_current_waiting_for_reply;
+        end if;
+      end if;
+    end process;
+
+
+--REPLY sbuf
+--------------
+
+  REPLY_POOL_SBUF: trb_net16_sbuf
+    generic map (
+      Version => 0
+      )
+    port map (
+      CLK   => CLK,
+      RESET  => RESET,
+      CLK_EN => CLK_EN,
+      COMB_DATAREADY_IN => comb_REPLY_POOL_DATAREADY,
+      COMB_next_READ_OUT => comb_REPLY_POOL_next_read,
+      COMB_READ_IN => REPLY_POOL_next_read,
+      COMB_DATA_IN => comb_REPLY_POOL_DATA,
+      COMB_PACKET_NUM_IN => comb_REPLY_POOL_PACKET_NUM,
+      SYN_DATAREADY_OUT => REPLY_POOL_DATAREADY,
+      SYN_DATA_OUT => REPLY_POOL_DATA,
+      SYN_PACKET_NUM_OUT => REPLY_POOL_PACKET_NUM,
+      SYN_READ_IN => REPLY_POOL_READ
+      );
+
+--REPLY output
+--------------
+
+  gen_reply_data_out: for i in 0 to POINT_NUMBER-1 generate
+    REPLY_DATAREADY_OUT(i) <= REPLY_POOL_DATAREADY and locking_point(i);
+    REPLY_DATA_OUT((i+1)*c_DATA_WIDTH-1 downto i*c_DATA_WIDTH) <= REPLY_POOL_DATA;
+    REPLY_PACKET_NUM_OUT((i+1)*c_NUM_WIDTH-1 downto i*c_NUM_WIDTH) <= REPLY_POOL_PACKET_NUM;
+  end generate;
+  REPLY_POOL_READ <= or_all(REPLY_READ_IN and locking_point);
+
+
+
+
+----------------------
+--Debugging
+----------------------
+
+  STAT_DEBUG(0) <= got_trm(0);
+  STAT_DEBUG(1) <= got_trm(1);
+  STAT_DEBUG(2) <= REPLY_POOL_DATAREADY;
+  STAT_DEBUG(3) <= REPLY_DATAREADY_IN(0);
+  STAT_DEBUG(4) <= buf_REPLY_READ_OUT(0);
+  STAT_DEBUG(5) <= comb_REPLY_muxed_DATA(14);
+
+  STAT_DEBUG(6) <= REPLY_DATA_IN(14);
+  STAT_DEBUG(7) <= REPLY_DATA_IN(30);
+  STAT_DEBUG(8) <= '0';--REPLY_DATA_IN(46);
+  STAT_DEBUG(9) <= locked;
+  STAT_DEBUG(13 downto 10) <= reply_fsm_state(3 downto 0);
+  STAT_DEBUG(15 downto 14) <= (others => '0');
+  --STAT(15 downto 8) <= data_counter;
+  STAT_POINTS_locked(POINT_NUMBER-1 downto 0) <= not got_trm;
+  STAT_POINTS_locked(31 downto POINT_NUMBER)  <= (others => '0');
+  STAT_ERRORBITS <= REPLY_combined_trm_F1 & REPLY_combined_trm_F2;
+
+
+
+end architecture;
index bb87f205e58c7b3baa237fd6a75e0cbc9f0c9260..2703620d83571893e4b3a131fb9abcdc057cfd99 100644 (file)
@@ -41,6 +41,7 @@ entity trb_net16_ibuf is
     INT_REPLY_READ_IN       : in  std_logic;
     INT_ERROR_OUT           : out std_logic_vector (2 downto 0);
     -- Status and control port
+    STAT_BUFFER_COUNTER     : out std_logic_vector (31 downto 0);
     STAT_BUFFER             : out std_logic_vector (31 downto 0)
     );
 end entity;
@@ -143,6 +144,8 @@ architecture trb_net16_ibuf_arch of trb_net16_ibuf is
   signal fifo_read_before : std_logic;
   signal stat_sbufs : std_logic_vector(1 downto 0);
   signal counter_match : std_logic;
+  signal init_buffer_number : std_logic_vector(15 downto 0);
+  signal reply_buffer_number : std_logic_vector(15 downto 0);
 begin
 
 counter_match <= '1';
@@ -457,7 +460,7 @@ counter_match <= '1';
     end process;
 
   gen_ack1 : if USE_ACKNOWLEDGE = 1 generate
-    reg_locked: process(CLK)
+    proc_reg_eob_out: process(CLK)
       begin
         if rising_edge(CLK) then
           if RESET = '1' then
@@ -469,11 +472,27 @@ counter_match <= '1';
           end if;
         end if;
       end process;
+    proc_count_buffers : process(CLK)
+      begin
+        if rising_edge(CLK) then
+          if RESET = '1' then
+            init_buffer_number <= (others => '1');
+            reply_buffer_number <= (others => '1');
+          elsif CLK_EN = '1' then
+            if got_eob_init_out = '1' then
+              init_buffer_number <= init_buffer_number + 1;
+            end if;
+            if got_eob_reply_out = '1' then
+              reply_buffer_number <= reply_buffer_number + 1;
+            end if;
+          end if;
+        end if;
+      end process;
   end generate;
 
 
 
-
+  STAT_BUFFER_COUNTER <= reply_buffer_number & init_buffer_number;
 
 -- make STAT_BUFFER
   STAT_BUFFER(3 downto 0) <= std_logic_vector(to_unsigned(DEPTH,4));
index a9ac779226ea308eed81fe78582f10b978c2fefb..75d40cba16722bcf094e2d9356bf4d2c8963f83f 100644 (file)
@@ -154,6 +154,7 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is
       INT_REPLY_READ_IN       : in  std_logic;
       INT_ERROR_OUT           : out std_logic_vector (2 downto 0);
       -- Status and control port
+      STAT_BUFFER_COUNTER     : out std_logic_vector (31 downto 0);
       STAT_BUFFER             : out std_logic_vector (31 downto 0)
       );
   end component;
@@ -191,6 +192,7 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is
   signal  INITOBUF_stat_buffer, INITOBUF_ctrl_buffer:  STD_LOGIC_VECTOR (31 downto 0);
   signal  REPLYOBUF_stat_buffer, REPLYOBUF_ctrl_buffer:  STD_LOGIC_VECTOR (31 downto 0);
   signal ibuf_dataready_in, ibuf_read_out   : std_logic;
+  signal STAT_BUFFER_COUNTER : std_logic_vector (31 downto 0);
 
 begin
   GEN_IBUF: if IBUF_DEPTH>0 generate
@@ -226,6 +228,7 @@ begin
         INT_REPLY_PACKET_NUM_OUT => INT_REPLY_PACKET_NUM_OUT,
         INT_REPLY_READ_IN => INT_REPLY_READ_IN,
         INT_ERROR_OUT => IBUF_error,
+        STAT_BUFFER_COUNTER => STAT_BUFFER_COUNTER,
         STAT_BUFFER(31 downto 0) => IBUF_stat_buffer
         );
   end generate;
@@ -375,10 +378,13 @@ STAT_IBUF_BUFFER <= IBUF_stat_buffer;
 
 -- build the CTRL register of the OBUFs
   INITOBUF_ctrl_buffer(9 downto 0) <= IBUF_stat_buffer(9 downto 0);
-  INITOBUF_ctrl_buffer(31 downto 10) <= (others => '0');
+  INITOBUF_ctrl_buffer(15 downto 10) <= (others => '0');
+  INITOBUF_ctrl_buffer(31 downto 16) <= STAT_BUFFER_COUNTER(15 downto 0);
+
   REPLYOBUF_ctrl_buffer(7 downto 0) <= IBUF_stat_buffer(7 downto 0);
   REPLYOBUF_ctrl_buffer(9 downto 8) <= IBUF_stat_buffer(11 downto 10);
-  REPLYOBUF_ctrl_buffer(31 downto 10) <= (others => '0');
+  REPLYOBUF_ctrl_buffer(15 downto 10) <= (others => '0');
+  REPLYOBUF_ctrl_buffer(31 downto 16) <= STAT_BUFFER_COUNTER(31 downto 16);
 
   STAT_GEN  <= (others => '0');
 
index eb2168e91e3f9d8e4d0a76565987f9fe2a55f155..6e289365a39314836a1dd02c769bb0cea0d19f29 100644 (file)
@@ -115,6 +115,8 @@ architecture trb_net16_obuf_arch of trb_net16_obuf is
   signal buf_MED_PACKET_NUM_OUT : std_logic_vector(c_NUM_WIDTH-1 downto 0);
   signal sbuf_status : std_logic;
   signal crc_match : std_logic;
+  signal buffer_number : std_logic_vector(15 downto 0);
+
 
 begin
 --  gen_sbuf : if SECURE_MODE = 1 generate
@@ -208,6 +210,9 @@ begin
         current_ACK_word(3 downto 0) <= SEND_BUFFER_SIZE_IN;
       elsif transfer_counter = c_F2 then
         current_EOB_word(DATA_COUNT_WIDTH-1 downto 0) <= CURRENT_DATA_COUNT;
+      elsif transfer_counter = c_F3 then
+        current_EOB_word(15 downto 0) <= buffer_number;
+        current_ACK_word(15 downto 0) <= CTRL_BUFFER(31 downto 16);
       elsif transfer_counter = c_H0 then
         current_NOP_word(2 downto 0) <= TYPE_ILLEGAL;
         current_ACK_word(2 downto 0) <= TYPE_ACK;
@@ -269,7 +274,6 @@ begin
                                current_ACK_word, current_EOB_word, INT_PACKET_NUM_IN,
                                TRANSMITTED_BUFFERS, send_DATA, comb_next_read)
     begin
-
       current_output_data_buffer <= current_NOP_word;
       current_output_num_buffer  <= transfer_counter;
       next_INT_READ_OUT     <= '1';
@@ -412,12 +416,16 @@ begin
         if rising_edge(CLK) then
           if RESET = '1' then
             TRANSMITTED_BUFFERS <= "00";
+            buffer_number <= (others => '0');
           elsif CLK_EN = '1' then
             if (increase_TRANSMITTED_BUFFERS = '1' and decrease_TRANSMITTED_BUFFERS = '0') then
               TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS +1;
             elsif (increase_TRANSMITTED_BUFFERS = '0' and decrease_TRANSMITTED_BUFFERS = '1') then
               TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS -1;
             end if;
+            if increase_TRANSMITTED_BUFFERS = '1' then
+              buffer_number <= buffer_number + 1;
+            end if;
           end if;
         end if;
       end process;
index 212e72679a687d08b40611e085150dfb43d7f25e..57f059a6163c718c86e632259f9bfe6ec8055f90 100644 (file)
@@ -10,6 +10,7 @@ use work.trb_net_std.all;
 entity trb_net_onewire is
   generic(
     USE_TEMPERATURE_READOUT : integer range 0 to 1 := 1;
+    PARASITIC_MODE : integer range 0 to 1 := c_YES;
     CLK_PERIOD : integer := 10  --clk period in ns
     );
   port(
@@ -28,7 +29,7 @@ end entity;
 
 
 architecture trb_net_onewire_arch of trb_net_onewire is
-  constant MAX_COUNTER : integer := 2**17-1;
+  constant MAX_COUNTER : integer := 2**28-1;
   type state_t is (IDLE, SEND_RESET, WAIT_AFTER_RESET, SEND_ROM_COMMAND, READ_WAIT,
                    WRITE_START, WRITE_WAIT, READ_BIT, READ_READ_ROM, SEND_CONV_TEMP,
                    READ_CONV_TEMP, SEND_READ_TEMP, READ_READ_TEMP);
@@ -53,9 +54,10 @@ architecture trb_net_onewire_arch of trb_net_onewire is
   signal skip_rom, next_skip_rom : std_logic;
   signal buf_TEMP_OUT : std_logic_vector(11 downto 0);
   signal buf_STAT : std_logic;
+  signal strong_pullup, next_strong_pullup : std_logic;
 begin
 
-  ONEWIRE <= '0' when output = '0' else 'Z';
+  ONEWIRE <= '0' when output = '0' else '1' when strong_pullup = '1' else 'Z';
   input <= ONEWIRE;
 
   bitcounter_vector <= conv_std_logic_vector(bitcounter,7);
@@ -77,6 +79,7 @@ begin
       next_reading_temp <= reading_temp;
       next_recv_bit <= recv_bit;
       next_skip_rom <= skip_rom;
+      next_strong_pullup <= '0';
       case state is
 --reset / presence
         when IDLE =>
@@ -128,6 +131,7 @@ begin
           if bitcounter_vector(3) = '1' then  --send 8 bit
             next_state <= READ_CONV_TEMP;
             reset_bitcounter <= '1';
+            reset_timecounter <= '1';
             next_recv_bit <= '0';
           else
             next_state <= WRITE_START;
@@ -164,14 +168,25 @@ begin
 
 --reading sensor answers
         when READ_CONV_TEMP => --waiting for end of conversion
-          if recv_bit = '1' then
-            next_state <= IDLE;
-            if USE_TEMPERATURE_READOUT = 1 then
-              next_conv_temp <= '0';
-              next_reading_temp <= '1';
+          if PARASITIC_MODE = c_NO then
+            if recv_bit = '1' then    --polling device for end of measurement
+              next_state <= IDLE;
+              if USE_TEMPERATURE_READOUT = 1 then
+                next_conv_temp <= '0';
+                next_reading_temp <= '1';
+              end if;
+            else
+              next_state <= READ_BIT;
+            end if;
+          elsif PARASITIC_MODE = c_YES then --waiting 1.3s, then start reading
+            next_strong_pullup <= '1';
+            if is_time_reached(timecounter,130000000,CLK_PERIOD) = '1' then
+              next_state <= IDLE;
+              if USE_TEMPERATURE_READOUT = 1 then
+                next_conv_temp <= '0';
+                next_reading_temp <= '1';
+              end if;
             end if;
-          else
-            next_state <= READ_BIT;
           end if;
 
         when READ_READ_TEMP =>
@@ -271,6 +286,7 @@ begin
           send_bit <= '0';
           output_tmp <= '0';
           recv_bit <= '0';
+          strong_pullup <= '0';
         else
           recv_bit_ready <= next_recv_bit_ready;
           state <= next_state;
@@ -278,6 +294,7 @@ begin
           output <= next_output;
           output_tmp <= next_output_tmp;
           recv_bit <= next_recv_bit;
+          strong_pullup <= next_strong_pullup;
         end if;
       end if;
     end process;
index 5651a8f8abce90dc111d23c6f00c97846c9dcf38..bcb711e7c5d8634e45005b02c4dd05e740e561ae 100644 (file)
@@ -19,6 +19,7 @@ package trb_net_std is
 --assigning channel names
   constant c_TRG_LVL1_CHANNEL  : integer := 0;
   constant c_DATA_CHANNEL      : integer := 1;
+  constant c_IPU_CHANNEL       : integer := 1;
   constant c_UNUSED_CHANNEL    : integer := 2;
   constant c_SLOW_CTRL_CHANNEL : integer := 3;
 
@@ -213,11 +214,12 @@ package body trb_net_std is
   function is_time_reached  (timer : integer; time : integer; period : integer)
     return std_logic is
     variable i : integer range 0 to 1 := 0;
-    variable t : std_logic_vector(16 downto 0) := conv_std_logic_vector(timer,17);
+    variable t : std_logic_vector(27 downto 0) := conv_std_logic_vector(timer,28);
     begin
       i := 0;
       if period = 10 then
         case time is
+          when 130000000 => if t(27) = '1' then i := 1; end if;
           when 640000 => if t(16) = '1' then i := 1; end if;
           when 80000  => if t(13) = '1' then i := 1; end if;
           when 10000  => if t(10) = '1' then i := 1; end if;