]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
first version of trb_net16_iobuf, Jan
authorhadeshyp <hadeshyp>
Fri, 28 Sep 2007 10:28:58 +0000 (10:28 +0000)
committerhadeshyp <hadeshyp>
Fri, 28 Sep 2007 10:28:58 +0000 (10:28 +0000)
trb_net16_iobuf.vhd
trb_net16_obuf.vhd
trb_net16_term_ibuf.vhd
trb_net_term_ibuf.vhd

index 05bbe9592ab95ce81d4488238d623b99373cdf40..87c7479e9df40a86eb6b6f4e6253b08176f13f43 100644 (file)
@@ -13,8 +13,8 @@ use work.trb_net_std.all;
 entity trb_net16_iobuf is
   generic (
     --FIFO size is given in 2^(n+1) 64Bit-packets i.e. 2^(n+3) 16bit packets
-    INIT_DEPTH : integer := 3;
-    REPLY_DEPTH : integer := 3);
+    INIT_DEPTH : integer := 2;
+    REPLY_DEPTH : integer := 2);
   port(
     --  Misc
     CLK    : in std_logic;
@@ -87,7 +87,7 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is
 
   component trb_net16_obuf is
     generic (
-      DATA_COUNT_WIDTH : integer := 4;
+      DATA_COUNT_WIDTH : integer := 5
       );
     port(
       --  Misc
@@ -124,14 +124,14 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is
       --  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 (15 downto 0); -- Data word
-      MED_PACKET_NUM_IN :out std_logic_vector(1 downto 0);
+      MED_PACKET_NUM_IN :in  std_logic_vector(1 downto 0);
       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 (15 downto 0); -- Data word
-      INT_PACKET_NUM_IN: in  std_logic_vector(1 downto 0);
+      INT_PACKET_NUM_OUT:out std_logic_vector(1 downto 0);
       INT_READ_IN:       in  std_logic;
       INT_ERROR_OUT:     out std_logic_vector (2 downto 0);  -- Status bits
       -- Status and control port
@@ -141,9 +141,280 @@ architecture trb_net16_iobuf_arch of trb_net16_iobuf is
       );
   end component;
 
+  component trb_net16_term_ibuf is
+    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 (15 downto 0); -- Data word
+      MED_PACKET_NUM_IN: in  std_logic_vector (1 downto 0);
+      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 (15 downto 0); -- Data word
+      INT_PACKET_NUM_OUT:out std_logic_vector (1 downto 0);
+      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 component;
+  
+  -- internal signals for the INITIBUF
+  signal  INITIBUF_error:    STD_LOGIC_VECTOR (2 downto 0);  -- error watch needed!
+  signal  INITIBUF_stat_locked, INITIBUF_ctrl_locked: STD_LOGIC_VECTOR (15 downto 0);
+  signal  INITIBUF_stat_buffer  :  STD_LOGIC_VECTOR (31 downto 0);
+
+  -- internal signals for the REPLYIBUF
+  signal  REPLYIBUF_error:    STD_LOGIC_VECTOR (2 downto 0); -- error watch needed!
+  signal  REPLYIBUF_stat_locked, REPLYIBUF_ctrl_locked: STD_LOGIC_VECTOR (15 downto 0);
+  signal  REPLYIBUF_stat_buffer  :  STD_LOGIC_VECTOR (31 downto 0);
+
+  -- internal signals for the INITOBUF
+  signal  INITOBUF_stat_locked, INITOBUF_ctrl_locked: STD_LOGIC_VECTOR (15 downto 0);
+  signal  INITOBUF_stat_buffer, INITOBUF_ctrl_buffer:  STD_LOGIC_VECTOR (31 downto 0);
+
+  -- internal signals for the REPLYOBUF
+  signal  REPLYOBUF_stat_locked, REPLYOBUF_ctrl_locked: STD_LOGIC_VECTOR (15 downto 0);
+  signal  REPLYOBUF_stat_buffer, REPLYOBUF_ctrl_buffer:  STD_LOGIC_VECTOR (31 downto 0);
+
+-- locking control
+  signal  INIT_IS_LOCKED,  REPLY_IS_LOCKED: STD_LOGIC;
+  signal  next_INIT_IS_LOCKED,  next_REPLY_IS_LOCKED: STD_LOGIC;
 
 begin
+  GEN_IBUF: if INIT_DEPTH>0 generate
+    INITIBUF : trb_net16_ibuf
+      generic map (
+        DEPTH => INIT_DEPTH)
+      port map (
+        CLK       => CLK,
+        RESET     => RESET,
+        CLK_EN    => CLK_EN,
+        MED_DATAREADY_IN => MED_INIT_DATAREADY_IN,
+        MED_DATA_IN => MED_INIT_DATA_IN,
+        MED_PACKET_NUM_IN => MED_INIT_PACKET_NUM_IN,
+        MED_READ_OUT => MED_INIT_READ_OUT,
+        MED_ERROR_IN => MED_INIT_ERROR_IN,
+        INT_HEADER_IN => '0',
+        INT_DATAREADY_OUT => INT_INIT_DATAREADY_OUT,
+        INT_DATA_OUT => INT_INIT_DATA_OUT,
+        INT_PACKET_NUM_OUT => INT_INIT_PACKET_NUM_OUT,
+        INT_READ_IN => INT_INIT_READ_IN,
+        INT_ERROR_OUT => INITIBUF_error,
+        STAT_LOCKED(15 downto 0) => INITIBUF_stat_locked,
+        CTRL_LOCKED(15 downto 0) => INITIBUF_ctrl_locked,
+        STAT_BUFFER(31 downto 0) => INITIBUF_stat_buffer
+        );
+    REPLYIBUF : trb_net16_ibuf
+      generic map (
+        DEPTH => REPLY_DEPTH)
+      port map (
+        CLK       => CLK,
+        RESET     => RESET,
+        CLK_EN    => CLK_EN,
+        MED_DATAREADY_IN => MED_REPLY_DATAREADY_IN,
+        MED_DATA_IN => MED_REPLY_DATA_IN,
+        MED_PACKET_NUM_IN => MED_REPLY_PACKET_NUM_IN,
+        MED_READ_OUT => MED_REPLY_READ_OUT,
+        MED_ERROR_IN => MED_REPLY_ERROR_IN,
+        INT_HEADER_IN => INT_REPLY_HEADER_IN,
+        INT_DATAREADY_OUT => INT_REPLY_DATAREADY_OUT,
+        INT_DATA_OUT => INT_REPLY_DATA_OUT,
+        INT_PACKET_NUM_OUT => INT_REPLY_PACKET_NUM_OUT,
+        INT_READ_IN => INT_REPLY_READ_IN,
+        INT_ERROR_OUT => REPLYIBUF_error,
+        STAT_LOCKED(15 downto 0) => REPLYIBUF_stat_locked,
+        CTRL_LOCKED(15 downto 0) => REPLYIBUF_ctrl_locked,
+        STAT_BUFFER(31 downto 0) => REPLYIBUF_stat_buffer
+        );
+  end generate;
 
+  GEN_TERM_IBUF: if INIT_DEPTH=0 generate
+    INITIBUF : trb_net16_term_ibuf
+      port map (
+        CLK       => CLK,
+        RESET     => RESET,
+        CLK_EN    => CLK_EN,
+        MED_DATAREADY_IN => MED_INIT_DATAREADY_IN,
+        MED_DATA_IN => MED_INIT_DATA_IN,
+        MED_PACKET_NUM_IN => MED_INIT_PACKET_NUM_IN,
+        MED_READ_OUT => MED_INIT_READ_OUT,
+        MED_ERROR_IN => MED_INIT_ERROR_IN,
+        INT_HEADER_IN => '0',
+        INT_DATAREADY_OUT => INT_INIT_DATAREADY_OUT,
+        INT_DATA_OUT => INT_INIT_DATA_OUT,
+        INT_PACKET_NUM_OUT => INT_INIT_PACKET_NUM_OUT,
+        INT_READ_IN => INT_INIT_READ_IN,
+        INT_ERROR_OUT => INITIBUF_error,
+        STAT_LOCKED(15 downto 0) => INITIBUF_stat_locked,
+        CTRL_LOCKED(15 downto 0) => INITIBUF_ctrl_locked,
+        STAT_BUFFER(31 downto 0) => INITIBUF_stat_buffer
+        );
+    REPLYIBUF : trb_net16_term_ibuf
+      port map (
+        CLK       => CLK,
+        RESET     => RESET,
+        CLK_EN    => CLK_EN,
+        MED_DATAREADY_IN => MED_REPLY_DATAREADY_IN,
+        MED_DATA_IN => MED_REPLY_DATA_IN,
+        MED_PACKET_NUM_IN => MED_REPLY_PACKET_NUM_IN,
+        MED_READ_OUT => MED_REPLY_READ_OUT,
+        MED_ERROR_IN => MED_REPLY_ERROR_IN,
+        INT_HEADER_IN => INT_REPLY_HEADER_IN,
+        INT_DATAREADY_OUT => INT_REPLY_DATAREADY_OUT,
+        INT_DATA_OUT => INT_REPLY_DATA_OUT,
+        INT_PACKET_NUM_OUT => INT_REPLY_PACKET_NUM_OUT,
+        INT_READ_IN => INT_REPLY_READ_IN,
+        INT_ERROR_OUT => REPLYIBUF_error,
+        STAT_LOCKED(15 downto 0) => REPLYIBUF_stat_locked,
+        CTRL_LOCKED(15 downto 0) => REPLYIBUF_ctrl_locked,
+        STAT_BUFFER(31 downto 0) => REPLYIBUF_stat_buffer
+        );
+  end generate;
 
-end architecture;
+  INITOBUF : trb_net16_obuf
+
+--    generic map (
+--      DATA_COUNT_WIDTH => 16
+--      )
+    port map (
+      CLK       => CLK,
+      RESET     => RESET,
+      CLK_EN    => CLK_EN,
+      MED_DATAREADY_OUT => MED_INIT_DATAREADY_OUT,
+      MED_DATA_OUT => MED_INIT_DATA_OUT,
+      MED_PACKET_NUM_OUT => MED_INIT_PACKET_NUM_OUT,
+      MED_READ_IN => MED_INIT_READ_IN,
+      INT_DATAREADY_IN => INT_INIT_DATAREADY_IN,
+      INT_DATA_IN => INT_INIT_DATA_IN,
+      INT_PACKET_NUM_IN => INT_INIT_PACKET_NUM_IN,
+      INT_READ_OUT => INT_INIT_READ_OUT,
+      STAT_LOCKED(15 downto 0) => INITOBUF_stat_locked,
+      CTRL_LOCKED(15 downto 0) => INITOBUF_ctrl_locked,
+      STAT_BUFFER(31 downto 0) => INITOBUF_stat_buffer,
+      CTRL_BUFFER(31 downto 0) => INITOBUF_ctrl_buffer
+      );
+
+  REPLYOBUF : trb_net16_obuf
+--    generic map (
+--      DATA_COUNT_WIDTH => 16
+--      )
+    port map (
+      CLK       => CLK,
+      RESET     => RESET,
+      CLK_EN    => CLK_EN,
+      MED_DATAREADY_OUT => MED_REPLY_DATAREADY_OUT,
+      MED_DATA_OUT => MED_REPLY_DATA_OUT,
+      MED_PACKET_NUM_OUT => MED_REPLY_PACKET_NUM_OUT,
+      MED_READ_IN => MED_REPLY_READ_IN,
+      INT_DATAREADY_IN => INT_REPLY_DATAREADY_IN,
+      INT_DATA_IN => INT_REPLY_DATA_IN,
+      INT_PACKET_NUM_IN => INT_REPLY_PACKET_NUM_IN,
+      INT_READ_OUT => INT_REPLY_READ_OUT,
+      STAT_LOCKED(15 downto 0) => REPLYOBUF_stat_locked,
+      CTRL_LOCKED(15 downto 0) => REPLYOBUF_ctrl_locked,
+      STAT_BUFFER(31 downto 0) => REPLYOBUF_stat_buffer,
+      CTRL_BUFFER(31 downto 0) => REPLYOBUF_ctrl_buffer
+      );
+
+
+-- build the registers according to the wiki page
+  STAT_INIT_BUFFER(11 downto 0) <= INITIBUF_stat_buffer(11 downto 0);
+  STAT_INIT_BUFFER(15 downto 14) <= INITOBUF_stat_buffer(1 downto 0);
+  STAT_INIT_BUFFER(31 downto 16) <= INITOBUF_stat_buffer(31 downto 16);
+  STAT_REPLY_BUFFER(11 downto 0) <= REPLYIBUF_stat_buffer(11 downto 0);
+  STAT_REPLY_BUFFER(15 downto 14) <= REPLYOBUF_stat_buffer(1 downto 0);
+  STAT_REPLY_BUFFER(31 downto 16) <= REPLYOBUF_stat_buffer(31 downto 16);
+
+-- build the CTRL register of the OBUFs
+  INITOBUF_ctrl_buffer(9 downto 0) <= INITIBUF_stat_buffer(9 downto 0);
+  INITOBUF_ctrl_buffer(31 downto 10) <= (others => '0');
+  REPLYOBUF_ctrl_buffer(9 downto 0) <= REPLYIBUF_stat_buffer(9 downto 0);
+  REPLYOBUF_ctrl_buffer(31 downto 10) <= (others => '0');
+
+  STAT_LOCKED(0) <= INIT_IS_LOCKED;
+  STAT_LOCKED(1) <= REPLY_IS_LOCKED;
+  STAT_LOCKED(31 downto 2) <= (others => '0');
+
+  REPLYOBUF_ctrl_locked(15 downto 2) <= (others => '0');
+  REPLYIBUF_ctrl_locked(15 downto 2) <= (others => '0');
+  INITOBUF_ctrl_locked(15 downto 2) <= (others => '0');
+  INITIBUF_ctrl_locked(15 downto 2) <= (others => '0');
+
+-- comb part of the locking control
+  comb_locked : process (INIT_IS_LOCKED, REPLY_IS_LOCKED, INITIBUF_stat_locked,
+                       REPLYOBUF_stat_locked, REPLYIBUF_stat_locked,
+                       INITOBUF_stat_locked,  CTRL_LOCKED)
+    
+    begin  -- process
+      next_INIT_IS_LOCKED <= INIT_IS_LOCKED;
+      next_REPLY_IS_LOCKED <= REPLY_IS_LOCKED;
+      REPLYOBUF_ctrl_locked(1 downto 0) <= (others => '0');
+      REPLYIBUF_ctrl_locked(1 downto 0) <= (others => '0');
+      INITOBUF_ctrl_locked(1 downto 0) <= (others => '0');
+      INITIBUF_ctrl_locked(1 downto 0) <= (others => '0');
   
+      if REPLY_IS_LOCKED = '1' then
+        -- listen to INITOBUF
+        if INITOBUF_stat_locked(0) = '1' or CTRL_LOCKED(1) = '1' then
+          next_REPLY_IS_LOCKED <= '0';
+          REPLYIBUF_ctrl_locked(0) <= '1';
+        else
+          next_REPLY_IS_LOCKED <= '1';
+        end if;
+      else
+        -- listen to REPLYIBUF itself
+        if REPLYIBUF_stat_locked(0) = '1' then
+          next_REPLY_IS_LOCKED <= '1';
+          INITOBUF_ctrl_locked(0) <= '1';        
+        else
+          next_REPLY_IS_LOCKED <= '0';
+        end if;
+      end if;   
+      
+      if INIT_IS_LOCKED = '1' then
+        -- listen to REPLYOBUF
+        if REPLYOBUF_stat_locked(0) = '1' or CTRL_LOCKED(0) = '1' then
+          next_INIT_IS_LOCKED <= '0';
+          INITIBUF_ctrl_locked(0) <= '1';
+        else
+          next_INIT_IS_LOCKED <= '1';
+        end if;
+      else
+        -- listen to INITIBUF itself
+        if INITIBUF_stat_locked(0) = '1' then
+          next_INIT_IS_LOCKED <= '1';
+          REPLYOBUF_ctrl_locked(0) <= '1';        
+        else
+          next_INIT_IS_LOCKED <= '0';
+  
+        end if;
+      end if;  
+  
+    end process;
+
+  reg_locked: process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          INIT_IS_LOCKED <= '0';
+          REPLY_IS_LOCKED <= '1';
+        elsif CLK_EN = '1' then
+          INIT_IS_LOCKED <= next_INIT_IS_LOCKED;
+          REPLY_IS_LOCKED <= next_REPLY_IS_LOCKED;
+        else
+          INIT_IS_LOCKED <= INIT_IS_LOCKED;
+          REPLY_IS_LOCKED <= REPLY_IS_LOCKED;
+        end if;
+      end if;
+    end process;
+
+end architecture;
index 4883d56ceb07b89f1e1cd606461d5576064f158b..ef7410a4f9462722eb9f6716f7775071c62846f7 100644 (file)
@@ -2,15 +2,15 @@
 -- http://hades-wiki.gsi.de/cgi-bin/view/DaqSlowControl/TrbNetOBUF
 
 LIBRARY IEEE;
-USE IEEE.STD_LOGIC_1164.ALL;
-USE IEEE.STD_LOGIC_ARITH.ALL;
-USE IEEE.STD_LOGIC_UNSIGNED.ALL;
+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 trb_net16_obuf is
   generic (
-    DATA_COUNT_WIDTH : integer := 4;
+    DATA_COUNT_WIDTH : integer := 5
     );
   port(
     --  Misc
@@ -18,20 +18,20 @@ entity trb_net16_obuf is
     RESET  : in std_logic;     
     CLK_EN : in std_logic;
     --  Media direction port
-    MED_DATAREADY_OUT: out STD_LOGIC;
-    MED_DATA_OUT:      out STD_LOGIC_VECTOR (15 downto 0); -- Data word
-    MED_PACKET_NUM_OUT:out STD_LOGIC_VECTOR(1 downto 0);
-    MED_READ_IN:       in  STD_LOGIC; 
+    MED_DATAREADY_OUT: out std_logic;
+    MED_DATA_OUT:      out std_logic_vector (15 downto 0); -- Data word
+    MED_PACKET_NUM_OUT:out std_logic_vector(1 downto 0);
+    MED_READ_IN:       in  std_logic;
     -- Internal direction port
-    INT_DATAREADY_IN:  in  STD_LOGIC; 
-    INT_DATA_IN:       in  STD_LOGIC_VECTOR (15 downto 0); -- Data word
-    INT_PACKET_NUM_IN: in STD_LOGIC_VECTOR(1 downto 0);
-    INT_READ_OUT:      out STD_LOGIC; 
+    INT_DATAREADY_IN:  in  std_logic;
+    INT_DATA_IN:       in  std_logic_vector (15 downto 0); -- Data word
+    INT_PACKET_NUM_IN: in std_logic_vector(1 downto 0);
+    INT_READ_OUT:      out std_logic;
     -- 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);
-    CTRL_BUFFER:       in  STD_LOGIC_VECTOR (31 downto 0)
+    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);
+    CTRL_BUFFER:       in  std_logic_vector (31 downto 0)
     );
 end entity;
 
@@ -40,32 +40,308 @@ architecture trb_net16_obuf_arch of trb_net16_obuf is
   component trb_net16_sbuf is
     generic (
       DATA_WIDTH : integer := 16;
-      NUM_WIDTH  integer := 2;
-      VERSION : integer := 0
+      NUM_WIDTH  : integer := 2;
+      VERSION    : integer := 0
       );
     port(
       --  Misc
-      CLK    : in std_logic;           
-      RESET  : in std_logic;   
+      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 (DATA_WIDTH-1 downto 0); -- Data word
-      COMB_PACKET_NUM_IN: in STD_LOGIC_VECTOR(NUM_WIDTH-1 downto 0);
+      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 (DATA_WIDTH-1 downto 0); -- Data word
+      COMB_PACKET_NUM_IN: in  std_logic_vector(NUM_WIDTH-1 downto 0);
       -- 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_PACKET_NUM_OUT: out STD_LOGIC_VECTOR(NUM_WIDTH-1 downto 0);
-      SYN_READ_IN:        in  STD_LOGIC; 
+      SYN_DATAREADY_OUT:  out std_logic;
+      SYN_DATA_OUT:       out std_logic_vector (DATA_WIDTH-1 downto 0); -- Data word
+      SYN_PACKET_NUM_OUT: out std_logic_vector(NUM_WIDTH-1 downto 0);
+      SYN_READ_IN:        in  std_logic;
       -- Status and control port
-      STAT_BUFFER:        out STD_LOGIC
+      STAT_BUFFER:        out std_logic
       );
   end component;
 
-  begin
+  signal current_output_data_buffer : STD_LOGIC_VECTOR (15 downto 0);
+  signal current_output_num_buffer : STD_LOGIC_VECTOR (1 downto 0);
+  signal current_ACK_word, current_EOB_word, current_DATA_word, current_NOP_word :
+    STD_LOGIC_VECTOR (15 downto 0);
+  signal comb_dataready, comb_next_read, comb_read ,sbuf_free: STD_LOGIC;
+  signal reg_INT_READ_OUT , next_INT_READ_OUT:STD_LOGIC;
+  
+  signal next_SEND_ACK_IN, reg_SEND_ACK_IN : STD_LOGIC;
+  signal send_ACK, send_EOB, send_DATA : STD_LOGIC;
+
+  signal CURRENT_DATA_COUNT, next_DATA_COUNT : STD_LOGIC_VECTOR (DATA_COUNT_WIDTH-1  downto 0);
+--  signal max_DATA_COUNT, next_max_DATA_COUNT : STD_LOGIC_VECTOR (15 downto 0);
+  signal max_DATA_COUNT_minus_one, next_max_DATA_COUNT_minus_one : STD_LOGIC_VECTOR (DATA_COUNT_WIDTH-1 downto 0);
+  signal max_DATA_COUNT_minus_two, next_max_DATA_COUNT_minus_two : STD_LOGIC_VECTOR (DATA_COUNT_WIDTH-1 downto 0);
+  signal TRANSMITTED_BUFFERS, next_TRANSMITTED_BUFFERS : STD_LOGIC_VECTOR (1 downto 0);
+  signal increase_TRANSMITTED_BUFFERS, decrease_TRANSMITTED_BUFFERS : STD_LOGIC;
 
+  signal SEND_BUFFER_SIZE_IN : STD_LOGIC_VECTOR (3 downto 0);
+  signal REC_BUFFER_SIZE_IN  : STD_LOGIC_VECTOR (3 downto 0);
+  signal SEND_ACK_IN         : STD_LOGIC;
+  signal GOT_ACK_IN          : STD_LOGIC;
+  
+  signal is_locked, got_locked,release_locked : std_logic;
 
-end architecture;
+  type transfer_state_t is (IDLE, SENDING_DATA, SENDING_ACK, SENDING_EOB);
+  signal transfer_state, next_transfer_state : transfer_state_t;
+  signal transfer_counter    : std_logic_vector(1 downto 0);
+  signal saved_packet_type   : std_logic_vector(2 downto 0);
   
+begin
+
+  SBUF: trb_net16_sbuf
+    generic map (
+      DATA_WIDTH => 16,
+      NUM_WIDTH  => 2,
+      VERSION => 0
+      )
+    port map (
+      CLK   => CLK,
+      RESET  => RESET,
+      CLK_EN => CLK_EN,
+      COMB_DATAREADY_IN => comb_dataready,
+      COMB_next_READ_OUT => comb_next_read,
+      COMB_READ_IN => comb_read,
+      COMB_DATA_IN => current_output_data_buffer,
+      COMB_PACKET_NUM_IN => current_output_num_buffer,
+      SYN_DATAREADY_OUT => MED_DATAREADY_OUT,
+      SYN_DATA_OUT => MED_DATA_OUT,
+      SYN_PACKET_NUM_OUT => MED_PACKET_NUM_OUT,
+      SYN_READ_IN => MED_READ_IN
+      );
+
+  decrease_TRANSMITTED_BUFFERS <= GOT_ACK_IN;
+  comb_read    <= '1';
+  INT_READ_OUT <= reg_INT_READ_OUT;
+  sbuf_free    <= comb_next_read;
+
+  send_ACK     <= SEND_ACK_IN or reg_SEND_ACK_IN;
+  send_DATA    <= '1' when (TRANSMITTED_BUFFERS(1) = '0') else '0';
+  send_EOB     <= '1' when (CURRENT_DATA_COUNT = max_DATA_COUNT_minus_one) else '0';
+
+
+  -- buffer registers
+  STAT_BUFFER(1 downto 0)   <= TRANSMITTED_BUFFERS;
+  STAT_BUFFER(15 downto 2)  <= (others => '0');
+  STAT_BUFFER(31 downto 16) <= CURRENT_DATA_COUNT;
+  SEND_BUFFER_SIZE_IN       <= CTRL_BUFFER(3 downto 0);
+  REC_BUFFER_SIZE_IN        <= CTRL_BUFFER(7 downto 4);
+  SEND_ACK_IN               <= CTRL_BUFFER(8);
+  GOT_ACK_IN                <= CTRL_BUFFER(9);
+
+
+
+  GENERATE_WORDS : process(transfer_counter, SEND_BUFFER_SIZE_IN)
+    begin
+      current_NOP_word  <= (others => '0');
+      current_ACK_word  <= (others => '0');
+      current_EOB_word  <= (others => '0');
+      current_DATA_word <= INT_DATA_IN;
+      if transfer_counter = "10" then
+        current_ACK_word(3 downto 0) <= SEND_BUFFER_SIZE_IN;
+      end if;
+      if transfer_counter = "00" then
+        current_NOP_word(2 downto 0) <= TYPE_ILLEGAL;
+        current_ACK_word(2 downto 0) <= TYPE_ACK;
+        current_EOB_word(2 downto 0) <= TYPE_EOB;
+      end if;
+    end process;
+
+  REG_TRANSFER_COUNTER : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          transfer_counter <= (others => '0');
+        elsif comb_dataready = '1' then
+          transfer_counter <= transfer_counter + 1;
+        end if;
+      end if;
+    end process;
+
+  SAVE_PACKET_TYPE : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          saved_packet_type <= TYPE_ILLEGAL;
+        elsif transfer_counter <= "00" and comb_dataready = '1' then
+          saved_packet_type <= current_output_data_buffer(2 downto 0);
+        end if;
+      end if;
+    end process;
+
+  --since we count only 64Bit packets, each counter is updated on the last packet
+  --the EOB and ACK flags must be available when the last packet is sent.
+  --full buffers (despite the sbuf) can only occur on the last packet.
+  COMB_NEXT_TRANSFER : process(transfer_state, comb_dataready, transfer_counter, current_NOP_word,
+                               CURRENT_DATA_COUNT, reg_SEND_ACK_IN, INT_DATAREADY_IN, INT_DATA_IN,
+                               reg_INT_READ_OUT, reg_SEND_ACK_IN, saved_packet_type )
+    begin
+      if transfer_counter = "11" and comb_dataready = '1' then
+        next_transfer_state <= IDLE;
+      else
+        next_transfer_state <= transfer_state;
+      end if;
+
+      current_output_data_buffer <= current_NOP_word;
+      current_output_num_buffer  <= transfer_counter;
+      next_INT_READ_OUT     <= '1';
+      increase_TRANSMITTED_BUFFERS <= '0';
+      next_DATA_COUNT    <= CURRENT_DATA_COUNT;
+      next_SEND_ACK_IN   <= reg_SEND_ACK_IN;
+      comb_dataready     <= '0';
+
+      if (reg_INT_READ_OUT = '1' and  INT_DATAREADY_IN = '1') then
+                                      --can only happen if idle or sending_data
+        next_transfer_state   <= SENDING_DATA;
+        current_output_data_buffer <= current_DATA_word;
+        comb_dataready        <= '1';          --I hope sbuf can store
+        if saved_packet_type = TYPE_TRM and transfer_counter = "11" then  --TRM means EOB
+          next_DATA_COUNT <= (others => '0');
+          increase_TRANSMITTED_BUFFERS <= '1';
+        else
+          next_DATA_COUNT <= CURRENT_DATA_COUNT +1;
+        end if;
+        if (send_ACK = '1'  or send_EOB = '1' ) then
+          if transfer_counter = "11" then  --finish running packet, then stop.
+            next_INT_READ_OUT       <= '0';
+          end if;
+        end if;
+        if send_ACK = '1' then        --BUGBUG: next_SEND_ACK_IN should be a counter (2 may arrive)
+                                      --no real problem due to same speed of transmission
+          next_SEND_ACK_IN   <= '1';
+        end if;
+      elsif (send_ACK = '1' or transfer_state = SENDING_ACK) then
+        if not (transfer_counter = "11" and comb_dataready = '1') then
+          next_transfer_state <= SENDING_ACK;
+        end if;
+        next_INT_READ_OUT     <= '0';
+        if sbuf_free = '1' then
+          current_output_data_buffer <= current_ACK_word;
+          next_SEND_ACK_IN      <= '0';
+          comb_dataready        <= '1';
+        end if;
+      elsif send_EOB = '1' or transfer_state = SENDING_EOB then
+        if not (transfer_counter = "11" and comb_dataready = '1') then
+          next_transfer_state <= SENDING_EOB;
+        else
+          next_DATA_COUNT       <= (others => '0');
+          increase_TRANSMITTED_BUFFERS <= '1';
+        end if;
+        next_INT_READ_OUT     <= '0';
+        if sbuf_free = '1' then
+          current_output_data_buffer <= current_EOB_word;
+          comb_dataready        <= '1';
+        end if;
+      end if;
+      if send_data = '0' or           --block reading if two buffers have been sent or current buffer runs full
+        ((current_DATA_COUNT(DATA_COUNT_WIDTH-1 downto 0) = (max_DATA_COUNT_minus_two(DATA_COUNT_WIDTH-1 downto 0)))
+          and reg_INT_READ_OUT = '1' and  INT_DATAREADY_IN = '1' ) --and INT_DATA_IN(TYPE_POSITION) = TYPE_TRM
+                                                 --long version of (next_count = max_count-1)
+          or (next_TRANSMITTED_BUFFERS(1) = '1')
+          or sbuf_free = '0' then
+        next_INT_READ_OUT       <= '0';
+      end if;
+    end process;
+
+
+  REG : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          reg_SEND_ACK_IN       <= '0';
+          CURRENT_DATA_COUNT    <= (others => '0');
+          reg_INT_READ_OUT      <= '0';
+          transfer_state        <= IDLE;
+        elsif CLK_EN = '1' then
+          reg_SEND_ACK_IN       <= next_SEND_ACK_IN; 
+          CURRENT_DATA_COUNT    <= next_DATA_COUNT;
+          reg_INT_READ_OUT      <= next_INT_READ_OUT;
+          transfer_state        <= next_transfer_state;
+        end if;
+      end if;
+    end process;
+
+
+  next_max_DATA_COUNT_minus_one <= "0000000000000011" when REC_BUFFER_SIZE_IN="0001" else
+                                   "0000000000000111" when REC_BUFFER_SIZE_IN="0010" else
+                                   "0000000000001111" when REC_BUFFER_SIZE_IN="0011" else
+                                   "0000000000011111" when REC_BUFFER_SIZE_IN="0100" else
+                                   "0000000000000001";
+  next_max_DATA_COUNT_minus_two <= "0000000000000010" when REC_BUFFER_SIZE_IN="0001" else
+                                   "0000000000000110" when REC_BUFFER_SIZE_IN="0010" else
+                                   "0000000000001110" when REC_BUFFER_SIZE_IN="0011" else
+                                   "0000000000011110" when REC_BUFFER_SIZE_IN="0100" else
+                                   "0000000000000000";
+
+  reg_max_DATA_COUNT : process(CLK)
+    begin
+    if rising_edge(CLK) then
+      if RESET = '1' then
+        max_DATA_COUNT_minus_one(0) <= '1';
+        max_DATA_COUNT_minus_one(DATA_COUNT_WIDTH-1 downto 1) <= (others => '0');
+        max_DATA_COUNT_minus_two(DATA_COUNT_WIDTH-1 downto 0) <= (others => '0');
+      else
+        max_DATA_COUNT_minus_one <= next_max_DATA_COUNT_minus_one(DATA_COUNT_WIDTH-1 downto 0);
+        max_DATA_COUNT_minus_two <= next_max_DATA_COUNT_minus_two(DATA_COUNT_WIDTH-1 downto 0);
+      end if;
+    end if;
+  end process;
+
+  comb_TRANSMITTED_BUFFERS : process (increase_TRANSMITTED_BUFFERS, decrease_TRANSMITTED_BUFFERS, TRANSMITTED_BUFFERS)
+    begin
+      if (increase_TRANSMITTED_BUFFERS = '1' and decrease_TRANSMITTED_BUFFERS = '0') then
+        next_TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS +1;
+      elsif (increase_TRANSMITTED_BUFFERS = '0' and decrease_TRANSMITTED_BUFFERS = '1') then
+        next_TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS -1;
+      else
+        next_TRANSMITTED_BUFFERS <= TRANSMITTED_BUFFERS;
+      end if;
+    end process;
+
+  reg_TRANSMITTED_BUFFERS : process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          TRANSMITTED_BUFFERS <= "00";
+        elsif CLK_EN = '1' then
+          TRANSMITTED_BUFFERS <= next_TRANSMITTED_BUFFERS;
+        end if;
+      end if;
+    end process;
+
+  comb_locked : process (MED_READ_IN, saved_packet_type, transfer_counter, release_locked, is_locked)
+    begin  -- process
+      got_locked  <= is_locked;
+      if MED_READ_IN = '1' then
+        if saved_packet_type = TYPE_TRM and transfer_counter = "11" and release_locked = '0' then
+          got_locked  <= '1';
+        elsif release_locked = '1' then
+          got_locked <= '0';
+        end if;
+      elsif release_locked = '1' then
+        got_locked <= '0';
+      end if;
+    end process;
+
+  release_locked <= CTRL_LOCKED(0);
+  STAT_LOCKED(0) <= is_locked;
+  STAT_LOCKED(15 downto 1) <= (others => '0');
+
+  reg_locked: process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          is_locked <= '0';
+        elsif CLK_EN = '1' then
+          is_locked <= got_locked;
+        end if;
+      end if;
+    end process;
+
+end architecture;
\ No newline at end of file
index deb0737f3496a95b8077ab775303a2e6c5098bf9..da099adb6b87c718a46b058e9792a460168380bf 100644 (file)
@@ -23,7 +23,7 @@ entity trb_net16_term_ibuf is
     --  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 (15 downto 0); -- Data word
-    MED_PACKET_NUM_IN :out std_logic_vector(1 downto 0);
+    MED_PACKET_NUM_IN :in  std_logic_vector(1 downto 0);
     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
@@ -79,75 +79,95 @@ architecture trb_net16_term_ibuf_arch of trb_net16_term_ibuf is
   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);
+  signal current_packet_type, saved_packet_type : std_logic_vector(2 downto 0);
+  
                                       -- buffer size control
 begin
 
-this process has to be converted to 16 Bit
-------------------------------------------
-
-
--- -- this process controls the writing of the media into the fifo
---     FILTER_DATAREADY_IN : process(MED_DATA_IN, MED_DATAREADY_IN, MED_ERROR_IN,
---                                   is_locked, current_rec_buffer_size_out,
---                                   current_error_state, release_locked,
---                                   sbuf_free)
---     begin  -- process
---       got_ack_internal <=   '0';
---       next_rec_buffer_size_out <= current_rec_buffer_size_out;
---       next_error_state <= current_error_state;
---       tmp_INT_DATA_OUT <= (others => '1');
---       tmp_INT_DATAREADY_OUT <= '0';
---       got_eob_out <= '0';
---       got_locked  <= is_locked;
---       
---       if MED_DATAREADY_IN = '1' then    -- data word offered
---         if MED_DATA_IN(TYPE_POSITION) = TYPE_ACK then
---           got_ack_internal <=   '1';    
---           if MED_DATA_IN(F1_POSITION) = F1_CHECK_ACK then
---             next_rec_buffer_size_out <= MED_DATA_IN(BUFFER_SIZE_POSITION);
---           end if;
---         elsif MED_DATA_IN(TYPE_POSITION) = TYPE_TRM then
---           got_eob_out <= '1';           --exactly when buffer is killed
---           tmp_INT_DATA_OUT <= MED_DATA_IN;
---           tmp_INT_DATAREADY_OUT <= '1';
---           if release_locked = '0' then
---             got_locked  <= '1';
---           end if;
---         elsif MED_DATA_IN(TYPE_POSITION) = TYPE_EOB then
---           got_eob_out <= '1';
---           tmp_INT_DATAREADY_OUT <= '0';
---           -- this should happen only one CLK cycle
---         elsif sbuf_free = '0' then
---           next_error_state <= GOT_OVERFLOW_ERROR;
---         elsif is_locked = '1' then
---           next_error_state <= GOT_LOCKED_ERROR;
---         end if;                         -- end TYPE
---       end if;                           -- end MED_DATAREADY_IN             
---     end process;
--- 
---     MED_READ_OUT <= '1';                -- I always can read
---     
--- 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 holds the current packet type
+  process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          saved_packet_type <= "111";
+        elsif MED_PACKET_NUM_IN = "00" then
+          saved_packet_type <= MED_DATA_IN(2 downto 0);
+        end if;
+      end if;
+    end process;
+  --create comb. real packet type
+  current_packet_type <= MED_DATA_IN(2 downto 0) when (MED_PACKET_NUM_IN = "00" and RESET = '0') 
+                         else saved_packet_type;
+
+  -- this process controls the writing of the media into the fifo
+  FILTER_DATAREADY_IN : process(MED_DATA_IN, MED_DATAREADY_IN, MED_ERROR_IN,
+                                  is_locked, current_rec_buffer_size_out,
+                                  current_error_state, release_locked,
+                                  sbuf_free, MED_PACKET_NUM_IN, current_packet_type)
+    begin
+      got_ack_internal <=   '0';
+      next_rec_buffer_size_out <= current_rec_buffer_size_out;
+      next_error_state <= current_error_state;
+      tmp_INT_DATA_OUT <= (others => '1');
+      tmp_INT_PACKET_NUM_OUT <= (others => '0');
+      tmp_INT_DATAREADY_OUT <= '0';
+      got_eob_out <= '0';
+      got_locked  <= is_locked;
+
+      if MED_DATAREADY_IN = '1' then    -- data word offered
+        if current_packet_type = TYPE_ACK then
+          if MED_PACKET_NUM_IN = "00" then
+            got_ack_internal <=   '1';
+          elsif MED_PACKET_NUM_IN = "10" then
+            next_rec_buffer_size_out <= MED_DATA_IN(3 downto 0);
+          end if;
+        elsif current_packet_type = TYPE_TRM then
+          if MED_PACKET_NUM_IN = "11" then
+            got_eob_out <= '1';           --exactly when buffer is killed
+            if release_locked = '0' then
+              got_locked  <= '1';
+            end if;
+          end if;
+          tmp_INT_DATA_OUT <= MED_DATA_IN;
+          tmp_INT_PACKET_NUM_OUT <= MED_PACKET_NUM_IN;
+          tmp_INT_DATAREADY_OUT <= '1';
+        elsif current_packet_type = TYPE_EOB then
+          if MED_PACKET_NUM_IN = "11" then
+            got_eob_out <= '1';
+          end if;
+        elsif sbuf_free = '0' then
+          next_error_state <= GOT_OVERFLOW_ERROR;
+        elsif is_locked = '1' then
+          next_error_state <= GOT_LOCKED_ERROR;
+        end if;
+      end if;
+    end process;
+
+
+
+  MED_READ_OUT <= '1';                -- I always can read
+
+  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;
+
+
+
   SBUF: trb_net16_sbuf
     generic map (
       DATA_WIDTH => 16,
@@ -198,8 +218,8 @@ this process has to be converted to 16 Bit
   STAT_BUFFER(7 downto 4) <= current_rec_buffer_size_out;
   STAT_BUFFER(8) <= reg_eob_out;
   STAT_BUFFER(9) <= reg_ack_internal;
-  STAT_BUFFER(11 downto 10) <= "00" when current_error_state = IDLE,
-                               "01" when current_error_state = GOT_OVERFLOW_ERROR,
+  STAT_BUFFER(11 downto 10) <= "00" when current_error_state = IDLE else
+                               "01" when current_error_state = GOT_OVERFLOW_ERROR else
                                "10" when current_error_state = GOT_LOCKED_ERROR
                                else "11";
   STAT_BUFFER(31 downto 12) <= (others => '0');
index 3b8baed05c3461a7ddb7bd78a2dc5d192f410eb4..6aee06915ae798c4716dbbd8ad3adbc9c488d877 100644 (file)
@@ -37,7 +37,7 @@ entity trb_net_term_ibuf is
     CTRL_LOCKED:       in  STD_LOGIC_VECTOR (15 downto 0);
     STAT_BUFFER:       out STD_LOGIC_VECTOR (31 downto 0)
     );
-END trb_net_term_ibuf;
+end trb_net_term_ibuf;
 
 architecture trb_net_term_ibuf_arch of trb_net_term_ibuf is
 
@@ -63,7 +63,7 @@ architecture trb_net_term_ibuf_arch of trb_net_term_ibuf is
     -- Status and control port
     STAT_BUFFER:       out STD_LOGIC
     );
-  END component;
+   end component;
 
 
 signal got_ack_internal, reg_ack_internal : std_logic;    --should be raised for 1 cycle when ack
@@ -159,32 +159,32 @@ reg_buffer: process(CLK)
       SYN_DATA_OUT => INT_DATA_OUT,
       SYN_READ_IN => INT_READ_IN
       );
-  
+
   sbuf_free <= comb_next_read or INT_READ_IN;  --sbuf killed
-  
-release_locked <= CTRL_LOCKED(0);
-STAT_LOCKED(0) <= is_locked;
-STAT_LOCKED(15 downto 1) <= (others => '0');
-  
-reg_locked: process(CLK)
+
+  release_locked <= CTRL_LOCKED(0);
+  STAT_LOCKED(0) <= is_locked;
+  STAT_LOCKED(15 downto 1) <= (others => '0');
+
+  reg_locked: process(CLK)
     begin
-    if rising_edge(CLK) then
-      if RESET = '1' then
-        is_locked <= '0';
-        reg_eob_out <= '0';
-      elsif CLK_EN = '1' then
-        if release_locked = '1' then
+      if rising_edge(CLK) then
+        if RESET = '1' then
           is_locked <= '0';
+          reg_eob_out <= '0';
+        elsif CLK_EN = '1' then
+          if release_locked = '1' then
+            is_locked <= '0';
+          else
+            is_locked <= got_locked;
+          end if;
+          reg_eob_out <= got_eob_out;
         else
-          is_locked <= got_locked;
+          is_locked <= is_locked;
+          reg_eob_out <= reg_eob_out;
         end if;
-        reg_eob_out <= got_eob_out;
-      else
-        is_locked <= is_locked;
-        reg_eob_out <= reg_eob_out;
       end if;
-    end if;
-  end process;
+    end process;