]> jspc29.x-matter.uni-frankfurt.de Git - trbnet.git/commitdiff
code cleanup in transition
authorMichael Boehmer <mboehmer@ph.tum.de>
Fri, 28 Oct 2022 22:29:58 +0000 (00:29 +0200)
committerMichael Boehmer <mboehmer@ph.tum.de>
Fri, 28 Oct 2022 22:29:58 +0000 (00:29 +0200)
28 files changed:
gbe_trb/base/gbe_frame_constr.vhd [new file with mode: 0644]
gbe_trb/base/gbe_frame_receiver.vhd [new file with mode: 0644]
gbe_trb/base/gbe_logic_wrapper.vhd
gbe_trb/base/gbe_main_control.vhd [new file with mode: 0644]
gbe_trb/base/gbe_protocol_prioritizer.vhd [new file with mode: 0644]
gbe_trb/base/gbe_protocol_selector.vhd [new file with mode: 0644]
gbe_trb/base/gbe_receive_control.vhd [new file with mode: 0644]
gbe_trb/base/gbe_rx_rb.vhd [new file with mode: 0644]
gbe_trb/base/gbe_sgl_ctrl.vhd [new file with mode: 0644]
gbe_trb/base/gbe_transmit_control.vhd [new file with mode: 0644]
gbe_trb/base/gbe_type_validator.vhd [new file with mode: 0644]
gbe_trb/base/gbe_wrapper_fifo.vhd
gbe_trb/base/ip_configurator.vhd [changed mode: 0755->0644]
gbe_trb/base/sgl_ctrl.vhd
gbe_trb/base/trb_net16_gbe_frame_constr.vhd [changed mode: 0755->0644]
gbe_trb/base/trb_net16_gbe_frame_trans.vhd [changed mode: 0755->0644]
gbe_trb/protocols/gbe_response_constructor_ARP.vhd [new file with mode: 0644]
gbe_trb/protocols/gbe_response_constructor_DHCP.vhd [new file with mode: 0644]
gbe_trb/protocols/gbe_response_constructor_Forward.vhd [new file with mode: 0644]
gbe_trb/protocols/gbe_response_constructor_Ping.vhd [new file with mode: 0644]
gbe_trb/protocols/gbe_response_constructor_SCTRL.vhd [new file with mode: 0644]
gbe_trb_ecp3/media/gbe_med_fifo.vhd
media_interfaces/sync/gbe_tx_reset.vhd [new file with mode: 0644]
special/trb_net_i2cwire.vhd
special/trb_net_i2cwire2.vhd
trb_net16_api_base.vhd
trb_net16_endpoint_standalone_sctrl.vhd
trb_net16_regIO.vhd

diff --git a/gbe_trb/base/gbe_frame_constr.vhd b/gbe_trb/base/gbe_frame_constr.vhd
new file mode 100644 (file)
index 0000000..e2a1414
--- /dev/null
@@ -0,0 +1,450 @@
+library IEEE;\r
+use IEEE.std_logic_1164.ALL;\r
+use IEEE.numeric_std.ALL;\r
+use IEEE.std_logic_UNSIGNED.ALL;\r
+\r
+library work;\r
+use work.trb_net_std.all;\r
+use work.trb_net_components.all;\r
+\r
+entity gbe_frame_constr is\r
+  port( \r
+    -- ports for user logic\r
+    RESET                   : in  std_logic;\r
+    CLK                     : in  std_logic; -- 125MHz clock\r
+    LINK_OK_IN              : in  std_logic; \r
+    -- frame stuff\r
+    WR_EN_IN                : in  std_logic;\r
+    DATA_IN                 : in  std_logic_vector(7 downto 0);\r
+    START_OF_DATA_IN        : in  std_logic;\r
+    END_OF_DATA_IN          : in  std_logic;\r
+    IP_F_SIZE_IN            : in  std_logic_vector(15 downto 0);\r
+    UDP_P_SIZE_IN           : in  std_logic_vector(15 downto 0); -- needed for fragmentation\r
+    HEADERS_READY_OUT       : out std_logic;\r
+    READY_OUT               : out std_logic;\r
+    DEST_MAC_ADDRESS_IN     : in  std_logic_vector(47 downto 0);\r
+    DEST_IP_ADDRESS_IN      : in  std_logic_vector(31 downto 0);\r
+    DEST_UDP_PORT_IN        : in  std_logic_vector(15 downto 0);\r
+    SRC_MAC_ADDRESS_IN      : in  std_logic_vector(47 downto 0);\r
+    SRC_IP_ADDRESS_IN       : in  std_logic_vector(31 downto 0);\r
+    SRC_UDP_PORT_IN         : in  std_logic_vector(15 downto 0);\r
+    FRAME_TYPE_IN           : in  std_logic_vector(15 downto 0);\r
+    IHL_VERSION_IN          : in  std_logic_vector(7 downto 0);\r
+    TOS_IN                  : in  std_logic_vector(7 downto 0);\r
+    IDENTIFICATION_IN       : in  std_logic_vector(15 downto 0);\r
+    FLAGS_OFFSET_IN         : in  std_logic_vector(15 downto 0);\r
+    TTL_IN                  : in  std_logic_vector(7 downto 0);\r
+    PROTOCOL_IN             : in  std_logic_vector(7 downto 0);\r
+    FRAME_DELAY_IN          : in  std_logic_vector(31 downto 0);\r
+    -- port for "RX ringbuffer"\r
+    FT_TX_DATA_OUT          : out std_logic_vector(8 downto 0);\r
+    FT_TX_WR_OUT            : out std_logic;\r
+    FT_TX_FIFOFULL_IN       : in  std_logic;\r
+    -- monitoring\r
+    MONITOR_TX_BYTES_OUT    : out std_logic_vector(31 downto 0);\r
+    MONITOR_TX_FRAMES_OUT   : out std_logic_vector(31 downto 0)\r
+  );\r
+end entity gbe_frame_constr;\r
+\r
+architecture gbe_frame_constr_arch of gbe_frame_constr is\r
+\r
+attribute syn_encoding      : string;\r
+\r
+type constructStates is (IDLE, DEST_MAC_ADDR, SRC_MAC_ADDR, FRAME_TYPE_S, VERSION,\r
+                         TOS_S, IP_LENGTH, IDENT, FLAGS, TTL_S, PROTO, HEADER_CS,\r
+                         SRC_IP_ADDR, DEST_IP_ADDR, SRC_PORT, DEST_PORT, UDP_LENGTH,\r
+                         UDP_CS, SAVE_DATA, CLEANUP, DELAY);\r
+signal constructCurrentState, constructNextState : constructStates;\r
+attribute syn_encoding of constructCurrentState: signal is "onehot";\r
+\r
+signal headers_int_counter  : integer range 0 to 6;\r
+signal fpf_data             : std_logic_vector(7 downto 0);\r
+signal fpf_wr_en            : std_logic;\r
+signal fpf_rd_en            : std_logic;\r
+signal fpf_rd_en_q          : std_logic;\r
+signal fpf_q                : std_logic_vector(8 downto 0);\r
+signal ip_size              : std_logic_vector(15 downto 0);\r
+signal ip_checksum          : std_logic_vector(31 downto 0);\r
+signal udp_size             : std_logic_vector(15 downto 0);\r
+signal udp_checksum         : std_logic_vector(15 downto 0);\r
+signal put_udp_headers      : std_logic;\r
+signal ready                : std_logic;\r
+signal headers_ready        : std_logic;\r
+\r
+signal cur_max              : integer range 0 to 10;\r
+\r
+signal ip_cs_temp_right     : std_logic_vector(15 downto 0);\r
+\r
+signal delay_ctr            : std_logic_vector(31 downto 0);\r
+signal frame_delay_reg      : std_logic_vector(31 downto 0);\r
+signal fpf_data_q           : std_logic_vector(7 downto 0);\r
+signal fpf_wr_en_q          : std_logic;\r
+signal fpf_eod_q            : std_logic;\r
+\r
+signal mon_sent_frames      : unsigned(31 downto 0);\r
+signal mon_sent_bytes       : unsigned(31 downto 0);\r
+\r
+begin\r
+\r
+-- No checksum test needed\r
+udp_checksum  <= x"0000";\r
+\r
+-- frame constructor ready\r
+THE_READY_PROC: process( CLK )\r
+begin\r
+if( rising_edge(CLK) )then\r
+  if( constructCurrentState = IDLE ) then\r
+    ready <= '1';\r
+  else\r
+    ready <= '0';\r
+  end if;\r
+\r
+  if( constructCurrentState = SAVE_DATA ) then\r
+    headers_ready <= '1';\r
+  else\r
+    headers_ready <= '0';\r
+  end if;\r
+end if;\r
+end process;\r
+\r
+-- Calculate UDP and IP sizes\r
+THE_SIZE_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( (put_udp_headers = '1') and (DEST_UDP_PORT_IN /= x"0000") ) then\r
+      ip_size  <= IP_F_SIZE_IN + x"14" + x"8";\r
+      udp_size <= UDP_P_SIZE_IN + x"8";\r
+    else\r
+      ip_size  <= IP_F_SIZE_IN + x"14";\r
+      udp_size <= UDP_P_SIZE_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SIZE_PROC;\r
+\r
+THE_IP_CS_PROC : process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( constructCurrentState = IDLE ) then\r
+      ip_checksum <= x"00000000";\r
+    else\r
+      case constructCurrentState is\r
+        when DEST_MAC_ADDR =>\r
+          case headers_int_counter is\r
+            when 0 =>\r
+              ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + SRC_IP_ADDRESS_IN(7 downto 0);\r
+            when 1 =>\r
+              ip_checksum <= ip_checksum +  SRC_IP_ADDRESS_IN(15 downto 8);\r
+            when 2 =>\r
+              ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + SRC_IP_ADDRESS_IN(23 downto 16);\r
+            when 3 =>\r
+              ip_checksum <= ip_checksum +  SRC_IP_ADDRESS_IN(31 downto 24);\r
+            when 4 =>\r
+              ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + DEST_IP_ADDRESS_IN(7 downto 0);\r
+            when 5 =>\r
+              ip_checksum <= ip_checksum +  DEST_IP_ADDRESS_IN(15 downto 8);\r
+            when others => null;\r
+          end case;\r
+        when SRC_MAC_ADDR =>\r
+          case headers_int_counter is\r
+            when 0 =>\r
+              ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + DEST_IP_ADDRESS_IN(23 downto 16);\r
+            when 1 =>\r
+              ip_checksum <= ip_checksum +  DEST_IP_ADDRESS_IN(31 downto 24);\r
+            when 2 =>\r
+              ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + IHL_VERSION_IN;\r
+            when 3 =>\r
+              ip_checksum <= ip_checksum + TOS_IN;\r
+            when 4 =>\r
+              ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + ip_size(15 downto 8);\r
+            when 5 =>\r
+              ip_checksum <= ip_checksum + ip_size(7 downto 0);\r
+            when others => null;\r
+          end case;\r
+        when VERSION =>\r
+          if( headers_int_counter = 0 ) then\r
+            ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + IDENTIFICATION_IN(7 downto 0);\r
+          end if;\r
+        when TOS_S =>\r
+          if( headers_int_counter = 0 ) then\r
+            ip_checksum <= ip_checksum + IDENTIFICATION_IN(15 downto 8);\r
+          end if;\r
+        when IP_LENGTH =>\r
+          if( headers_int_counter = 0 ) then\r
+            ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + FLAGS_OFFSET_IN(15 downto 8);\r
+          elsif headers_int_counter = 1 then\r
+            ip_checksum <= ip_checksum + FLAGS_OFFSET_IN(7 downto 0);\r
+          end if;\r
+        when IDENT =>\r
+          if headers_int_counter = 0 then\r
+            ip_checksum(31 downto 8) <= ip_checksum(31 downto 8) + TTL_IN;\r
+          elsif headers_int_counter = 1 then\r
+            ip_checksum <= ip_checksum + PROTOCOL_IN;\r
+          end if;\r
+        -- gk 29.03.10 corrected the bug with bad checksums when sum larger than 16b\r
+        when FLAGS =>\r
+          if   ( headers_int_counter = 0 ) then\r
+            ip_cs_temp_right <= ip_checksum(31 downto 16);\r
+          elsif( headers_int_counter = 1 ) then\r
+            ip_checksum(31 downto 16) <= (others => '0');\r
+          end if;\r
+        when TTL_S =>\r
+          if( headers_int_counter = 0 ) then\r
+            ip_checksum <= ip_checksum + ip_cs_temp_right;\r
+          end if;\r
+        when PROTO =>\r
+          if( headers_int_counter = 0 ) then\r
+            ip_checksum(15 downto 0) <= ip_checksum(15 downto 0) + ip_checksum(31 downto 16);\r
+          end if;\r
+        when others => null;\r
+      end case;\r
+    end if;\r
+  end if;\r
+end process THE_IP_CS_PROC;\r
+\r
+\r
+THE_CONSTRUCT_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( RESET = '1' ) then\r
+      constructCurrentState <= IDLE;\r
+    else\r
+      constructCurrentState <= constructNextState;\r
+    end if;\r
+  end if;\r
+end process THE_CONSTRUCT_PROC;\r
+\r
+--find next state of construct machine\r
+constructMachine: process( constructCurrentState, delay_ctr, FRAME_DELAY_IN, START_OF_DATA_IN, \r
+                          END_OF_DATA_IN, headers_int_counter, put_udp_headers, CUR_MAX, \r
+                          FRAME_TYPE_IN, DEST_UDP_PORT_IN)\r
+begin\r
+  constructNextState <= constructCurrentState;\r
+  if( headers_int_counter = cur_max ) then    --can be checked everytime - if not in use, counter and cur_max are 0\r
+    case constructCurrentState is\r
+      when IDLE =>\r
+        if( START_OF_DATA_IN = '1' ) then\r
+          constructNextState <= DEST_MAC_ADDR;\r
+        end if;\r
+      when DEST_MAC_ADDR =>\r
+        constructNextState <= SRC_MAC_ADDR;\r
+      when SRC_MAC_ADDR =>\r
+        constructNextState <= FRAME_TYPE_S;\r
+      when FRAME_TYPE_S =>\r
+        if( FRAME_TYPE_IN = x"0008" ) then \r
+          constructNextState <= VERSION;\r
+        else  -- otherwise transmit data as pure ethernet frame\r
+          constructNextState <= SAVE_DATA;\r
+        end if;\r
+      when VERSION =>\r
+        constructNextState <= TOS_S;\r
+      when TOS_S =>\r
+        constructNextState <= IP_LENGTH;\r
+      when IP_LENGTH =>\r
+        constructNextState <= IDENT;\r
+      when IDENT =>\r
+        constructNextState <= FLAGS;\r
+      when FLAGS =>\r
+        constructNextState <= TTL_S;\r
+      when TTL_S =>\r
+        constructNextState <= PROTO;\r
+      when PROTO =>\r
+        constructNextState <= HEADER_CS;\r
+      when HEADER_CS =>\r
+        constructNextState <= SRC_IP_ADDR;\r
+      when SRC_IP_ADDR =>\r
+        constructNextState <= DEST_IP_ADDR;\r
+      when DEST_IP_ADDR =>\r
+        if( (put_udp_headers = '1') and (DEST_UDP_PORT_IN /= x"0000") ) then\r
+          constructNextState <= SRC_PORT;\r
+        else\r
+          constructNextState <= SAVE_DATA;\r
+        end if;\r
+      when SRC_PORT =>\r
+        constructNextState <= DEST_PORT;\r
+      when DEST_PORT =>\r
+        constructNextState <= UDP_LENGTH;\r
+      when UDP_LENGTH =>\r
+        constructNextState <= UDP_CS;\r
+      when UDP_CS =>\r
+        constructNextState <= SAVE_DATA;\r
+      when SAVE_DATA =>\r
+        if( END_OF_DATA_IN = '1' ) then\r
+          constructNextState <= CLEANUP;\r
+        end if;\r
+      when CLEANUP =>\r
+        constructNextState <= DELAY;\r
+      when DELAY =>\r
+        if (delay_ctr = FRAME_DELAY_IN) then\r
+          constructNextState <= IDLE;\r
+        else\r
+          constructNextState <= DELAY;\r
+        end if;\r
+    \r
+      when others =>\r
+        constructNextState <= IDLE;\r
+    end case;\r
+  end if;\r
+end process constructMachine;\r
+\r
+THE_DELAY_CTR_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( (constructCurrentState = IDLE) or (constructCurrentState = CLEANUP) ) then\r
+      delay_ctr <= (others => '0');\r
+    elsif( constructCurrentState = DELAY ) then\r
+      delay_ctr <= delay_ctr + x"1";\r
+    end if;\r
+\r
+    frame_delay_reg <= FRAME_DELAY_IN;\r
+  end if;\r
+end process THE_DELAY_CTR_PROC;\r
+\r
+THE_BSM_CONSTR_PROC: process( constructCurrentState )\r
+begin\r
+--find maximum time in each state & set state bits\r
+  case constructCurrentState is\r
+    when IDLE          => cur_max <= 0;\r
+    when DEST_MAC_ADDR => cur_max <= 5;\r
+    when SRC_MAC_ADDR  => cur_max <= 5;\r
+    when FRAME_TYPE_S  => cur_max <= 1;\r
+    when VERSION       => cur_max <= 0;\r
+    when TOS_S         => cur_max <= 0;\r
+    when IP_LENGTH     => cur_max <= 1;\r
+    when IDENT         => cur_max <= 1;\r
+    when FLAGS         => cur_max <= 1;\r
+    when TTL_S         => cur_max <= 0;\r
+    when PROTO         => cur_max <= 0;\r
+    when HEADER_CS     => cur_max <= 1;\r
+    when SRC_IP_ADDR   => cur_max <= 3;\r
+    when DEST_IP_ADDR  => cur_max <= 3;\r
+    when SRC_PORT      => cur_max <= 1;\r
+    when DEST_PORT     => cur_max <= 1;\r
+    when UDP_LENGTH    => cur_max <= 1;\r
+    when UDP_CS        => cur_max <= 1;\r
+    when SAVE_DATA     => cur_max <= 0;\r
+    when CLEANUP       => cur_max <= 0;\r
+    when DELAY         => cur_max <= 0;\r
+    when others        => cur_max <= 0;\r
+end case;\r
+end process THE_BSM_CONSTR_PROC;\r
+\r
+THE_HEADERS_INT_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( constructCurrentState = IDLE ) then\r
+      headers_int_counter <= 0;\r
+    else\r
+      if( headers_int_counter = cur_max ) then\r
+        headers_int_counter <= 0;\r
+      else\r
+        headers_int_counter <= headers_int_counter + 1;\r
+      end if;\r
+    end if;\r
+end if;\r
+end process THE_HEADERS_INT_PROC;\r
+\r
+THE_PUT_UDP_HEADERS_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( FLAGS_OFFSET_IN(12 downto 0) = "0000000000000" ) then\r
+      put_udp_headers <= '1';\r
+    else\r
+      put_udp_headers <= '0';\r
+    end if;\r
+  end if;\r
+end process THE_PUT_UDP_HEADERS_PROC;\r
+\r
+THE_FPF_WREN_PROC : process( constructCurrentState, WR_EN_IN, LINK_OK_IN )\r
+begin\r
+  if   ( LINK_OK_IN = '0' ) then\r
+    fpf_wr_en <= '0';\r
+  elsif( (constructCurrentState /= IDLE) and (constructCurrentState /= CLEANUP) and (constructCurrentState /= SAVE_DATA)  and (constructCurrentState /= DELAY) ) then\r
+    fpf_wr_en <= '1';\r
+  elsif( (constructCurrentState = SAVE_DATA) and (WR_EN_IN = '1') ) then\r
+    fpf_wr_en <= '1';\r
+  else\r
+    fpf_wr_en <= '0';\r
+  end if;\r
+end process THE_FPF_WREN_PROC;\r
+\r
+THE_FPF_DATA_PROC: process( constructCurrentState, DEST_MAC_ADDRESS_IN, SRC_MAC_ADDRESS_IN, FRAME_TYPE_IN, IHL_VERSION_IN,\r
+                            TOS_IN, ip_size, IDENTIFICATION_IN, FLAGS_OFFSET_IN, TTL_IN, PROTOCOL_IN,\r
+                            ip_checksum, SRC_IP_ADDRESS_IN, DEST_IP_ADDRESS_IN,\r
+                            SRC_UDP_PORT_IN, DEST_UDP_PORT_IN, udp_size, udp_checksum, headers_int_counter, DATA_IN )\r
+begin\r
+  case constructCurrentState is\r
+    when IDLE           =>  fpf_data <= DEST_MAC_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+    when DEST_MAC_ADDR  =>  fpf_data <= DEST_MAC_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+    when SRC_MAC_ADDR   =>  fpf_data <= SRC_MAC_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+    when FRAME_TYPE_S   =>  fpf_data <= FRAME_TYPE_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+    when VERSION        =>  fpf_data <= IHL_VERSION_IN;\r
+    when TOS_S          =>  fpf_data <= TOS_IN;\r
+    when IP_LENGTH      =>  fpf_data <= ip_size(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+    when IDENT          =>  fpf_data <= IDENTIFICATION_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+    when FLAGS          =>  fpf_data <= FLAGS_OFFSET_IN(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+    when TTL_S          =>  fpf_data <= TTL_IN;\r
+    when PROTO          =>  fpf_data <= PROTOCOL_IN;\r
+    when HEADER_CS      =>  fpf_data <= x"ff" - ip_checksum(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+    when SRC_IP_ADDR    =>  fpf_data <= SRC_IP_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+    when DEST_IP_ADDR   =>  fpf_data <= DEST_IP_ADDRESS_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+    when SRC_PORT       =>  fpf_data <= SRC_UDP_PORT_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+    when DEST_PORT      =>  fpf_data <= DEST_UDP_PORT_IN(headers_int_counter * 8 + 7 downto headers_int_counter * 8);\r
+    when UDP_LENGTH     =>  fpf_data <= udp_size(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+    when UDP_CS         =>  fpf_data <= udp_checksum(15 - headers_int_counter * 8 downto 8 - headers_int_counter * 8);\r
+    when SAVE_DATA      =>  fpf_data <= DATA_IN;\r
+    when CLEANUP        =>  fpf_data <= x"ab";\r
+    when DELAY          =>  fpf_data <= x"ac";\r
+    when others         =>  fpf_data <= x"00";\r
+  end case;\r
+end process THE_FPF_DATA_PROC;\r
+\r
+THE_SYNC_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    fpf_data_q  <= fpf_data;\r
+    fpf_wr_en_q <= fpf_wr_en;\r
+    fpf_eod_q   <= END_OF_DATA_IN;\r
+  end if;\r
+end process THE_SYNC_PROC;\r
+\r
+-- count bytes sent\r
+THE_MON_SENT_BYTES_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( LINK_OK_IN = '0' ) then\r
+      mon_sent_bytes <= (others => '0');\r
+    elsif( fpf_rd_en = '1' ) then\r
+      mon_sent_bytes <= mon_sent_bytes + 1;\r
+    else\r
+      mon_sent_bytes <= mon_sent_bytes;\r
+    end if;\r
+  end if;\r
+end process THE_MON_SENT_BYTES_PROC;\r
+\r
+-- count frames sent\r
+THE_MON_SENT_FRAMES_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) )then\r
+    if   ( LINK_OK_IN = '0' ) then\r
+      mon_sent_frames <= (others => '0');\r
+    elsif( (fpf_wr_en_q = '1') and (fpf_eod_q = '1') ) then -- TO BE TESTED\r
+      mon_sent_frames <= mon_sent_frames + 1;\r
+    else\r
+      mon_sent_frames <= mon_sent_frames;\r
+    end if;\r
+  end if;\r
+end process THE_MON_SENT_FRAMES_PROC;\r
+\r
+-- Outputs\r
+\r
+FT_TX_DATA_OUT(7 downto 0) <= fpf_data_q;\r
+FT_TX_DATA_OUT(8)          <= fpf_eod_q;\r
+FT_TX_WR_OUT               <= fpf_wr_en_q;\r
+\r
+READY_OUT                 <= ready;\r
+HEADERS_READY_OUT         <= headers_ready;\r
+\r
+MONITOR_TX_BYTES_OUT      <= std_logic_vector(mon_sent_bytes);\r
+MONITOR_TX_FRAMES_OUT     <= std_logic_vector(mon_sent_frames);\r
+\r
+end gbe_frame_constr_arch;\r
diff --git a/gbe_trb/base/gbe_frame_receiver.vhd b/gbe_trb/base/gbe_frame_receiver.vhd
new file mode 100644 (file)
index 0000000..099db77
--- /dev/null
@@ -0,0 +1,717 @@
+LIBRARY IEEE;\r
+USE IEEE.std_logic_1164.ALL;\r
+USE IEEE.numeric_std.ALL;\r
+USE IEEE.std_logic_UNSIGNED.ALL;\r
+\r
+library work;\r
+use work.trb_net_std.all;\r
+use work.trb_net_components.all;\r
+use work.gbe_protocols.all;\r
+\r
+--********\r
+-- here all frame checking has to be done, if the frame fits into protocol standards\r
+-- if so FR_FRAME_VALID_OUT is asserted after having received all bytes of a frame\r
+-- otherwise, after receiving all bytes, FR_FRAME_VALID_OUT keeps low and the fifo is cleared\r
+-- also a part of addresses assignment has to be done here\r
+\r
+-- This entity receives an Ethernet frame, disassembles it and checks if the frame has to be processed.\r
+-- In case, decoded information from header is stored in FIFOs and next stage is informed about available\r
+-- data by FR_FRAME_VALID_OUT.\r
+\r
+entity gbe_frame_receiver is\r
+port (\r
+  CLK                     : in  std_logic;  -- system clock\r
+  RESET                   : in  std_logic;\r
+  LINK_OK_IN              : in  std_logic;\r
+  ALLOW_RX_IN             : in  std_logic;\r
+  MY_MAC_IN               : in  std_logic_vector(47 downto 0);\r
+-- killer ping\r
+  MY_TRBNET_ADDRESS_IN    : in  std_logic_vector(15 downto 0) := (others => '0');\r
+  ISSUE_REBOOT_OUT        : out std_logic;\r
+-- input signals from TS_MAC\r
+  MAC_RX_EOF_IN           : in  std_logic; -- End Of Frame\r
+  MAC_RX_ER_IN            : in  std_logic; -- only for statistics\r
+  MAC_RXD_IN              : in  std_logic_vector(7 downto 0); -- RX data\r
+  MAC_RX_EN_IN            : in  std_logic; -- write signal\r
+-- output signal to control logic\r
+  FR_Q_OUT                : out std_logic_vector(8 downto 0);\r
+  FR_RD_EN_IN             : in  std_logic;\r
+  FR_FRAME_VALID_OUT      : out std_logic;\r
+  FR_GET_FRAME_IN         : in  std_logic;\r
+  FR_FRAME_SIZE_OUT       : out std_logic_vector(15 downto 0);\r
+  FR_FRAME_PROTO_OUT      : out std_logic_vector(15 downto 0);\r
+  FR_IP_PROTOCOL_OUT      : out std_logic_vector(7 downto 0);\r
+  FR_ALLOWED_TYPES_IN     : in  std_logic_vector(31 downto 0);\r
+  FR_ALLOWED_IP_IN        : in  std_logic_vector(31 downto 0);\r
+  FR_ALLOWED_UDP_IN       : in  std_logic_vector(31 downto 0);\r
+  FR_VLAN_ID_IN           : in  std_logic_vector(31 downto 0);\r
+--\r
+  FR_SRC_MAC_ADDRESS_OUT  : out std_logic_vector(47 downto 0);\r
+  FR_DEST_MAC_ADDRESS_OUT : out std_logic_vector(47 downto 0);\r
+  FR_SRC_IP_ADDRESS_OUT   : out std_logic_vector(31 downto 0);\r
+  FR_DEST_IP_ADDRESS_OUT  : out std_logic_vector(31 downto 0);\r
+  FR_SRC_UDP_PORT_OUT     : out std_logic_vector(15 downto 0);\r
+  FR_DEST_UDP_PORT_OUT    : out std_logic_vector(15 downto 0);\r
+--\r
+  OOB_REGISTER_0_OUT      : out std_logic_vector(31 downto 0);\r
+  OOB_REGISTER_1_OUT      : out std_logic_vector(31 downto 0);\r
+  OOB_REGISTER_2_OUT      : out std_logic_vector(31 downto 0);\r
+  OOB_REGISTER_3_OUT      : out std_logic_vector(31 downto 0);\r
+--\r
+  MONITOR_RX_BYTES_OUT    : out std_logic_vector(31 downto 0);\r
+  MONITOR_RX_FRAMES_OUT   : out std_logic_vector(31 downto 0);\r
+  MONITOR_DROPPED_OUT     : out std_logic_vector(31 downto 0);\r
+  DEBUG_OUT               : out std_logic_vector(15 downto 0)\r
+);\r
+end gbe_frame_receiver;\r
+\r
+architecture gbe_frame_receiver_arch of gbe_frame_receiver is\r
+\r
+attribute syn_encoding  : string;\r
+type filter_states is (IDLE, REMOVE_DEST, REMOVE_SRC, REMOVE_TYPE, SAVE_FRAME, DROP_FRAME,\r
+                       REMOVE_VID, REMOVE_VTYPE, REMOVE_IP, REMOVE_UDP, DECIDE, CLEANUP);\r
+signal filter_current_state, filter_next_state : filter_states;\r
+attribute syn_encoding of filter_current_state : signal is "onehot";\r
+\r
+signal fifo_wr_en                           : std_logic;\r
+signal rx_bytes_ctr                         : std_logic_vector(15 downto 0);\r
+signal frame_valid_q                        : std_logic;\r
+signal delayed_frame_valid                  : std_logic;\r
+signal delayed_frame_valid_q                : std_logic;\r
+\r
+signal rec_fifo_empty                       : std_logic;\r
+signal rec_fifo_full                        : std_logic;\r
+signal sizes_fifo_full                      : std_logic;\r
+signal sizes_fifo_empty                     : std_logic;\r
+\r
+signal remove_ctr                           : unsigned(7 downto 0);\r
+signal new_frame                            : std_logic;\r
+signal new_frame_lock                       : std_logic := '0';\r
+signal saved_frame_type                     : std_logic_vector(15 downto 0);\r
+signal saved_vid                            : std_logic_vector(15 downto 0) := (others => '0');\r
+signal saved_src_mac                        : std_logic_vector(47 downto 0);\r
+signal saved_dest_mac                       : std_logic_vector(47 downto 0);\r
+signal frame_type_valid                     : std_logic;\r
+signal saved_proto                          : std_logic_vector(7 downto 0);\r
+signal saved_src_ip                         : std_logic_vector(31 downto 0);\r
+signal saved_dest_ip                        : std_logic_vector(31 downto 0);\r
+signal saved_src_udp                        : std_logic_vector(15 downto 0);\r
+signal saved_dest_udp                       : std_logic_vector(15 downto 0);\r
+\r
+signal error_frames_ctr                     : unsigned(15 downto 0);\r
+signal dbg_rec_frames                       : unsigned(31 downto 0);\r
+signal dbg_drp_frames                       : unsigned(31 downto 0);\r
+signal mon_rec_bytes                        : unsigned(31 downto 0);\r
+\r
+signal state                                : std_logic_vector(3 downto 0);\r
+\r
+signal rx_data                              : std_logic_vector(8 downto 0);\r
+signal fr_q                                 : std_logic_vector(8 downto 0);\r
+\r
+signal fr_src_ip                            : std_logic_vector(31 downto 0);\r
+signal fr_dest_ip                           : std_logic_vector(31 downto 0);\r
+signal fr_dest_udp                          : std_logic_vector(15 downto 0);\r
+signal fr_src_udp                           : std_logic_vector(15 downto 0);\r
+signal fr_frame_size                        : std_logic_vector(15 downto 0);\r
+signal fr_frame_proto                       : std_logic_vector(15 downto 0);\r
+signal fr_dest_mac                          : std_logic_vector(47 downto 0);\r
+signal fr_src_mac                           : std_logic_vector(47 downto 0);\r
+signal fr_ip_proto                          : std_logic_vector(7 downto 0);\r
+\r
+signal xxx0                                 : std_logic_vector(7 downto 0);\r
+signal xxx1                                 : std_logic_vector(7 downto 0);\r
+\r
+signal oob_register_0_int                   : std_logic_vector(31 downto 0);\r
+signal oob_register_1_int                   : std_logic_vector(31 downto 0);\r
+signal oob_register_2_int                   : std_logic_vector(31 downto 0);\r
+signal oob_register_3_int                   : std_logic_vector(31 downto 0);\r
+signal oob_write                            : std_logic;\r
+\r
+attribute syn_preserve : boolean;\r
+attribute syn_keep : boolean;\r
+attribute syn_keep of rec_fifo_empty, rec_fifo_full, state, sizes_fifo_empty, sizes_fifo_full : signal is true;\r
+attribute syn_preserve of rec_fifo_empty, rec_fifo_full, state, sizes_fifo_empty, sizes_fifo_full : signal is true;\r
+\r
+begin\r
+\r
+-- new_frame is asserted when first byte of the frame arrives\r
+THE_NEW_FRAME_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) )then\r
+    if   ( (LINK_OK_IN = '0') or (MAC_RX_EOF_IN = '1') ) then\r
+      new_frame <= '0';\r
+      new_frame_lock <= '0';\r
+    elsif( (new_frame_lock = '0') and (MAC_RX_EN_IN = '1') ) then\r
+      new_frame <= '1';\r
+      new_frame_lock <= '1';\r
+    else\r
+      new_frame <= '0';\r
+    end if;\r
+  end if;\r
+end process THE_NEW_FRAME_PROC;\r
+\r
+THE_FILTER_MACHINE_PROC: process( CLK, RESET )\r
+begin\r
+  if   ( RESET = '1' ) then\r
+    filter_current_state <= IDLE;\r
+  elsif( rising_edge(CLK) ) then\r
+    filter_current_state <= filter_next_state;\r
+  end if;\r
+end process THE_FILTER_MACHINE_PROC;\r
+\r
+THE_FILTER_MACHINE : process( filter_current_state, saved_frame_type, LINK_OK_IN, saved_proto, MY_MAC_IN,\r
+                              saved_dest_mac, remove_ctr, new_frame, MAC_RX_EOF_IN, frame_type_valid, ALLOW_RX_IN)\r
+begin\r
+  case filter_current_state is\r
+\r
+    when IDLE =>\r
+      state <= x"1";\r
+      if( (new_frame = '1') and (ALLOW_RX_IN = '1') and (LINK_OK_IN = '1') ) then\r
+        filter_next_state <= REMOVE_DEST;\r
+      else\r
+        filter_next_state <= IDLE;\r
+      end if;\r
+\r
+    -- frames arrive without preamble!\r
+    when REMOVE_DEST =>\r
+      state <= x"3";\r
+      if( remove_ctr = x"03" ) then  -- counter starts with a delay that's why only 3\r
+        -- destination MAC address filtering here\r
+        if( (saved_dest_mac = MY_MAC_IN) or (saved_dest_mac = x"ffffffffffff") ) then  -- must accept broadcasts for ARP\r
+          filter_next_state <= REMOVE_SRC;\r
+        else\r
+          filter_next_state <= DECIDE;\r
+        end if;\r
+      else\r
+        filter_next_state <= REMOVE_DEST;\r
+      end if;\r
+\r
+    when REMOVE_SRC =>\r
+      state <= x"4";\r
+      if( remove_ctr = x"09" ) then\r
+        filter_next_state <= REMOVE_TYPE;\r
+      else\r
+        filter_next_state <= REMOVE_SRC;\r
+      end if;\r
+\r
+    when REMOVE_TYPE =>\r
+      state <= x"5";\r
+      if( remove_ctr = x"0b" ) then\r
+        if( saved_frame_type = x"8100" ) then  -- VLAN tagged frame\r
+          filter_next_state <= REMOVE_VID;\r
+        else  -- no VLAN tag\r
+          if( saved_frame_type = x"0800" ) then  -- in case of IP continue removing headers\r
+            filter_next_state <= REMOVE_IP;\r
+          else\r
+            filter_next_state <= DECIDE;\r
+          end if;\r
+        end if;\r
+      else\r
+        filter_next_state <= REMOVE_TYPE;\r
+      end if;\r
+\r
+    when REMOVE_VID =>\r
+      state <= x"a";\r
+      if( remove_ctr = x"0d" ) then\r
+        filter_next_state <= REMOVE_VTYPE;\r
+      else\r
+        filter_next_state <= REMOVE_VID;\r
+      end if;\r
+\r
+    when REMOVE_VTYPE =>\r
+      state <= x"b";\r
+      if( remove_ctr = x"0f" ) then\r
+        if( saved_frame_type = x"0800" ) then  -- in case of IP continue removing headers\r
+          filter_next_state <= REMOVE_IP;\r
+        else\r
+          filter_next_state <= DECIDE;\r
+        end if;\r
+      else\r
+        filter_next_state <= REMOVE_VTYPE;\r
+      end if;\r
+\r
+    when REMOVE_IP =>\r
+      state <= x"c";\r
+      if( remove_ctr = x"11" ) then\r
+        if( saved_proto = x"11" ) then  -- forced to recognize udp only, TODO check all protocols\r
+          filter_next_state <= REMOVE_UDP;\r
+        else\r
+          filter_next_state <= DECIDE;  -- changed from drop\r
+        end if;\r
+      else\r
+        filter_next_state <= REMOVE_IP;\r
+      end if;\r
+\r
+    when REMOVE_UDP =>\r
+      state <= x"d";\r
+      if( remove_ctr = x"19" ) then\r
+        filter_next_state <= DECIDE;\r
+      else\r
+        filter_next_state <= REMOVE_UDP;\r
+      end if;\r
+\r
+    when DECIDE =>\r
+      state <= x"6";\r
+      if   ( frame_type_valid = '1' ) then\r
+        filter_next_state <= SAVE_FRAME;\r
+      elsif( saved_frame_type = x"0806" ) then\r
+        -- ARP?\r
+        filter_next_state <= SAVE_FRAME;\r
+      else\r
+        filter_next_state <= DROP_FRAME;\r
+      end if;\r
+\r
+    when SAVE_FRAME =>\r
+      state <= x"7";\r
+      if( MAC_RX_EOF_IN = '1' ) then\r
+        filter_next_state <= CLEANUP;\r
+      else\r
+        filter_next_state <= SAVE_FRAME;\r
+      end if;\r
+\r
+    when DROP_FRAME =>\r
+      state <= x"8";\r
+      if( MAC_RX_EOF_IN = '1' ) then\r
+        filter_next_state <= CLEANUP;\r
+      else\r
+        filter_next_state <= DROP_FRAME;\r
+      end if;\r
+\r
+    when CLEANUP =>\r
+      state <= x"9";\r
+      filter_next_state <= IDLE;\r
+\r
+    when others => null;\r
+\r
+  end case;\r
+end process THE_FILTER_MACHINE;\r
+\r
+-- counts the bytes to be removed from the ethernet headers fields\r
+REMOVE_CTR_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( (filter_current_state = IDLE) or\r
+           ((filter_current_state = REMOVE_VTYPE) and (remove_ctr = x"0f")) or\r
+           ((filter_current_state = REMOVE_TYPE) and (remove_ctr = x"0b") and (saved_frame_type /= x"8100")) ) then\r
+      remove_ctr <= (others => '1');\r
+    elsif( (MAC_RX_EN_IN = '1') and (filter_current_state /= IDLE) ) then\r
+      remove_ctr <= remove_ctr + 1;\r
+    end if;\r
+ end if;\r
+end process REMOVE_CTR_PROC;\r
+\r
+THE_SAVED_PROTO_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( filter_current_state = CLEANUP ) then\r
+      saved_proto <= (others => '0');\r
+    elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"07") ) then\r
+      saved_proto <= MAC_RXD_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SAVED_PROTO_PROC;\r
+\r
+-- saves the destination mac address of the incoming frame\r
+THE_SAVED_DEST_MAC_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( filter_current_state = CLEANUP ) then\r
+      saved_dest_mac <= (others => '0');\r
+    elsif( (filter_current_state = IDLE) and (MAC_RX_EN_IN = '1') and (new_frame = '0') ) then\r
+      saved_dest_mac(7 downto 0) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = IDLE) and (new_frame = '1') and (ALLOW_RX_IN = '1') ) then\r
+      saved_dest_mac(15 downto 8) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"FF") ) then\r
+      saved_dest_mac(23 downto 16) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"00") ) then\r
+      saved_dest_mac(31 downto 24) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"01") ) then\r
+      saved_dest_mac(39 downto 32) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"02") ) then\r
+      saved_dest_mac(47 downto 40) <= MAC_RXD_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SAVED_DEST_MAC_PROC;\r
+\r
+-- saves the source mac address of the incoming frame\r
+THE_SAVED_SRC_MAC_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( filter_current_state = CLEANUP ) then\r
+      saved_src_mac <= (others => '0');\r
+    elsif( (filter_current_state = REMOVE_DEST) and (remove_ctr = x"03") )then\r
+      saved_src_mac(7 downto 0) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"04") ) then\r
+      saved_src_mac(15 downto 8) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"05") ) then\r
+      saved_src_mac(23 downto 16) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"06") ) then\r
+      saved_src_mac(31 downto 24) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"07") ) then\r
+      saved_src_mac(39 downto 32) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"08") ) then\r
+      saved_src_mac(47 downto 40) <= MAC_RXD_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SAVED_SRC_MAC_PROC;\r
+\r
+-- saves the frame type of the incoming frame for futher check\r
+THE_SAVED_FRAME_TYPE_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( filter_current_state = CLEANUP ) then\r
+      saved_frame_type <= (others => '0');\r
+    elsif( (filter_current_state = REMOVE_SRC) and (remove_ctr = x"09") ) then\r
+      saved_frame_type(15 downto 8) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_TYPE) and (remove_ctr = x"0a") ) then\r
+      saved_frame_type(7 downto 0) <= MAC_RXD_IN;\r
+    -- two more cases for VLAN tagged frame\r
+    elsif( (filter_current_state = REMOVE_VID) and (remove_ctr = x"0d") ) then\r
+      saved_frame_type(15 downto 8) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_VTYPE) and (remove_ctr = x"0e") ) then\r
+      saved_frame_type(7 downto 0) <= MAC_RXD_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SAVED_FRAME_TYPE_PROC;\r
+\r
+THE_SAVED_SRC_IP_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( filter_current_state = CLEANUP ) then\r
+      saved_src_ip <= (others => '0');\r
+    elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0a") ) then\r
+      saved_src_ip(7 downto 0) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0b") ) then\r
+      saved_src_ip(15 downto 8) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0c") ) then\r
+      saved_src_ip(23 downto 16) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0d") ) then\r
+      saved_src_ip(31 downto 24) <= MAC_RXD_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SAVED_SRC_IP_PROC;\r
+\r
+THE_SAVED_DEST_IP_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( filter_current_state = CLEANUP ) then\r
+      saved_dest_ip <= (others => '0');\r
+    elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0e") ) then\r
+      saved_dest_ip(7 downto 0) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"0f") ) then\r
+      saved_dest_ip(15 downto 8) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"10") ) then\r
+      saved_dest_ip(23 downto 16) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_IP) and (remove_ctr = x"11") ) then\r
+      saved_dest_ip(31 downto 24) <= MAC_RXD_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SAVED_DEST_IP_PROC;\r
+\r
+THE_SAVED_SRC_UDP_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( filter_current_state = CLEANUP ) then\r
+      saved_src_udp <= (others => '0');\r
+    elsif( (filter_current_state = REMOVE_UDP) and (remove_ctr = x"12") ) then\r
+      saved_src_udp(15 downto 8) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_UDP) and (remove_ctr = x"13") ) then\r
+      saved_src_udp(7 downto 0) <= MAC_RXD_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SAVED_SRC_UDP_PROC;\r
+\r
+THE_SAVED_DEST_UDP_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( filter_current_state = CLEANUP ) then\r
+      saved_dest_udp <= (others => '0');\r
+    elsif( (filter_current_state = REMOVE_UDP) and (remove_ctr = x"14") ) then\r
+      saved_dest_udp(15 downto 8) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_UDP) and (remove_ctr = x"15") ) then\r
+      saved_dest_udp(7 downto 0) <= MAC_RXD_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SAVED_DEST_UDP_PROC;\r
+\r
+-- saves VLAN id when tagged frame spotted\r
+THE_SAVED_VID_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if   ( filter_current_state = CLEANUP ) then\r
+      saved_vid <= (others => '0');\r
+    elsif( (filter_current_state = REMOVE_TYPE) and (remove_ctr = x"0b") and (saved_frame_type = x"8100") ) then\r
+      saved_vid(15 downto 8) <= MAC_RXD_IN;\r
+    elsif( (filter_current_state = REMOVE_VID) and (remove_ctr = x"0c") ) then\r
+      saved_vid(7 downto 0) <= MAC_RXD_IN;\r
+    end if;\r
+  end if;\r
+end process THE_SAVED_VID_PROC;\r
+\r
+THE_TYPE_VALIDATOR: entity gbe_type_validator\r
+port map(\r
+  CLK                      => CLK,\r
+  RESET                    => RESET,\r
+  FRAME_TYPE_IN            => saved_frame_type,\r
+  ALLOWED_TYPES_IN         => FR_ALLOWED_TYPES_IN,\r
+  SAVED_VLAN_ID_IN         => saved_vid,\r
+  VLAN_ID_IN               => FR_VLAN_ID_IN,\r
+  -- IP level\r
+  IP_PROTOCOLS_IN          => saved_proto,\r
+  ALLOWED_IP_PROTOCOLS_IN  => FR_ALLOWED_IP_IN,\r
+  -- UDP level\r
+  UDP_PROTOCOL_IN          => saved_dest_udp,\r
+  ALLOWED_UDP_PROTOCOLS_IN => FR_ALLOWED_UDP_IN,\r
+  --\r
+  VALID_OUT                => frame_type_valid\r
+);\r
+\r
+THE_RECEIVE_FIFO: entity fifo_4096x9\r
+port map(\r
+  Data      => rx_data,\r
+  WrClock   => CLK,\r
+  RdClock   => CLK,\r
+  WrEn      => fifo_wr_en,\r
+  RdEn      => FR_RD_EN_IN,\r
+  Reset     => RESET,\r
+  RPReset   => RESET,\r
+  Q         => fr_q,\r
+  Empty     => rec_fifo_empty,\r
+  Full      => rec_fifo_full\r
+);\r
+\r
+-- killer ping\r
+THE_KILLER_PING_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( (filter_current_state = SAVE_FRAME) and \r
+        (saved_proto = x"01") and \r
+        (saved_frame_type = x"0800") and\r
+        (rx_bytes_ctr = x"001A") and \r
+        (rx_data(7 downto 0) = MY_TRBNET_ADDRESS_IN(7 downto 0)) and\r
+        (MAC_RXD_IN = MY_TRBNET_ADDRESS_IN(15 downto 8)) ) then\r
+      ISSUE_REBOOT_OUT <= '1';\r
+    else\r
+      ISSUE_REBOOT_OUT <= '0';\r
+    end if;\r
+  end if;\r
+end process THE_KILLER_PING_PROC;\r
+\r
+THE_SECRET_FRAME_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( (filter_current_state = DECIDE) and \r
+        (saved_proto = x"11") and \r
+        (saved_frame_type = x"0800") and\r
+        (saved_dest_udp = x"d903") and \r
+        (saved_src_udp = x"2b67") ) then\r
+      oob_write <= '1';\r
+    else\r
+      oob_write <= '0';\r
+    end if;\r
+  end if;\r
+end process THE_SECRET_FRAME_PROC;\r
+\r
+THE_REGISTERS_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( oob_write = '1' ) then\r
+      case saved_src_ip(1 downto 0) is\r
+        when b"00"  => oob_register_0_int <= saved_dest_ip;\r
+        when b"01"  => oob_register_1_int <= saved_dest_ip;\r
+        when b"10"  => oob_register_2_int <= saved_dest_ip;\r
+        when others => oob_register_3_int <= saved_dest_ip;\r
+      end case;\r
+    end if;\r
+  end if;\r
+end process THE_REGISTERS_PROC;\r
+\r
+OOB_REGISTER_0_OUT <= oob_register_0_int;\r
+OOB_REGISTER_1_OUT <= oob_register_1_int;\r
+OOB_REGISTER_2_OUT <= oob_register_2_int;\r
+OOB_REGISTER_3_OUT <= oob_register_3_int;\r
+\r
+THE_RX_FIFO_SYNC: process( CLK )\r
+begin\r
+  if rising_edge(CLK) then\r
+\r
+    rx_data(8)          <= MAC_RX_EOF_IN;\r
+    rx_data(7 downto 0) <= MAC_RXD_IN;\r
+\r
+    if( MAC_RX_EN_IN = '1' ) then\r
+      if   ( filter_current_state = SAVE_FRAME ) then\r
+        fifo_wr_en <= '1';\r
+--      elsif( (filter_current_state = REMOVE_VTYPE) and (remove_ctr = x"0f") ) then\r
+--        fifo_wr_en <= '1';\r
+      elsif( (filter_current_state = DECIDE) and (frame_type_valid = '1') ) then\r
+        fifo_wr_en <= '1';\r
+      else\r
+        fifo_wr_en <= '0';\r
+      end if;\r
+    else\r
+      fifo_wr_en <= '0';\r
+    end if;\r
+\r
+  end if;\r
+end process THE_RX_FIFO_SYNC;\r
+\r
+THE_SIZES_FIFO: entity fifo_512x32\r
+port map(\r
+  Data(15 downto 0)   => rx_bytes_ctr,\r
+  Data(31 downto 16)  => saved_frame_type,\r
+  WrClock             => CLK,\r
+  RdClock             => CLK,\r
+  WrEn                => frame_valid_q,\r
+  RdEn                => FR_GET_FRAME_IN,\r
+  Reset               => RESET,\r
+  RPReset             => RESET,\r
+  Q(15 downto 0)      => fr_frame_size,\r
+  Q(31 downto 16)     => fr_frame_proto,\r
+  Empty               => sizes_fifo_empty,\r
+  Full                => sizes_fifo_full\r
+);\r
+\r
+THE_MACS_FIFO: entity fifo_512x72\r
+port map(\r
+  Data(47 downto 0)   => saved_src_mac,\r
+  Data(63 downto 48)  => saved_src_udp,\r
+  Data(71 downto 64)  => (others => '0'),\r
+  WrClock             => CLK,\r
+  RdClock             => CLK,\r
+  WrEn                => frame_valid_q,\r
+  RdEn                => FR_GET_FRAME_IN,\r
+  Reset               => RESET,\r
+  RPReset             => RESET,\r
+  Q(47 downto 0)      => fr_src_mac,\r
+  Q(63 downto 48)     => fr_src_udp,\r
+  Q(71 downto 64)     => xxx0, --open,\r
+  Empty               => open,\r
+  Full                => open\r
+);\r
+\r
+THE_MACD_FIFO: entity fifo_512x72\r
+port map(\r
+  Data(47 downto 0)   => saved_dest_mac,\r
+  Data(63 downto 48)  => saved_dest_udp,\r
+  Data(71 downto 64)  => (others => '0'),\r
+  WrClock             => CLK,\r
+  RdClock             => CLK,\r
+  WrEn                => frame_valid_q,\r
+  RdEn                => FR_GET_FRAME_IN,\r
+  Reset               => RESET,\r
+  RPReset             => RESET,\r
+  Q(47 downto 0)      => fr_dest_mac,\r
+  Q(63 downto 48)     => fr_dest_udp,\r
+  Q(71 downto 64)     => xxx1, --open,\r
+  Empty               => open,\r
+  Full                => open\r
+);\r
+\r
+THE_IP_FIFO: entity fifo_512x72\r
+port map(\r
+  Data(31 downto 0)   => saved_src_ip,\r
+  Data(63 downto 32)  => saved_dest_ip,\r
+  Data(71 downto 64)  => saved_proto,\r
+  WrClock             => CLK,\r
+  RdClock             => CLK,\r
+  WrEn                => frame_valid_q,\r
+  RdEn                => FR_GET_FRAME_IN,\r
+  Reset               => RESET,\r
+  RPReset             => RESET,\r
+  Q(31 downto 0)      => fr_src_ip,\r
+  Q(63 downto 32)     => fr_dest_ip,\r
+  Q(71 downto 64)     => fr_ip_proto,\r
+  Empty               => open,\r
+  Full                => open\r
+);\r
+\r
+THE_SYNC_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    FR_SRC_IP_ADDRESS_OUT   <= fr_src_ip;\r
+    FR_DEST_IP_ADDRESS_OUT  <= fr_dest_ip;\r
+    FR_IP_PROTOCOL_OUT      <= fr_ip_proto;\r
+    FR_DEST_UDP_PORT_OUT    <= fr_dest_udp;\r
+    FR_DEST_MAC_ADDRESS_OUT <= fr_dest_mac;\r
+    FR_SRC_MAC_ADDRESS_OUT  <= fr_src_mac;\r
+    FR_SRC_UDP_PORT_OUT     <= fr_src_udp;\r
+    FR_FRAME_PROTO_OUT      <= fr_frame_proto;\r
+    FR_FRAME_SIZE_OUT       <= fr_frame_size;\r
+    FR_Q_OUT                <= fr_q;\r
+    --\r
+    delayed_frame_valid     <= MAC_RX_EOF_IN;\r
+    delayed_frame_valid_q   <= delayed_frame_valid;\r
+  end if;\r
+end process THE_SYNC_PROC;\r
+\r
+THE_FRAME_VALID_PROC: process( CLK )\r
+begin\r
+  if( rising_edge(CLK) ) then\r
+    if( (MAC_RX_EOF_IN = '1') and (ALLOW_RX_IN = '1') and (frame_type_valid = '1') ) then\r
+      frame_valid_q <= '1';\r
+    else\r
+      frame_valid_q <= '0';\r
+    end if;\r
+  end if;\r
+end process THE_FRAME_VALID_PROC;\r
+\r
+THE_RX_BYTES_CTR_PROC: process( CLK, RESET )\r
+begin\r
+  if   ( RESET = '1' ) then\r
+    rx_bytes_ctr <= x"0001";\r
+  elsif( rising_edge(CLK) ) then\r
+    if( delayed_frame_valid_q = '1' ) then\r
+      rx_bytes_ctr <= x"0001";\r
+    elsif( fifo_wr_en = '1' ) then\r
+      rx_bytes_ctr <= rx_bytes_ctr + 1;\r
+    end if;\r
+  end if;\r
+end process THE_RX_BYTES_CTR_PROC;\r
+\r
+THE_ERROR_FRAMES_CTR_PROC: process( CLK, RESET )\r
+begin\r
+  if   ( RESET = '1' ) then\r
+    error_frames_ctr <= (others => '0');\r
+  elsif( rising_edge(CLK) ) then\r
+    error_frames_ctr <= error_frames_ctr + 1;\r
+  end if;\r
+end process THE_ERROR_FRAMES_CTR_PROC;\r
+\r
+FR_FRAME_VALID_OUT <= frame_valid_q when rising_edge(CLK);\r
+\r
+THE_RECEIVED_FRAMES_CTR: process( CLK, RESET )\r
+begin\r
+  if   ( RESET = '1' ) then\r
+    dbg_rec_frames <= (others => '0');\r
+  elsif( rising_edge(CLK) ) then\r
+    dbg_rec_frames <= dbg_rec_frames + 1;\r
+  end if;\r
+end process THE_RECEIVED_FRAMES_CTR;\r
+\r
+THE_DROPPED_FRAMES_CTR: process( CLK, RESET )\r
+begin\r
+  if   ( RESET = '1' ) then\r
+    dbg_drp_frames <= (others => '0');\r
+  elsif( rising_edge(CLK) ) then\r
+    if( (filter_current_state = DECIDE) and (frame_type_valid = '0') ) then\r
+      dbg_drp_frames <= dbg_drp_frames + 1;\r
+    end if;\r
+  end if;\r
+end process THE_DROPPED_FRAMES_CTR;\r
+\r
+MONITOR_DROPPED_OUT   <= std_logic_vector(dbg_drp_frames);\r
+MONITOR_RX_FRAMES_OUT <= std_logic_vector(dbg_rec_frames);\r
+MONITOR_RX_BYTES_OUT  <= std_logic_vector(mon_rec_bytes);\r
+\r
+THE_MON_REC_BYTES_PROC: process( CLK, RESET )\r
+begin\r
+  if   ( RESET = '1' ) then\r
+    mon_rec_bytes <= (others => '0');\r
+  elsif( rising_edge(CLK) ) then\r
+    if( fifo_wr_en = '1' ) then\r
+      mon_rec_bytes <= mon_rec_bytes + x"1";\r
+    end if;\r
+  end if;\r
+end process;\r
+\r
+end gbe_frame_receiver_arch;\r
index d9ef582e0f3f81ff6127f92a70697b6c9773fe69..b2a52551787ed8dd267d44a93e2c05e9fcc94fe9 100644 (file)
@@ -1,14 +1,9 @@
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.std_logic_ARITH.all;
-use IEEE.std_logic_UNSIGNED.all;
+library ieee;
+  use ieee.std_logic_1164.all;
+  use ieee.numeric_std.all;
 
 library work;
-use work.trb_net_std.all;
-use work.trb_net_components.all;
-
---use work.trb_net_gbe_components.all;
-use work.gbe_protocols.all;
+  use work.gbe_protocols.all;
 
 entity gbe_logic_wrapper is
   generic(
@@ -84,7 +79,8 @@ entity gbe_logic_wrapper is
   );
 end entity gbe_logic_wrapper;
 
-architecture RTL of gbe_logic_wrapper is
+architecture gbe_logic_wrapper_arch of gbe_logic_wrapper is
+
   signal fr_q                   : std_logic_vector(8 downto 0);
   signal fr_rd_en               : std_logic;
   signal fr_frame_valid         : std_logic;
@@ -160,9 +156,6 @@ architecture RTL of gbe_logic_wrapper is
 
   signal dbg_select_gen         : std_logic_vector(2 * c_MAX_PROTOCOLS * 32 - 1 downto 0);
 
---  signal global_reset           : std_logic;
---  signal rst_n                  : std_logic;
---  signal ff                     : std_logic;
   signal link_ok                : std_logic;
   signal dhcp_done              : std_logic;
 
@@ -184,7 +177,7 @@ begin
 
   DHCP_DONE_OUT <= dhcp_done;
 
-  MAIN_CONTROL: entity work.trb_net16_gbe_main_control
+  THE_GBE_MAIN_CONTROL: entity work.gbe_main_control
     generic map(
       INCLUDE_SLOWCTRL     => INCLUDE_SLOWCTRL,
       INCLUDE_DHCP         => INCLUDE_DHCP,
@@ -270,7 +263,7 @@ begin
 
   MAKE_RESET_OUT <= make_reset;
   
-  TRANSMIT_CONTROLLER: entity trb_net16_gbe_transmit_control2
+  THE_TRANSMIT_CONTROL: entity work.gbe_transmit_control
     port map(
       CLK                      => CLK_125_IN,
       RESET                    => RESET, --global_reset,
@@ -312,7 +305,7 @@ begin
       MONITOR_TX_PACKETS_OUT   => monitor_tx_packets
     );
 
-  FRAME_CONSTRUCTOR: entity trb_net16_gbe_frame_constr
+  THE_FRAME_CONSTR: entity work.gbe_frame_constr
     port map(
       RESET                   => RESET, --global_reset,
       CLK                     => CLK_125_IN,
@@ -349,7 +342,7 @@ begin
 --  frame_pause <= x"0000" & CFG_THROTTLE_PAUSE_IN; -- TAKE CARE!!!
   frame_pause <= x"0000" & x"0000"; -- TAKE CARE!!!
 
-  RECEIVE_CONTROLLER: entity trb_net16_gbe_receive_control
+  THE_RECEIVE_CONTROL: entity work.gbe_receive_control
     port map(
       CLK                     => CLK_125_IN,
       RESET                   => RESET, --global_reset,
@@ -386,7 +379,7 @@ begin
       DEBUG_OUT               => rc_debug
     );
 
-  FRAME_RECEIVER: entity trb_net16_gbe_frame_receiver
+  THE_FRAME_RECEIVER: entity work.gbe_frame_receiver
     port map(
       CLK                     => CLK_125_IN,
       RESET                   => RESET, --global_reset,
@@ -440,4 +433,4 @@ begin
 
   MONITOR_GEN_DBG_OUT    <= dbg_select_gen;
 
-end architecture RTL;
+end architecture gbe_logic_wrapper_arch;
diff --git a/gbe_trb/base/gbe_main_control.vhd b/gbe_trb/base/gbe_main_control.vhd
new file mode 100644 (file)
index 0000000..8166510
--- /dev/null
@@ -0,0 +1,594 @@
+library ieee;
+  use ieee.std_logic_1164.all;
+  use ieee.numeric_std.all;
+
+library work;
+  use work.trb_net_std.all;
+  use work.gbe_protocols.all;
+
+entity gbe_main_control is
+  generic(
+    INCLUDE_SLOWCTRL     : std_logic := '0';
+    INCLUDE_DHCP         : std_logic := '0';
+    INCLUDE_ARP          : std_logic := '0';
+    INCLUDE_PING         : std_logic := '0';
+    INCLUDE_FWD          : std_logic := '0';
+    --
+    SLOWCTRL_BUFFER_SIZE : integer range 1 to 4
+  );
+  port(
+    CLK                           : in  std_logic; -- system clock
+    CLK_125                       : in  std_logic;
+    RESET                         : in  std_logic;
+    --
+    MC_LINK_OK_OUT                : out std_logic; -- remark: set to '1' internally
+    MC_DHCP_DONE_OUT              : out std_logic; -- remark: set if link_current_state = ACTIVE
+    MY_IP_OUT                     : out std_logic_vector(31 downto 0);
+    MC_MY_MAC_IN                  : in  std_logic_vector(47 downto 0);
+    MY_TRBNET_ADDRESS_IN          : in  std_logic_vector(15 downto 0);
+    ISSUE_REBOOT_OUT              : out std_logic;
+    -- signals to/from receive controller
+    RC_FRAME_WAITING_IN           : in  std_logic;
+    RC_LOADING_DONE_OUT           : out std_logic;
+    RC_DATA_IN                    : in  std_logic_vector(8 downto 0);
+    RC_RD_EN_OUT                  : out std_logic;
+    RC_FRAME_SIZE_IN              : in  std_logic_vector(15 downto 0);
+    RC_FRAME_PROTO_IN             : in  std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+    --
+    RC_SRC_MAC_ADDRESS_IN         : in  std_logic_vector(47 downto 0);
+    RC_DEST_MAC_ADDRESS_IN        : in  std_logic_vector(47 downto 0);
+    RC_SRC_IP_ADDRESS_IN          : in  std_logic_vector(31 downto 0);
+    RC_DEST_IP_ADDRESS_IN         : in  std_logic_vector(31 downto 0);
+    RC_SRC_UDP_PORT_IN            : in  std_logic_vector(15 downto 0);
+    RC_DEST_UDP_PORT_IN           : in  std_logic_vector(15 downto 0);
+    -- signals to/from transmit controller
+    TC_TRANSMIT_CTRL_OUT          : out std_logic;
+    TC_DATA_OUT                   : out std_logic_vector(8 downto 0);
+    TC_RD_EN_IN                   : in  std_logic;
+    TC_FRAME_SIZE_OUT             : out std_logic_vector(15 downto 0);
+    TC_FRAME_TYPE_OUT             : out std_logic_vector(15 downto 0);
+    TC_DEST_MAC_OUT               : out std_logic_vector(47 downto 0);
+    TC_DEST_IP_OUT                : out std_logic_vector(31 downto 0);
+    TC_DEST_UDP_OUT               : out std_logic_vector(15 downto 0);
+    TC_SRC_MAC_OUT                : out std_logic_vector(47 downto 0);
+    TC_SRC_IP_OUT                 : out std_logic_vector(31 downto 0);
+    TC_SRC_UDP_OUT                : out std_logic_vector(15 downto 0);
+    TC_FLAGS_OFFSET_OUT           : out std_logic_vector(15 downto 0);
+    TC_IP_PROTOCOL_OUT            : out std_logic_vector(7 downto 0);
+    TC_IDENT_OUT                  : out std_logic_vector(15 downto 0);
+    TC_TRANSMIT_DONE_IN           : in  std_logic;
+    -- signals to/from sgmii/gbe pcs_an_complete
+    PCS_AN_COMPLETE_IN            : in  std_logic;
+    MAC_READY_CONF_IN             : in  std_logic;
+    -- signals to/from hub
+    GSC_CLK_IN                    : in  std_logic;
+    GSC_INIT_DATAREADY_OUT        : out std_logic;
+    GSC_INIT_DATA_OUT             : out std_logic_vector(15 downto 0);
+    GSC_INIT_PACKET_NUM_OUT       : out std_logic_vector(2 downto 0);
+    GSC_INIT_READ_IN              : in  std_logic;
+    GSC_REPLY_DATAREADY_IN        : in  std_logic;
+    GSC_REPLY_DATA_IN             : in  std_logic_vector(15 downto 0);
+    GSC_REPLY_PACKET_NUM_IN       : in  std_logic_vector(2 downto 0);
+    GSC_REPLY_READ_OUT            : out std_logic;
+    GSC_BUSY_IN                   : in  std_logic;
+    CFG_MAX_REPLY_SIZE_IN         : in  std_logic_vector(31 downto 0);
+    --
+    RESET_TRBNET_IN               : in  std_logic;
+    RESET_SCTRL_IN                : in  std_logic;
+    MAKE_RESET_OUT                : out std_logic;
+    -- Forwarder
+    FWD_DST_MAC_IN                : in  std_logic_vector(47 downto 0);
+    FWD_DST_IP_IN                 : in  std_logic_vector(31 downto 0);
+    FWD_DST_UDP_IN                : in  std_logic_vector(15 downto 0);
+    FWD_DATA_IN                   : in  std_logic_vector(7 downto 0);
+    FWD_DATA_VALID_IN             : in  std_logic;
+    FWD_SOP_IN                    : in  std_logic;
+    FWD_EOP_IN                    : in  std_logic;
+    FWD_READY_OUT                 : out std_logic;
+    FWD_FULL_OUT                  : out std_logic;
+    --
+    MONITOR_SELECT_REC_OUT        : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    MONITOR_SELECT_REC_BYTES_OUT  : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    MONITOR_SELECT_SENT_BYTES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    MONITOR_SELECT_SENT_OUT       : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    MONITOR_SELECT_GEN_DBG_OUT    : out std_logic_vector(2 * c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    --
+    SCTRL_HIST_OUT                : out hist_array;
+    --
+    DEBUG_OUT                     : out std_logic_vector(63 downto 0)
+  );
+end gbe_main_control;
+
+architecture gbe_main_control_arch of gbe_main_control is
+
+  attribute syn_encoding : string;
+
+  type link_states is (INACTIVE, ACTIVE, ENABLE_MAC, TIMEOUT, FINALIZE, WAIT_FOR_BOOT, GET_ADDRESS);
+  signal link_current_state, link_next_state : link_states;
+  attribute syn_encoding of link_current_state : signal is "onehot";
+
+  signal link_ok             : std_logic;
+  signal link_ok_timeout_ctr : unsigned(15 downto 0);
+
+  type flow_states is (IDLE, TRANSMIT_CTRL, WAIT_FOR_FC, CLEANUP);
+  signal flow_current_state, flow_next_state : flow_states;
+  attribute syn_encoding of flow_current_state : signal is "onehot";
+
+  signal state               : std_logic_vector(3 downto 0);
+  signal link_state          : std_logic_vector(3 downto 0);
+  signal redirect_state      : std_logic_vector(3 downto 0);
+
+  signal ps_wr_en            : std_logic;
+  signal ps_response_ready   : std_logic;
+  signal ps_busy             : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+  signal rc_rd_en            : std_logic;
+  signal proto_select        : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+  signal loaded_bytes_ctr    : unsigned(15 downto 0);
+
+  signal dhcp_start          : std_logic;
+  signal dhcp_done           : std_logic;
+  signal wait_ctr            : unsigned(31 downto 0);
+
+  signal rc_data_local       : std_logic_vector(8 downto 0);
+
+  type redirect_states is (IDLE, CHECK_TYPE, DROP, CHECK_BUSY, LOAD, BUSY, WAIT_ONE, FINISH, CLEANUP);
+  signal redirect_current_state, redirect_next_state : redirect_states;
+  attribute syn_encoding of redirect_current_state : signal is "onehot";
+
+  signal disable_redirect    : std_logic;
+  signal ps_wr_en_q          : std_logic;
+  signal ps_wr_en_qq         : std_logic;
+
+  signal tc_data             : std_logic_vector(8 downto 0);
+
+  attribute syn_preserve : boolean;
+  attribute syn_keep : boolean;
+  attribute syn_keep of link_state, state, redirect_state, dhcp_done : signal is true;
+  attribute syn_preserve of link_state, state, redirect_state, dhcp_done : signal is true;
+
+  signal mc_busy             : std_logic;
+  signal incl_dhcp           : std_logic;
+  signal flow_state          : std_logic_vector(3 downto 0);
+  signal selector_debug      : std_logic_vector(63 downto 0);
+
+begin
+  THE_PROTOCOL_SELECTOR: entity work.gbe_protocol_selector
+    generic map(
+      INCLUDE_SLOWCTRL     => INCLUDE_SLOWCTRL,
+      INCLUDE_DHCP         => INCLUDE_DHCP,
+      INCLUDE_ARP          => INCLUDE_ARP,
+      INCLUDE_PING         => INCLUDE_PING,
+      INCLUDE_FWD          => INCLUDE_FWD,
+      SLOWCTRL_BUFFER_SIZE => SLOWCTRL_BUFFER_SIZE
+    )
+    port map(
+      CLK                           => CLK,
+      RESET                         => RESET,
+      PS_DATA_IN                    => rc_data_local,
+      PS_WR_EN_IN                   => ps_wr_en_qq,
+      PS_PROTO_SELECT_IN            => proto_select,
+      PS_BUSY_OUT                   => ps_busy,
+      PS_FRAME_SIZE_IN              => RC_FRAME_SIZE_IN,
+      PS_RESPONSE_READY_OUT         => ps_response_ready,
+      PS_SRC_MAC_ADDRESS_IN         => RC_SRC_MAC_ADDRESS_IN,
+      PS_DEST_MAC_ADDRESS_IN        => RC_DEST_MAC_ADDRESS_IN,
+      PS_SRC_IP_ADDRESS_IN          => RC_SRC_IP_ADDRESS_IN,
+      PS_DEST_IP_ADDRESS_IN         => RC_DEST_IP_ADDRESS_IN,
+      PS_SRC_UDP_PORT_IN            => RC_SRC_UDP_PORT_IN,
+      PS_DEST_UDP_PORT_IN           => RC_DEST_UDP_PORT_IN,
+      TC_DATA_OUT                   => tc_data,
+      TC_RD_EN_IN                   => TC_RD_EN_IN,
+      TC_FRAME_SIZE_OUT             => TC_FRAME_SIZE_OUT,
+      TC_FRAME_TYPE_OUT             => TC_FRAME_TYPE_OUT,
+      TC_IP_PROTOCOL_OUT            => TC_IP_PROTOCOL_OUT,
+      TC_IDENT_OUT                  => TC_IDENT_OUT,
+      TC_DEST_MAC_OUT               => TC_DEST_MAC_OUT,
+      TC_DEST_IP_OUT                => TC_DEST_IP_OUT,
+      TC_DEST_UDP_OUT               => TC_DEST_UDP_OUT,
+      TC_SRC_MAC_OUT                => TC_SRC_MAC_OUT,
+      TC_SRC_IP_OUT                 => TC_SRC_IP_OUT,
+      TC_SRC_UDP_OUT                => TC_SRC_UDP_OUT,
+      MC_BUSY_IN                    => mc_busy,
+      MY_MAC_IN                     => MC_MY_MAC_IN,
+      MY_IP_OUT                     => MY_IP_OUT,
+      DHCP_START_IN                 => dhcp_start,
+      DHCP_DONE_OUT                 => dhcp_done,
+      GSC_CLK_IN                    => GSC_CLK_IN,
+      GSC_INIT_DATAREADY_OUT        => GSC_INIT_DATAREADY_OUT,
+      GSC_INIT_DATA_OUT             => GSC_INIT_DATA_OUT,
+      GSC_INIT_PACKET_NUM_OUT       => GSC_INIT_PACKET_NUM_OUT,
+      GSC_INIT_READ_IN              => GSC_INIT_READ_IN,
+      GSC_REPLY_DATAREADY_IN        => GSC_REPLY_DATAREADY_IN,
+      GSC_REPLY_DATA_IN             => GSC_REPLY_DATA_IN,
+      GSC_REPLY_PACKET_NUM_IN       => GSC_REPLY_PACKET_NUM_IN,
+      GSC_REPLY_READ_OUT            => GSC_REPLY_READ_OUT,
+      GSC_BUSY_IN                   => GSC_BUSY_IN,
+      MAKE_RESET_OUT                => MAKE_RESET_OUT,
+
+      MY_TRBNET_ADDRESS_IN          => MY_TRBNET_ADDRESS_IN,
+--      ISSUE_REBOOT_OUT              => ISSUE_REBOOT_OUT,
+
+      CFG_MAX_REPLY_SIZE_IN         => CFG_MAX_REPLY_SIZE_IN,
+
+      FWD_DST_MAC_IN                => FWD_DST_MAC_IN,
+      FWD_DST_IP_IN                 => FWD_DST_IP_IN,
+      FWD_DST_UDP_IN                => FWD_DST_UDP_IN,
+      FWD_DATA_IN                   => FWD_DATA_IN,
+      FWD_DATA_VALID_IN             => FWD_DATA_VALID_IN,
+      FWD_SOP_IN                    => FWD_SOP_IN,
+      FWD_EOP_IN                    => FWD_EOP_IN,
+      FWD_READY_OUT                 => FWD_READY_OUT,
+      FWD_FULL_OUT                  => FWD_FULL_OUT,
+
+      -- input for statistics from outside
+      MONITOR_SELECT_REC_OUT        => MONITOR_SELECT_REC_OUT,
+      MONITOR_SELECT_REC_BYTES_OUT  => MONITOR_SELECT_REC_BYTES_OUT,
+      MONITOR_SELECT_SENT_BYTES_OUT => MONITOR_SELECT_SENT_BYTES_OUT,
+      MONITOR_SELECT_SENT_OUT       => MONITOR_SELECT_SENT_OUT,
+      MONITOR_SELECT_GEN_DBG_OUT    => MONITOR_SELECT_GEN_DBG_OUT,
+      SCTRL_HIST_OUT                => SCTRL_HIST_OUT,
+      DEBUG_OUT                     => selector_debug
+    );
+
+  TC_DATA_OUT <= tc_data;
+
+  -- gk 07.11.11
+  -- do not select any response constructors when dropping a frame
+  proto_select <= RC_FRAME_PROTO_IN when disable_redirect = '0' else (others => '0');
+
+  -- gk 07.11.11
+  -- we do not answer at all, unless we are in either ACTIVE or GET_ADDRESS state.
+  -- in GET_ADDRESS state, we only answer on DHCP frames.
+  PROC_DISABLE_REDIRECT: process( CLK, RESET )
+  begin
+    if   ( RESET = '1' ) then
+      disable_redirect <= '0';
+    elsif( rising_edge(CLK) ) then
+      if( redirect_current_state = CHECK_TYPE ) then
+        if   ( (link_current_state /= ACTIVE) and (link_current_state /= GET_ADDRESS) ) then
+          disable_redirect <= '1';
+        elsif( (link_current_state = GET_ADDRESS) and (RC_FRAME_PROTO_IN /= "10") ) then -- (UDP, DHCP)
+          disable_redirect <= '1';
+        else
+          disable_redirect <= '0';
+        end if;
+      end if;
+    end if;
+  end process PROC_DISABLE_REDIRECT;
+
+  -- warning
+  PROC_SYNC: process( CLK )
+  begin
+    if( rising_edge(CLK) ) then
+      rc_data_local <= RC_DATA_IN;
+    end if;
+  end process PROC_SYNC;
+
+  PROC_REDIRECT_FSM: process( CLK, RESET )
+  begin
+    if   ( RESET = '1' ) then
+      redirect_current_state <= IDLE;
+    elsif( rising_edge(CLK) ) then
+      redirect_current_state <= redirect_next_state;
+    end if;
+  end process PROC_REDIRECT_FSM;
+
+  PROC_REDIRECT_TRANSITIONS: process( redirect_current_state, link_current_state, RC_FRAME_WAITING_IN, 
+                                      ps_busy, RC_FRAME_PROTO_IN, loaded_bytes_ctr, RC_FRAME_SIZE_IN )
+  begin
+    redirect_state <= x"0";
+
+    case redirect_current_state is
+      when IDLE =>
+        redirect_state <= x"1";
+        if( RC_FRAME_WAITING_IN = '1' ) then
+          redirect_next_state <= CHECK_TYPE;
+        else
+          redirect_next_state <= IDLE;
+        end if;
+
+      when CHECK_TYPE =>
+        redirect_state <= x"2";
+        if   ( link_current_state = ACTIVE ) then
+          redirect_next_state <= CHECK_BUSY;
+        elsif( (link_current_state = GET_ADDRESS) and (RC_FRAME_PROTO_IN = "10") ) then
+          redirect_next_state <= CHECK_BUSY;
+        else
+          redirect_next_state <= DROP;
+        end if;
+
+      when DROP =>
+        redirect_state <= x"3";
+        if( loaded_bytes_ctr = unsigned(RC_FRAME_SIZE_IN) - 1 ) then
+          redirect_next_state <= WAIT_ONE;
+        else
+          redirect_next_state <= DROP;
+        end if;
+
+      when CHECK_BUSY =>
+        redirect_state <= x"4";
+        if( or_all(ps_busy and RC_FRAME_PROTO_IN) = '0' ) then
+          redirect_next_state <= LOAD;
+        else
+          redirect_next_state <= BUSY;
+        end if;
+
+      when LOAD =>
+        redirect_state <= x"5";
+        if( loaded_bytes_ctr = unsigned(RC_FRAME_SIZE_IN) - 1 ) then
+          redirect_next_state <= WAIT_ONE;
+        else
+          redirect_next_state <= LOAD;
+        end if;
+
+      when BUSY =>
+        redirect_state <= x"6";
+        if( or_all(ps_busy and RC_FRAME_PROTO_IN) = '0' ) then
+          redirect_next_state <= LOAD;
+        else
+          redirect_next_state <= BUSY;
+        end if;
+
+      when WAIT_ONE =>
+        redirect_state      <= x"7";
+        redirect_next_state <= FINISH;
+
+      when FINISH =>
+        redirect_state      <= x"8";
+        redirect_next_state <= CLEANUP;
+
+      when CLEANUP =>
+        redirect_state      <= x"9";
+        redirect_next_state <= IDLE;
+
+      when others => redirect_next_state <= IDLE;
+
+    end case;
+  end process PROC_REDIRECT_TRANSITIONS;
+
+  rc_rd_en     <= '1' when redirect_current_state = LOAD or redirect_current_state = DROP else '0';
+  RC_RD_EN_OUT <= rc_rd_en;
+
+  PROC_LOADING_DONE: process( CLK )
+  begin
+    if rising_edge(CLK) then
+      if (RC_DATA_IN(8) = '1' and ps_wr_en_q = '1') then
+        RC_LOADING_DONE_OUT <= '1';
+      else
+        RC_LOADING_DONE_OUT <= '0';
+      end if;
+    end if;
+  end process PROC_LOADING_DONE;
+
+  PROC_PS_WR_EN: process( CLK )
+  begin
+    if rising_edge(CLK) then
+      ps_wr_en    <= rc_rd_en;
+      ps_wr_en_q  <= ps_wr_en;
+      ps_wr_en_qq <= ps_wr_en_q;
+    end if;
+  end process PROC_PS_WR_EN;
+
+  PROC_LOADED_BYTES_CTR: process( CLK )
+  begin
+    if rising_edge(CLK) then
+      if   ( redirect_current_state = IDLE) then
+        loaded_bytes_ctr <= (others => '0');
+      elsif( ((redirect_current_state = LOAD) or (redirect_current_state = DROP)) and (rc_rd_en = '1') )then
+        loaded_bytes_ctr <= loaded_bytes_ctr + x"1";
+      end if;
+    end if;
+  end process PROC_LOADED_BYTES_CTR;
+
+  --*********************
+  --   DATA FLOW CONTROL
+
+  PROC_FLOW_FSM: process( CLK, RESET )
+  begin
+    if   ( RESET = '1' ) then
+      flow_current_state <= IDLE;
+    elsif( rising_edge(CLK) ) then
+      flow_current_state <= flow_next_state;
+    end if;
+  end process PROC_FLOW_FSM;
+
+  PROC_FLOW_TRANSITIONS: process(flow_current_state, TC_TRANSMIT_DONE_IN, ps_response_ready, tc_data)
+  begin
+    flow_state <= x"0";
+
+    case flow_current_state is
+      when IDLE =>
+        flow_state <= x"1";
+        if (ps_response_ready = '1') then
+          flow_next_state <= TRANSMIT_CTRL;
+        else
+          flow_next_state <= IDLE;
+        end if;
+
+      when TRANSMIT_CTRL =>
+        flow_state <= x"2";
+        if (tc_data(8) = '1') then
+          flow_next_state <= WAIT_FOR_FC;
+        else
+          flow_next_state <= TRANSMIT_CTRL;
+        end if;
+
+      when WAIT_FOR_FC =>
+        flow_state <= x"3";
+        if (TC_TRANSMIT_DONE_IN = '1') then
+          flow_next_state <= CLEANUP;
+        else
+          flow_next_state <= WAIT_FOR_FC;
+        end if;
+
+      when CLEANUP =>
+        flow_state      <= x"4";
+        flow_next_state <= IDLE;
+
+      when others => flow_next_state <= IDLE;
+
+    end case;
+  end process PROC_FLOW_TRANSITIONS;
+
+  PROC_BUSY: process( CLK )
+  begin
+    if rising_edge(CLK) then
+      if (flow_current_state = IDLE and ps_response_ready = '1') then
+        TC_TRANSMIT_CTRL_OUT <= '1';
+      else
+        TC_TRANSMIT_CTRL_OUT <= '0';
+      end if;
+
+      if (flow_current_state = TRANSMIT_CTRL or flow_current_state = WAIT_FOR_FC) then
+        mc_busy <= '1';
+      else
+        mc_busy <= '0';
+      end if;
+    end if;
+  end process PROC_BUSY;
+
+  --***********************
+  --   LINK STATE CONTROL
+
+  PROC_LINK_FSM: process( RESET, CLK )
+  begin
+    if   ( RESET = '1' ) then
+      link_current_state <= INACTIVE;
+    elsif( rising_edge(CLK) ) then
+      link_current_state <= link_next_state;
+    end if;
+  end process PROC_LINK_FSM;
+
+  INCL_DHCP_GEN: if (INCLUDE_DHCP = '1') generate
+    incl_dhcp <= '1';
+  end generate INCL_DHCP_GEN;
+  NOINCL_DHCP_GEN: if (INCLUDE_DHCP = '0') generate
+    incl_dhcp <= '0';
+  end generate NOINCL_DHCP_GEN;
+
+  -- to be reworked. link_ok_timer is not needed anymore!
+  PROC_LINK_TRANSITIONS: process( link_current_state, dhcp_done, wait_ctr, PCS_AN_COMPLETE_IN, incl_dhcp, MAC_READY_CONF_IN, link_ok_timeout_ctr )
+  begin
+    link_state <= x"0";
+
+    case link_current_state is
+      when INACTIVE =>
+        link_state <= x"1";
+        if (PCS_AN_COMPLETE_IN = '1') then
+          link_next_state <= TIMEOUT;
+        else
+          link_next_state <= INACTIVE;
+        end if;
+
+      when TIMEOUT =>
+        link_state <= x"2";
+        if (PCS_AN_COMPLETE_IN = '0') then
+          link_next_state <= INACTIVE;
+        else
+          if (link_ok_timeout_ctr = x"ffff") then
+            link_next_state <= ENABLE_MAC;
+          else
+            link_next_state <= TIMEOUT;
+          end if;
+        end if;
+
+      when ENABLE_MAC =>
+        link_state <= x"3";
+        if (PCS_AN_COMPLETE_IN = '0') then
+          link_next_state <= INACTIVE;
+        elsif (MAC_READY_CONF_IN = '1') then
+          link_next_state <= FINALIZE;
+        else
+          link_next_state <= ENABLE_MAC;
+        end if;
+
+      when FINALIZE =>
+        link_state <= x"4";
+        if (PCS_AN_COMPLETE_IN = '0') then
+          link_next_state <= INACTIVE;
+        else
+          link_next_state <= WAIT_FOR_BOOT;
+        end if;
+
+      when WAIT_FOR_BOOT =>
+        link_state <= x"5";
+        if (PCS_AN_COMPLETE_IN = '0') then
+          link_next_state <= INACTIVE;
+        else
+          if (wait_ctr = x"0000_1000") then
+            if (incl_dhcp = '1') then
+              link_next_state <= GET_ADDRESS;
+            else
+              link_next_state <= ACTIVE;
+            end if;
+          else
+            link_next_state <= WAIT_FOR_BOOT;
+          end if;
+        end if;
+
+      when GET_ADDRESS =>
+        link_state <= x"6";
+        if (PCS_AN_COMPLETE_IN = '0') then
+          link_next_state <= INACTIVE;
+        else
+          if (dhcp_done = '1') then
+            link_next_state <= ACTIVE;
+          else
+            link_next_state <= GET_ADDRESS;
+          end if;
+        end if;
+
+      when ACTIVE =>
+        link_state <= x"7";
+        if (PCS_AN_COMPLETE_IN = '0') then
+          link_next_state <= INACTIVE;
+        else
+          link_next_state <= ACTIVE;
+        end if;
+
+      when others => 
+        link_next_state <= INACTIVE;
+
+    end case;
+  end process PROC_LINK_TRANSITIONS;
+
+  MC_DHCP_DONE_OUT <= '1' when link_current_state = ACTIVE else '0';
+
+  PROC_LINK_OK_CTR: process( CLK )
+  begin
+    if( rising_edge(CLK) ) then
+      if   ( link_current_state /= TIMEOUT ) then
+        link_ok_timeout_ctr <= (others => '0');
+      elsif( link_current_state = TIMEOUT ) then
+        link_ok_timeout_ctr <= link_ok_timeout_ctr + 1;
+      end if;
+
+      if( link_current_state = GET_ADDRESS ) then
+        dhcp_start <= '1';
+      else
+        dhcp_start <= '0';
+      end if;
+    end if;
+  end process PROC_LINK_OK_CTR;
+
+  link_ok <= '1'; -- BUG - what the fuck?
+
+  PROC_WAIT_CTR: process( CLK )
+  begin
+    if( rising_edge(CLK) ) then
+      if( link_current_state = WAIT_FOR_BOOT ) then
+        wait_ctr <= wait_ctr + 1;
+      else
+        wait_ctr <= (others => '0');
+      end if;
+    end if;
+  end process PROC_WAIT_CTR;
+
+  MC_LINK_OK_OUT <= link_ok;
+
+  -- END OF LINK STATE CONTROL
+  --*************
+
+  DEBUG_OUT <= selector_debug;
+
+end gbe_main_control_arch;
diff --git a/gbe_trb/base/gbe_protocol_prioritizer.vhd b/gbe_trb/base/gbe_protocol_prioritizer.vhd
new file mode 100644 (file)
index 0000000..612d122
--- /dev/null
@@ -0,0 +1,76 @@
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.gbe_protocols.all;
+
+--********
+-- maps the frame type and protocol code into internal value which sets the priority
+
+entity gbe_protocol_prioritizer is
+port(
+  CLK              : in  std_logic;
+  RESET            : in  std_logic;
+  FRAME_TYPE_IN    : in  std_logic_vector(15 downto 0);  -- recovered frame type  
+  PROTOCOL_CODE_IN : in  std_logic_vector(7 downto 0);  -- ip protocol
+  UDP_PROTOCOL_IN  : in  std_logic_vector(15 downto 0);
+  CODE_OUT         : out  std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0)
+);
+end gbe_protocol_prioritizer;
+
+architecture gbe_protocol_prioritizer_arch of gbe_protocol_prioritizer is
+
+begin
+
+PRIORITIZE: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    CODE_OUT <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+  
+    CODE_OUT <= (others => '0');
+        
+      --**** HERE ADD YOU PROTOCOL RECOGNITION AT WANTED PRIORITY LEVEL
+      -- priority level is the bit position in the CODE_OUT vector
+      -- less significant bit has the higher priority
+      case FRAME_TYPE_IN is
+      
+        -- IPv4 
+        when x"0800" =>
+          if   ( PROTOCOL_CODE_IN = x"11" ) then -- UDP
+            -- No. 2 = DHCP
+            if   ( UDP_PROTOCOL_IN = x"0044" ) then  -- DHCP Client
+              CODE_OUT(1) <= '1';
+            -- No. 4 = SCTRL
+            elsif( UDP_PROTOCOL_IN = x"6590" ) then -- SCTRL module
+              CODE_OUT(2) <= '1';
+            else
+              -- branch for pure IPv4
+              CODE_OUT <= (others => '0');
+            end if;
+          -- No. 3 = ICMP 
+          elsif( PROTOCOL_CODE_IN = x"01") then -- ICMP
+            CODE_OUT(4) <= '1';
+          else
+            CODE_OUT <= (others => '0');
+          end if;
+        
+        -- No. 1 = ARP
+        when x"0806" =>
+          CODE_OUT(0) <= '1';
+        
+        -- last slot is reserved for Trash
+        when others =>
+          CODE_OUT <= (others => '0');
+      
+      end case;
+      
+  end if;
+
+end process PRIORITIZE;
+
+end gbe_protocol_prioritizer_arch;
diff --git a/gbe_trb/base/gbe_protocol_selector.vhd b/gbe_trb/base/gbe_protocol_selector.vhd
new file mode 100644 (file)
index 0000000..7e02fa4
--- /dev/null
@@ -0,0 +1,514 @@
+library ieee;
+  use ieee.std_logic_1164.all;
+  use ieee.numeric_std.all;
+--LIBRARY IEEE;
+--USE IEEE.std_logic_1164.ALL;
+--USE IEEE.numeric_std.ALL;
+--USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+  use work.trb_net_std.all;
+  use work.gbe_protocols.all;
+
+entity gbe_protocol_selector is
+  generic(
+    INCLUDE_SLOWCTRL     : std_logic := '0';
+    INCLUDE_DHCP         : std_logic := '0';
+    INCLUDE_ARP          : std_logic := '0';
+    INCLUDE_PING         : std_logic := '0';
+    INCLUDE_FWD          : std_logic := '0';
+    SLOWCTRL_BUFFER_SIZE : integer range 1 to 4
+  );
+  port(
+    CLK                           : in  std_logic; -- system clock
+    RESET                         : in  std_logic;
+    -- signals to/from main controller
+    PS_DATA_IN                    : in  std_logic_vector(8 downto 0);
+    PS_WR_EN_IN                   : in  std_logic;
+    PS_PROTO_SELECT_IN            : in  std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+    PS_BUSY_OUT                   : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+    PS_FRAME_SIZE_IN              : in  std_logic_vector(15 downto 0);
+    PS_RESPONSE_READY_OUT         : out std_logic;
+    PS_SRC_MAC_ADDRESS_IN         : in  std_logic_vector(47 downto 0);
+    PS_DEST_MAC_ADDRESS_IN        : in  std_logic_vector(47 downto 0);
+    PS_SRC_IP_ADDRESS_IN          : in  std_logic_vector(31 downto 0);
+    PS_DEST_IP_ADDRESS_IN         : in  std_logic_vector(31 downto 0);
+    PS_SRC_UDP_PORT_IN            : in  std_logic_vector(15 downto 0);
+    PS_DEST_UDP_PORT_IN           : in  std_logic_vector(15 downto 0);
+    -- signals to/from transmit controller with constructed response
+    TC_DATA_OUT                   : out std_logic_vector(8 downto 0);
+    TC_RD_EN_IN                   : in  std_logic;
+    TC_FRAME_SIZE_OUT             : out std_logic_vector(15 downto 0);
+    TC_FRAME_TYPE_OUT             : out std_logic_vector(15 downto 0);
+    TC_IP_PROTOCOL_OUT            : out std_logic_vector(7 downto 0);
+    TC_IDENT_OUT                  : out std_logic_vector(15 downto 0);
+    TC_DEST_MAC_OUT               : out std_logic_vector(47 downto 0);
+    TC_DEST_IP_OUT                : out std_logic_vector(31 downto 0);
+    TC_DEST_UDP_OUT               : out std_logic_vector(15 downto 0);
+    TC_SRC_MAC_OUT                : out std_logic_vector(47 downto 0);
+    TC_SRC_IP_OUT                 : out std_logic_vector(31 downto 0);
+    TC_SRC_UDP_OUT                : out std_logic_vector(15 downto 0);
+    MC_BUSY_IN                    : in  std_logic;
+    -- misc signals for response constructors
+    MY_MAC_IN                     : in  std_logic_vector(47 downto 0);
+    MY_IP_OUT                     : out std_logic_vector(31 downto 0);
+    DHCP_START_IN                 : in  std_logic;
+    DHCP_DONE_OUT                 : out std_logic;
+    GSC_CLK_IN                    : in  std_logic;
+    GSC_INIT_DATAREADY_OUT        : out std_logic;
+    GSC_INIT_DATA_OUT             : out std_logic_vector(15 downto 0);
+    GSC_INIT_PACKET_NUM_OUT       : out std_logic_vector(2 downto 0);
+    GSC_INIT_READ_IN              : in  std_logic;
+    GSC_REPLY_DATAREADY_IN        : in  std_logic;
+    GSC_REPLY_DATA_IN             : in  std_logic_vector(15 downto 0);
+    GSC_REPLY_PACKET_NUM_IN       : in  std_logic_vector(2 downto 0);
+    GSC_REPLY_READ_OUT            : out std_logic;
+    GSC_BUSY_IN                   : in  std_logic;
+    CFG_MAX_REPLY_SIZE_IN         : in  std_logic_vector(31 downto 0);    -- USED IN SCTRL
+    MAKE_RESET_OUT                : out std_logic;
+    MY_TRBNET_ADDRESS_IN          : in  std_logic_vector(15 downto 0);
+    ISSUE_REBOOT_OUT              : out std_logic;
+    -- Forwarder
+    FWD_DST_MAC_IN                : in  std_logic_vector(47 downto 0);
+    FWD_DST_IP_IN                 : in  std_logic_vector(31 downto 0);
+    FWD_DST_UDP_IN                : in  std_logic_vector(15 downto 0);
+    FWD_DATA_IN                   : in  std_logic_vector(7 downto 0);
+    FWD_DATA_VALID_IN             : in  std_logic;
+    FWD_SOP_IN                    : in  std_logic;
+    FWD_EOP_IN                    : in  std_logic;
+    FWD_READY_OUT                 : out std_logic;
+    FWD_FULL_OUT                  : out std_logic;
+    -- input for statistics from outside       
+    MONITOR_SELECT_REC_OUT        : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    MONITOR_SELECT_REC_BYTES_OUT  : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    MONITOR_SELECT_SENT_BYTES_OUT : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    MONITOR_SELECT_SENT_OUT       : out std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    MONITOR_SELECT_GEN_DBG_OUT    : out std_logic_vector(2 * c_MAX_PROTOCOLS * 32 - 1 downto 0);
+    SCTRL_HIST_OUT                : out hist_array;
+    DEBUG_OUT                     : out std_logic_vector(63 downto 0)
+  );
+end gbe_protocol_selector;
+
+architecture gbe_protocol_selector_arch of gbe_protocol_selector is
+
+  attribute syn_encoding : string;
+
+  signal rd_en             : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+  signal resp_ready        : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+  signal tc_wr             : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+  signal tc_data           : std_logic_vector(c_MAX_PROTOCOLS * 9 - 1 downto 0);
+  signal tc_size           : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+  signal tc_type           : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+  signal busy              : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+  signal selected          : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+  signal tc_mac            : std_logic_vector(c_MAX_PROTOCOLS * 48 - 1 downto 0);
+  signal tc_ip             : std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+  signal tc_udp            : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+  signal tc_src_mac        : std_logic_vector(c_MAX_PROTOCOLS * 48 - 1 downto 0);
+  signal tc_src_ip         : std_logic_vector(c_MAX_PROTOCOLS * 32 - 1 downto 0);
+  signal tc_src_udp        : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+  signal tc_ip_proto       : std_logic_vector(c_MAX_PROTOCOLS * 8 - 1 downto 0);
+
+  type select_states is (IDLE, LOOP_OVER, SELECT_ONE, PROCESS_REQUEST, CLEANUP);
+  signal select_current_state, select_next_state : select_states;
+  attribute syn_encoding of select_current_state : signal is "onehot";
+
+  signal state : std_logic_vector(3 downto 0);
+  signal index : integer range 0 to c_MAX_PROTOCOLS - 1;
+
+  signal mult : std_logic;
+
+  signal tc_ident : std_logic_vector(c_MAX_PROTOCOLS * 16 - 1 downto 0);
+  signal zeros    : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+
+  attribute syn_preserve : boolean;
+  attribute syn_keep : boolean;
+  attribute syn_keep of state, mult : signal is true;
+  attribute syn_preserve of state, mult : signal is true;
+
+  signal my_ip        : std_logic_vector(31 downto 0);
+  signal select_state : std_logic_vector(3 downto 0);
+
+begin
+  zeros <= (others => '0');
+  MY_IP_OUT <= my_ip;
+
+  ARP_GEN: if( INCLUDE_ARP = '1' ) generate
+    -- protocol Nr. 1 ARP
+    THE_ARP: entity work.gbe_response_constructor_ARP
+      port map(
+        CLK                    => CLK,
+        RESET                  => RESET,
+        -- INTERFACE
+        MY_MAC_IN              => MY_MAC_IN,
+        MY_IP_IN               => my_ip,
+        PS_DATA_IN             => PS_DATA_IN,
+        PS_WR_EN_IN            => PS_WR_EN_IN,
+        PS_ACTIVATE_IN         => PS_PROTO_SELECT_IN(0),
+        PS_RESPONSE_READY_OUT  => resp_ready(0),
+        PS_BUSY_OUT            => busy(0),
+        PS_SELECTED_IN         => selected(0),
+        PS_SRC_MAC_ADDRESS_IN  => PS_SRC_MAC_ADDRESS_IN,
+        PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN,
+        PS_SRC_IP_ADDRESS_IN   => PS_SRC_IP_ADDRESS_IN,
+        PS_DEST_IP_ADDRESS_IN  => PS_DEST_IP_ADDRESS_IN,
+        PS_SRC_UDP_PORT_IN     => PS_SRC_UDP_PORT_IN,
+        PS_DEST_UDP_PORT_IN    => PS_DEST_UDP_PORT_IN,
+        TC_RD_EN_IN            => TC_RD_EN_IN,
+        TC_DATA_OUT            => tc_data(1 * 9 - 1 downto 0 * 9),
+        TC_FRAME_SIZE_OUT      => tc_size(1 * 16 - 1 downto 0 * 16),
+        TC_FRAME_TYPE_OUT      => tc_type(1 * 16 - 1 downto 0 * 16),
+        TC_IP_PROTOCOL_OUT     => tc_ip_proto(1 * 8 - 1 downto 0 * 8),
+        TC_IDENT_OUT           => tc_ident(1 * 16 - 1 downto 0 * 16),
+        TC_DEST_MAC_OUT        => tc_mac(1 * 48 - 1 downto 0 * 48),
+        TC_DEST_IP_OUT         => tc_ip(1 * 32 - 1 downto 0 * 32),
+        TC_DEST_UDP_OUT        => tc_udp(1 * 16 - 1 downto 0 * 16),
+        TC_SRC_MAC_OUT         => tc_src_mac(1 * 48 - 1 downto 0 * 48),
+        TC_SRC_IP_OUT          => tc_src_ip(1 * 32 - 1 downto 0 * 32),
+        TC_SRC_UDP_OUT         => tc_src_udp(1 * 16 - 1 downto 0 * 16),
+        DEBUG_OUT              => MONITOR_SELECT_GEN_DBG_OUT(1 * 64 - 1 downto 0 * 64)
+      -- END OF INTERFACE 
+      );
+  end generate ARP_GEN;
+
+  NO_ARP_GEN: if( INCLUDE_ARP = '0' ) generate
+    resp_ready(0) <= '0';
+    busy(0)       <= '0';
+  end generate NO_ARP_GEN;
+
+  DHCP_GEN: if( INCLUDE_DHCP = '1' ) generate
+    -- protocol No. 2 DHCP
+    THE_DHCP: entity work.gbe_response_constructor_DHCP
+      port map(
+        CLK                    => CLK,
+        RESET                  => RESET,
+        -- INTERFACE   
+        MY_MAC_IN              => MY_MAC_IN,
+        MY_IP_IN               => my_ip,
+        PS_DATA_IN             => PS_DATA_IN,
+        PS_WR_EN_IN            => PS_WR_EN_IN,
+        PS_ACTIVATE_IN         => PS_PROTO_SELECT_IN(1),
+        PS_RESPONSE_READY_OUT  => resp_ready(1),
+        PS_BUSY_OUT            => busy(1),
+        PS_SELECTED_IN         => selected(1),
+        PS_SRC_MAC_ADDRESS_IN  => PS_SRC_MAC_ADDRESS_IN,
+        PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN,
+        PS_SRC_IP_ADDRESS_IN   => PS_SRC_IP_ADDRESS_IN,
+        PS_DEST_IP_ADDRESS_IN  => PS_DEST_IP_ADDRESS_IN,
+        PS_SRC_UDP_PORT_IN     => PS_SRC_UDP_PORT_IN,
+        PS_DEST_UDP_PORT_IN    => PS_DEST_UDP_PORT_IN,
+        TC_RD_EN_IN            => TC_RD_EN_IN,
+        TC_DATA_OUT            => tc_data(2 * 9 - 1 downto 1 * 9),
+        TC_FRAME_SIZE_OUT      => tc_size(2 * 16 - 1 downto 1 * 16),
+        TC_FRAME_TYPE_OUT      => tc_type(2 * 16 - 1 downto 1 * 16),
+        TC_IP_PROTOCOL_OUT     => tc_ip_proto(2 * 8 - 1 downto 1 * 8),
+        TC_IDENT_OUT           => tc_ident(2 * 16 - 1 downto 1 * 16),
+        TC_DEST_MAC_OUT        => tc_mac(2 * 48 - 1 downto 1 * 48),
+        TC_DEST_IP_OUT         => tc_ip(2 * 32 - 1 downto 1 * 32),
+        TC_DEST_UDP_OUT        => tc_udp(2 * 16 - 1 downto 1 * 16),
+        TC_SRC_MAC_OUT         => tc_src_mac(2 * 48 - 1 downto 1 * 48),
+        TC_SRC_IP_OUT          => tc_src_ip(2 * 32 - 1 downto 1 * 32),
+        TC_SRC_UDP_OUT         => tc_src_udp(2 * 16 - 1 downto 1 * 16),
+        -- END OF INTERFACE
+        MY_IP_OUT              => my_ip,
+        DHCP_START_IN          => DHCP_START_IN,
+        DHCP_DONE_OUT          => DHCP_DONE_OUT,
+        DEBUG_OUT              => MONITOR_SELECT_GEN_DBG_OUT(2 * 64 - 1 downto 1 * 64)
+      );
+  end generate DHCP_GEN;
+
+  NO_DHCP_GEN: if( INCLUDE_DHCP = '0' ) generate
+    resp_ready(1) <= '0';
+    busy(1)       <= '0';
+  end generate NO_DHCP_GEN;
+
+  PING_GEN: if( INCLUDE_PING = '1' ) generate
+    --protocol No. 3 Ping
+    THE_PING: entity work.gbe_response_constructor_Ping
+      port map(
+        CLK                    => CLK,
+        RESET                  => RESET,
+        ---- INTERFACE
+        MY_MAC_IN              => MY_MAC_IN,
+        MY_IP_IN               => my_ip,
+        PS_DATA_IN             => PS_DATA_IN,
+        PS_WR_EN_IN            => PS_WR_EN_IN,
+        PS_ACTIVATE_IN         => PS_PROTO_SELECT_IN(4),
+        PS_RESPONSE_READY_OUT  => resp_ready(4),
+        PS_BUSY_OUT            => busy(4),
+        PS_SELECTED_IN         => selected(4),
+        PS_SRC_MAC_ADDRESS_IN  => PS_SRC_MAC_ADDRESS_IN,
+        PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN,
+        PS_SRC_IP_ADDRESS_IN   => PS_SRC_IP_ADDRESS_IN,
+        PS_DEST_IP_ADDRESS_IN  => PS_DEST_IP_ADDRESS_IN,
+        PS_SRC_UDP_PORT_IN     => PS_SRC_UDP_PORT_IN,
+        PS_DEST_UDP_PORT_IN    => PS_DEST_UDP_PORT_IN,
+        TC_RD_EN_IN            => TC_RD_EN_IN,
+        TC_DATA_OUT            => tc_data(5 * 9 - 1 downto 4 * 9),
+        TC_FRAME_SIZE_OUT      => tc_size(5 * 16 - 1 downto 4 * 16),
+        TC_FRAME_TYPE_OUT      => tc_type(5 * 16 - 1 downto 4 * 16),
+        TC_IP_PROTOCOL_OUT     => tc_ip_proto(5 * 8 - 1 downto 4 * 8),
+        TC_IDENT_OUT           => tc_ident(5 * 16 - 1 downto 4 * 16),
+        TC_DEST_MAC_OUT        => tc_mac(5 * 48 - 1 downto 4 * 48),
+        TC_DEST_IP_OUT         => tc_ip(5 * 32 - 1 downto 4 * 32),
+        TC_DEST_UDP_OUT        => tc_udp(5 * 16 - 1 downto 4 * 16),
+        TC_SRC_MAC_OUT         => tc_src_mac(5 * 48 - 1 downto 4 * 48),
+        TC_SRC_IP_OUT          => tc_src_ip(5 * 32 - 1 downto 4 * 32),
+        TC_SRC_UDP_OUT         => tc_src_udp(5 * 16 - 1 downto 4 * 16),
+        DEBUG_OUT              => MONITOR_SELECT_GEN_DBG_OUT(5 * 64 - 1 downto 4 * 64)
+      -- END OF INTERFACE
+      );
+  end generate PING_GEN;
+
+  NO_PING_GEN: if( INCLUDE_PING = '0' ) generate
+    resp_ready(4) <= '0';
+    busy(4)       <= '0';
+  end generate NO_PING_GEN;
+
+  SCTRL_GEN: if( INCLUDE_SLOWCTRL = '1' ) generate
+    THE_SCTRL: entity work.gbe_response_constructor_SCTRL
+      generic map( 
+        SLOWCTRL_BUFFER_SIZE => SLOWCTRL_BUFFER_SIZE
+      )
+      port map(
+        CLK                           => CLK,
+        RESET                         => RESET,
+        -- INTERFACE   
+        MY_MAC_IN                     => MY_MAC_IN,
+        MY_IP_IN                      => my_ip,
+        PS_DATA_IN                    => PS_DATA_IN,
+        PS_WR_EN_IN                   => PS_WR_EN_IN,
+        PS_ACTIVATE_IN                => PS_PROTO_SELECT_IN(2),
+        PS_RESPONSE_READY_OUT         => resp_ready(2),
+        PS_BUSY_OUT                   => busy(2),
+        PS_SELECTED_IN                => selected(2),
+        PS_SRC_MAC_ADDRESS_IN         => PS_SRC_MAC_ADDRESS_IN,
+        PS_DEST_MAC_ADDRESS_IN        => PS_DEST_MAC_ADDRESS_IN,
+        PS_SRC_IP_ADDRESS_IN          => PS_SRC_IP_ADDRESS_IN,
+        PS_DEST_IP_ADDRESS_IN         => PS_DEST_IP_ADDRESS_IN,
+        PS_SRC_UDP_PORT_IN            => PS_SRC_UDP_PORT_IN,
+        PS_DEST_UDP_PORT_IN           => PS_DEST_UDP_PORT_IN,
+        TC_RD_EN_IN                   => TC_RD_EN_IN,
+        TC_DATA_OUT                   => tc_data(3 * 9 - 1 downto 2 * 9),
+        TC_FRAME_SIZE_OUT             => tc_size(3 * 16 - 1 downto 2 * 16),
+        TC_FRAME_TYPE_OUT             => tc_type(3 * 16 - 1 downto 2 * 16),
+        TC_IP_PROTOCOL_OUT            => tc_ip_proto(3 * 8 - 1 downto 2 * 8),
+        TC_IDENT_OUT                  => tc_ident(3 * 16 - 1 downto 2 * 16),
+        TC_DEST_MAC_OUT               => tc_mac(3 * 48 - 1 downto 2 * 48),
+        TC_DEST_IP_OUT                => tc_ip(3 * 32 - 1 downto 2 * 32),
+        TC_DEST_UDP_OUT               => tc_udp(3 * 16 - 1 downto 2 * 16),
+        TC_SRC_MAC_OUT                => tc_src_mac(3 * 48 - 1 downto 2 * 48),
+        TC_SRC_IP_OUT                 => tc_src_ip(3 * 32 - 1 downto 2 * 32),
+        TC_SRC_UDP_OUT                => tc_src_udp(3 * 16 - 1 downto 2 * 16),
+        DEBUG_OUT                     => MONITOR_SELECT_GEN_DBG_OUT(3 * 64 - 1 downto 2 * 64),
+        -- END OF INTERFACE
+        GSC_CLK_IN                    => GSC_CLK_IN,
+        GSC_INIT_DATAREADY_OUT        => GSC_INIT_DATAREADY_OUT,
+        GSC_INIT_DATA_OUT             => GSC_INIT_DATA_OUT,
+        GSC_INIT_PACKET_NUM_OUT       => GSC_INIT_PACKET_NUM_OUT,
+        GSC_INIT_READ_IN              => GSC_INIT_READ_IN,
+        GSC_REPLY_DATAREADY_IN        => GSC_REPLY_DATAREADY_IN,
+        GSC_REPLY_DATA_IN             => GSC_REPLY_DATA_IN,
+        GSC_REPLY_PACKET_NUM_IN       => GSC_REPLY_PACKET_NUM_IN,
+        GSC_REPLY_READ_OUT            => GSC_REPLY_READ_OUT,
+        GSC_BUSY_IN                   => GSC_BUSY_IN,
+        CFG_MAX_REPLY_SIZE_IN         => CFG_MAX_REPLY_SIZE_IN,
+        MAKE_RESET_OUT                => MAKE_RESET_OUT,
+        MONITOR_SELECT_REC_OUT        => MONITOR_SELECT_REC_OUT(3 * 32 - 1 downto 2 * 32),
+        MONITOR_SELECT_REC_BYTES_OUT  => MONITOR_SELECT_REC_BYTES_OUT(3 * 32 - 1 downto 2 * 32),
+        MONITOR_SELECT_SENT_BYTES_OUT => MONITOR_SELECT_SENT_BYTES_OUT(3 * 32 - 1 downto 2 * 32),
+        MONITOR_SELECT_SENT_OUT       => MONITOR_SELECT_SENT_OUT(3 * 32 - 1 downto 2 * 32),
+        DATA_HIST_OUT                 => SCTRL_HIST_OUT
+      );
+  end generate SCTRL_GEN;
+
+  NO_SCTRL_GEN: if( INCLUDE_SLOWCTRL = '0' ) generate
+    resp_ready(2)  <= '0';
+    busy(2)        <= '0';
+    MAKE_RESET_OUT <= '0';
+
+    GSC_INIT_DATAREADY_OUT  <= '0';
+    GSC_INIT_DATA_OUT       <= (others => '0');
+    GSC_INIT_PACKET_NUM_OUT <= (others => '0');
+    GSC_REPLY_READ_OUT      <= '1';
+  end generate NO_SCTRL_GEN;
+
+  ---------------------------------------------------------------------------------------
+  -- once upon a time, this was "READOUT"
+  resp_ready(3)            <= '0';
+  busy(3)                  <= '0';
+  ---------------------------------------------------------------------------------------
+
+  FWD_GEN: if( INCLUDE_FWD = '1' ) generate
+
+    THE_FORWARD: entity work.gbe_response_constructor_Forward
+      port map(
+        CLK                    => CLK,
+        RESET                  => RESET,
+        ---- INTERFACE
+        MY_MAC_IN              => MY_MAC_IN,
+        MY_IP_IN               => my_ip,
+        PS_DATA_IN             => PS_DATA_IN,
+        PS_WR_EN_IN            => PS_WR_EN_IN,
+        PS_ACTIVATE_IN         => PS_PROTO_SELECT_IN(5),
+        PS_RESPONSE_READY_OUT  => resp_ready(5),
+        PS_BUSY_OUT            => busy(5),
+        PS_SELECTED_IN         => selected(5),
+        PS_SRC_MAC_ADDRESS_IN  => PS_SRC_MAC_ADDRESS_IN,
+        PS_DEST_MAC_ADDRESS_IN => PS_DEST_MAC_ADDRESS_IN,
+        PS_SRC_IP_ADDRESS_IN   => PS_SRC_IP_ADDRESS_IN,
+        PS_DEST_IP_ADDRESS_IN  => PS_DEST_IP_ADDRESS_IN,
+        PS_SRC_UDP_PORT_IN     => PS_SRC_UDP_PORT_IN,
+        PS_DEST_UDP_PORT_IN    => PS_DEST_UDP_PORT_IN,
+        TC_RD_EN_IN            => TC_RD_EN_IN,
+        TC_DATA_OUT            => tc_data(6 * 9 - 1 downto 5 * 9),
+        TC_FRAME_SIZE_OUT      => tc_size(6 * 16 - 1 downto 5 * 16),
+        TC_FRAME_TYPE_OUT      => tc_type(6 * 16 - 1 downto 5 * 16),
+        TC_IP_PROTOCOL_OUT     => tc_ip_proto(6 * 8 - 1 downto 5 * 8),
+        TC_IDENT_OUT           => tc_ident(6 * 16 - 1 downto 5 * 16),
+        TC_DEST_MAC_OUT        => tc_mac(6 * 48 - 1 downto 5 * 48),
+        TC_DEST_IP_OUT         => tc_ip(6 * 32 - 1 downto 5 * 32),
+        TC_DEST_UDP_OUT        => tc_udp(6 * 16 - 1 downto 5 * 16),
+        TC_SRC_MAC_OUT         => tc_src_mac(6 * 48 - 1 downto 5 * 48),
+        TC_SRC_IP_OUT          => tc_src_ip(6 * 32 - 1 downto 5 * 32),
+        TC_SRC_UDP_OUT         => tc_src_udp(6 * 16 - 1 downto 5 * 16),
+        RECEIVED_FRAMES_OUT    => open,
+        SENT_FRAMES_OUT        => open,
+        FWD_DST_MAC_IN         => FWD_DST_MAC_IN,
+        FWD_DST_IP_IN          => FWD_DST_IP_IN,
+        FWD_DST_UDP_IN         => FWD_DST_UDP_IN,
+        FWD_DATA_IN            => FWD_DATA_IN,
+        FWD_DATA_VALID_IN      => FWD_DATA_VALID_IN,
+        FWD_SOP_IN             => FWD_SOP_IN,
+        FWD_EOP_IN             => FWD_EOP_IN,
+        FWD_READY_OUT          => FWD_READY_OUT,
+        FWD_FULL_OUT           => FWD_FULL_OUT,  
+        DEBUG_OUT              => DEBUG_OUT(31 downto 0) --open
+      -- END OF INTERFACE
+      );
+
+  end generate FWD_GEN;
+
+  DEBUG_OUT(63 downto 32) <= (others => '0');
+  
+  NO_FWD_GEN: if( INCLUDE_FWD = '0' ) generate
+    resp_ready(5) <= '0';
+    busy(5) <= '0';
+    DEBUG_OUT(31 downto 0) <= (others => '0');
+  end generate NO_FWD_GEN;
+
+  PS_BUSY_OUT <= busy;
+
+  PROC_SELECT_MACHINE: process( CLK, RESET )
+  begin
+    if   ( RESET = '1' ) then
+      select_current_state <= IDLE;
+    elsif( rising_edge(CLK) ) then
+      select_current_state <= select_next_state;
+    end if;
+  end process PROC_SELECT_MACHINE;
+
+  PROC_SELECT_TRANSITIONS: process(select_current_state, MC_BUSY_IN, resp_ready, index, zeros, busy)
+  begin
+    select_state <= x"0";
+
+    case (select_current_state) is
+      when IDLE =>
+        select_state <= x"1";
+        if (MC_BUSY_IN = '0') then
+          select_next_state <= LOOP_OVER;
+        else
+          select_next_state <= IDLE;
+        end if;
+
+      when LOOP_OVER =>
+        select_state <= x"2";
+        if (resp_ready /= zeros) then
+          if (resp_ready(index) = '1') then
+            select_next_state <= SELECT_ONE;
+          elsif (index = c_MAX_PROTOCOLS) then
+            select_next_state <= CLEANUP;
+          else
+            select_next_state <= LOOP_OVER;
+          end if;
+        else
+          select_next_state <= CLEANUP;
+        end if;
+
+      when SELECT_ONE =>
+        select_state <= x"3";
+        if (MC_BUSY_IN = '1') then
+          select_next_state <= PROCESS_REQUEST;
+        else
+          select_next_state <= SELECT_ONE;
+        end if;
+
+      when PROCESS_REQUEST =>
+        select_state <= x"4";
+        if (busy(index) = '0') then
+          select_next_state <= CLEANUP;
+        else
+          select_next_state <= PROCESS_REQUEST;
+        end if;
+
+      when CLEANUP =>
+        select_state      <= x"5";
+        select_next_state <= IDLE;
+
+      when others => select_next_state <= IDLE;
+
+    end case;
+  end process PROC_SELECT_TRANSITIONS;
+
+  PROC_INDEX: process( CLK )
+  begin
+    if( rising_edge(CLK) ) then
+      if   ( select_current_state = IDLE ) then
+        index <= 0;
+      elsif( select_current_state = LOOP_OVER and resp_ready(index) = '0' ) then
+        index <= index + 1;
+      end if;
+    end if;
+  end process PROC_INDEX;
+
+  PROC_SELECTOR: process( CLK )
+  begin
+    if( rising_edge(CLK) ) then
+      if( select_current_state = SELECT_ONE or select_current_state = PROCESS_REQUEST ) then
+        TC_DATA_OUT        <= tc_data((index + 1) * 9 - 1 downto index * 9);
+        TC_FRAME_SIZE_OUT  <= tc_size((index + 1) * 16 - 1 downto index * 16);
+        TC_FRAME_TYPE_OUT  <= tc_type((index + 1) * 16 - 1 downto index * 16);
+        TC_DEST_MAC_OUT    <= tc_mac((index + 1) * 48 - 1 downto index * 48);
+        TC_DEST_IP_OUT     <= tc_ip((index + 1) * 32 - 1 downto index * 32);
+        TC_DEST_UDP_OUT    <= tc_udp((index + 1) * 16 - 1 downto index * 16);
+        TC_SRC_MAC_OUT     <= tc_src_mac((index + 1) * 48 - 1 downto index * 48);
+        TC_SRC_IP_OUT      <= tc_src_ip((index + 1) * 32 - 1 downto index * 32);
+        TC_SRC_UDP_OUT     <= tc_src_udp((index + 1) * 16 - 1 downto index * 16);
+        TC_IP_PROTOCOL_OUT <= tc_ip_proto((index + 1) * 8 - 1 downto index * 8);
+        TC_IDENT_OUT       <= tc_ident((index + 1) * 16 - 1 downto index * 16);
+        if( select_current_state = SELECT_ONE ) then
+          PS_RESPONSE_READY_OUT <= '1';
+          selected(index)       <= '0';
+        else
+          PS_RESPONSE_READY_OUT <= '0';
+          selected(index)       <= '1';
+        end if;
+      else
+        TC_DATA_OUT           <= (others => '0');
+        TC_FRAME_SIZE_OUT     <= (others => '0');
+        TC_FRAME_TYPE_OUT     <= (others => '0');
+        TC_DEST_MAC_OUT       <= (others => '0');
+        TC_DEST_IP_OUT        <= (others => '0');
+        TC_DEST_UDP_OUT       <= (others => '0');
+        TC_SRC_MAC_OUT        <= (others => '0');
+        TC_SRC_IP_OUT         <= (others => '0');
+        TC_SRC_UDP_OUT        <= (others => '0');
+        TC_IP_PROTOCOL_OUT    <= (others => '0');
+        TC_IDENT_OUT          <= (others => '0');
+        PS_RESPONSE_READY_OUT <= '0';
+        selected              <= (others => '0');
+      end if;
+    end if;
+  end process PROC_SELECTOR;
+
+end gbe_protocol_selector_arch;
diff --git a/gbe_trb/base/gbe_receive_control.vhd b/gbe_trb/base/gbe_receive_control.vhd
new file mode 100644 (file)
index 0000000..4620fbf
--- /dev/null
@@ -0,0 +1,204 @@
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.gbe_protocols.all;
+
+entity gbe_receive_control is
+port (
+  CLK                      : in  std_logic;  -- system clock
+  RESET                    : in  std_logic;
+-- signals to/from frame_receiver
+  RC_DATA_IN               : in  std_logic_vector(8 downto 0);
+  FR_RD_EN_OUT             : out std_logic;
+  FR_FRAME_VALID_IN        : in  std_logic;
+  FR_GET_FRAME_OUT         : out std_logic;
+  FR_FRAME_SIZE_IN         : in  std_logic_vector(15 downto 0);
+  FR_FRAME_PROTO_IN        : in  std_logic_vector(15 downto 0);
+  FR_IP_PROTOCOL_IN        : in  std_logic_vector(7 downto 0);
+  
+  FR_SRC_MAC_ADDRESS_IN    : in  std_logic_vector(47 downto 0);
+  FR_DEST_MAC_ADDRESS_IN   : in  std_logic_vector(47 downto 0);
+  FR_SRC_IP_ADDRESS_IN     : in  std_logic_vector(31 downto 0);
+  FR_DEST_IP_ADDRESS_IN    : in  std_logic_vector(31 downto 0);
+  FR_SRC_UDP_PORT_IN       : in  std_logic_vector(15 downto 0);
+  FR_DEST_UDP_PORT_IN      : in  std_logic_vector(15 downto 0);
+  -- signals to/from main controller
+  RC_RD_EN_IN              : in  std_logic;
+  RC_Q_OUT                 : out std_logic_vector(8 downto 0);
+  RC_FRAME_WAITING_OUT     : out std_logic;
+  RC_LOADING_DONE_IN       : in  std_logic;
+  RC_FRAME_SIZE_OUT        : out std_logic_vector(15 downto 0);
+  RC_FRAME_PROTO_OUT       : out std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+  RC_SRC_MAC_ADDRESS_OUT   : out std_logic_vector(47 downto 0);
+  RC_DEST_MAC_ADDRESS_OUT  : out std_logic_vector(47 downto 0);
+  RC_SRC_IP_ADDRESS_OUT    : out std_logic_vector(31 downto 0);
+  RC_DEST_IP_ADDRESS_OUT   : out std_logic_vector(31 downto 0);
+  RC_SRC_UDP_PORT_OUT      : out std_logic_vector(15 downto 0);
+  RC_DEST_UDP_PORT_OUT     : out std_logic_vector(15 downto 0);
+  -- statistics
+  FRAMES_RECEIVED_OUT      : out std_logic_vector(31 downto 0);
+  BYTES_RECEIVED_OUT       : out std_logic_vector(31 downto 0);
+  --
+  DEBUG_OUT                : out std_logic_vector(63 downto 0)
+);
+end gbe_receive_control;
+
+architecture gbe_receive_control_arch of gbe_receive_control is
+
+attribute syn_encoding : string;
+
+type load_states is (IDLE, PREPARE, WAIT_ONE, READY);
+signal load_current_state, load_next_state : load_states;
+attribute syn_encoding of load_current_state : signal is "onehot";
+
+signal frames_received_ctr       : unsigned(31 downto 0);
+signal frames_readout_ctr        : unsigned(31 downto 0);
+signal bytes_rec_ctr             : unsigned(31 downto 0);
+
+signal state                     : std_logic_vector(3 downto 0);
+signal proto_code                : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+signal reset_prioritizer         : std_logic;
+signal frame_waiting             : std_logic;
+
+-- debug only
+signal saved_proto               : std_logic_vector(c_MAX_PROTOCOLS - 1 downto 0);
+
+begin
+
+FR_RD_EN_OUT            <= RC_RD_EN_IN;
+RC_Q_OUT                <= RC_DATA_IN;
+RC_FRAME_SIZE_OUT       <= FR_FRAME_SIZE_IN;
+RC_SRC_MAC_ADDRESS_OUT  <= FR_SRC_MAC_ADDRESS_IN;
+RC_DEST_MAC_ADDRESS_OUT <= FR_DEST_MAC_ADDRESS_IN;
+RC_SRC_IP_ADDRESS_OUT   <= FR_SRC_IP_ADDRESS_IN;
+RC_DEST_IP_ADDRESS_OUT  <= FR_DEST_IP_ADDRESS_IN;
+RC_SRC_UDP_PORT_OUT     <= FR_SRC_UDP_PORT_IN;
+RC_DEST_UDP_PORT_OUT    <= FR_DEST_UDP_PORT_IN;
+
+protocol_prioritizer: entity gbe_protocol_prioritizer
+port map(
+  CLK              => CLK,
+  RESET            => reset_prioritizer,
+  --
+  FRAME_TYPE_IN    => FR_FRAME_PROTO_IN,
+  PROTOCOL_CODE_IN => FR_IP_PROTOCOL_IN,
+  UDP_PROTOCOL_IN  => FR_DEST_UDP_PORT_IN,
+  --
+  CODE_OUT         => proto_code
+);
+
+reset_prioritizer <= '1' when load_current_state = IDLE else '0';
+
+RC_FRAME_PROTO_OUT <= proto_code;  -- no more ones as the incorrect value, last slot for Trash
+
+LOAD_MACHINE_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    load_current_state <= IDLE;
+  elsif( rising_edge(CLK) ) then
+    load_current_state <= load_next_state;
+  end if;
+end process LOAD_MACHINE_PROC;
+
+LOAD_MACHINE: process( load_current_state, frames_readout_ctr, frames_received_ctr, RC_LOADING_DONE_IN )
+begin
+  case load_current_state is
+
+    when IDLE =>
+      state <= x"1";
+      if( frames_readout_ctr /= frames_received_ctr ) then -- frame is still waiting in frame_receiver
+        load_next_state <= PREPARE;
+      else
+        load_next_state <= IDLE;
+      end if;
+
+    when PREPARE =>  -- prepare frame size
+      state <= x"2";
+      load_next_state <= WAIT_ONE;
+      
+    when WAIT_ONE =>
+       load_next_state <= READY;
+
+    when READY => -- wait for reading out the whole frame
+      state <= x"3";
+      if( RC_LOADING_DONE_IN = '1' ) then
+        load_next_state <= IDLE;
+      else
+        load_next_state <= READY;
+      end if;
+
+  end case;
+end process LOAD_MACHINE;
+
+process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( load_current_state = PREPARE ) then
+      FR_GET_FRAME_OUT <= '1';
+    else
+      FR_GET_FRAME_OUT <= '0';
+    end if;
+
+    if( (load_current_state = READY) and (RC_LOADING_DONE_IN = '0') ) then
+      RC_FRAME_WAITING_OUT <= '1';
+    else
+      RC_FRAME_WAITING_OUT <= '0';
+    end if;
+  end if;
+end process;
+
+FRAMES_REC_CTR_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    frames_received_ctr <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if( FR_FRAME_VALID_IN = '1' ) then
+      frames_received_ctr <= frames_received_ctr + 1;
+    end if;
+  end if;
+end process FRAMES_REC_CTR_PROC;
+
+FRAMES_READOUT_CTR_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    frames_readout_ctr <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if( RC_LOADING_DONE_IN = '1' ) then
+      frames_readout_ctr <= frames_readout_ctr + 1;
+    end if;    
+  end if;
+end process FRAMES_READOUT_CTR_PROC;
+
+-- debug only
+BYTES_REC_CTR_PROC : process( CLK )
+begin
+  if   ( RESET = '1' ) then
+    bytes_rec_ctr <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if( FR_FRAME_VALID_IN = '1' ) then
+      bytes_rec_ctr <= bytes_rec_ctr + unsigned(FR_FRAME_SIZE_IN);    
+    end if;
+  end if;
+end process BYTES_REC_CTR_PROC;
+
+SAVED_PROTO_PROC : process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( load_current_state = READY ) then
+      if( and_all(proto_code) = '0' ) then
+        saved_proto <= proto_code;
+      else
+        saved_proto <= (others => '0');
+      end if;
+    else
+      saved_proto <= saved_proto;
+    end if;
+  end if;
+end process SAVED_PROTO_PROC;
+
+end gbe_receive_control_arch;
diff --git a/gbe_trb/base/gbe_rx_rb.vhd b/gbe_trb/base/gbe_rx_rb.vhd
new file mode 100644 (file)
index 0000000..b699689
--- /dev/null
@@ -0,0 +1,290 @@
+library ieee;\r
+  use ieee.std_logic_1164.all;\r
+  use ieee.numeric_std.all;\r
+\r
+library work;\r
+\r
+entity gbe_rx_rb is\r
+  port(\r
+    CLK                 : in  std_logic;\r
+    RESET               : in  std_logic;\r
+    -- MAC interface (RX)\r
+    MAC_RX_DATA_IN      : in  std_logic_vector(7 downto 0); -- RX data from TSMAC\r
+    MAC_RX_WR_IN        : in  std_logic; -- RX data write from TSMAC\r
+    MAC_RX_EOF_IN       : in  std_logic; -- RX EndOfFrame from TSMAC\r
+    MAC_RX_ERROR_IN     : in  std_logic; -- RX Error from TSMAC\r
+    MAC_RX_FIFOFULL_OUT : out std_logic;\r
+    -- FIFO interface (TX)\r
+    FIFO_FULL_IN        : in  std_logic; -- TX fifo full, delay read from ring buffer\r
+    FIFO_WR_OUT         : out std_logic; -- TX fifo write\r
+    FIFO_Q_OUT          : out std_logic_vector(8 downto 0); -- TX data\r
+    FRAME_REQ_IN        : in  std_logic; -- one pulse starts readout of frame stored in ring buffer\r
+    FRAME_ACK_OUT       : out std_logic; -- one pulse for "end of frame"\r
+    FRAME_AVAIL_OUT     : out std_logic; -- number of frames stored in ring buffer\r
+    FRAME_START_OUT     : out std_logic  -- StartOfFrame signal\r
+  );\r
+end entity gbe_rx_rb;\r
+\r
+-- This entity acts as receive buffer for the new GbE media interface. It connects to the MAC RX ports,\r
+-- and is storing incoming Ethernet frames. \r
+-- Broken frames (indicated by MAC_RX_ERROR_IN) are dropped, and in addition, frames which can't be stored\r
+-- completely (due to potential ring buffer overflow) are also dropped.\r
+-- This entity can forward frames on request by doing "DMA":\r
+-- If a frame is requested by FRAME_REQ_IN, the entity decides if a full frame is available (as shown by\r
+-- FRAME_AVAIL_OUT), in case no data is present, a FRAME_ACK_OUT is generated to avoid deadlocks, but\r
+-- no data is transfered.\r
+-- If a frame can be transfered, FRAME_START_OUT is set for one cycle, and data is written out \r
+-- (handshaking with FIFO_FULL_IN) on FIFO_Q_OUT, with data validated by FIFO_WR_OUT.\r
+-- With the EOF signal (FIFO_Q_OUT(8)) set FRAME_ACK_OUT is also set and the transfer ends.\r
+\r
+architecture gbe_rx_rb_arch of gbe_rx_rb is\r
+\r
+-- state machine signals\r
+  type state_t is (RX_DENY,RX_READY,RX_FRAME,FRAME_OK,FRAME_BAD,FORWARD,SKIP);\r
+  signal STATE, NEXT_STATE    : state_t;\r
+\r
+-- Signals\r
+  signal rd_ptr             : unsigned(11 downto 0);\r
+  signal wr_ptr             : unsigned(11 downto 0);\r
+  signal last_wr_ptr        : std_logic_vector(11 downto 0);\r
+  signal rb_used_x          : unsigned(11 downto 0);\r
+  signal rb_full_x          : std_logic;\r
+  signal rb_empty_x         : std_logic;\r
+  signal ce_wr_ptr_x        : std_logic;\r
+  signal ld_wr_ptr_x        : std_logic;\r
+  signal ce_rd_ptr_x        : std_logic;\r
+  signal wr_ram_x           : std_logic;\r
+  signal rd_ram_x           : std_logic;\r
+  signal ram_q              : std_logic_vector(8 downto 0);\r
+  signal frame_requested    : std_logic;\r
+  signal frame_acknowledged : std_logic;\r
+  signal fifo_wr_int        : std_logic;\r
+  signal empty_read_ack     : std_logic;\r
+  signal normal_read_ack_x  : std_logic;\r
+  signal sof_int            : std_logic;\r
+  signal frames_avail       : unsigned(7 downto 0);\r
+  signal frame_active       : std_logic;\r
+  signal frame_error        : std_logic;\r
+  \r
+begin\r
+\r
+  -- FrameActive: we must not change to "receive" in the middle of a frame\r
+  -- when "buffer full" condition is deasserted.\r
+  -- Needs to be extra process, not inside the state machine!\r
+  PROC_FRAME_ACTIVE: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+        frame_active <= '0';\r
+    elsif( rising_edge(CLK) ) then\r
+      if   ( (MAC_RX_WR_IN = '1') and (frame_active = '0') ) then\r
+        frame_active <= '1';\r
+      elsif( (MAC_RX_EOF_IN = '1') and (frame_active = '1') ) then\r
+        frame_active <= '0';\r
+      end if;\r
+    end if;\r
+  end process PROC_FRAME_ACTIVE;\r
+\r
+  -- Read pointer for ring buffer\r
+  PROC_RD_PTR: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+      rd_ptr <= (others => '0');\r
+    elsif( rising_edge(CLK) ) then\r
+      if( ce_rd_ptr_x = '1' ) then\r
+        rd_ptr <= rd_ptr + 1;\r
+      end if;\r
+    end if;\r
+  end process PROC_RD_PTR;\r
+\r
+  -- Write pointer for ring buffer\r
+  PROC_WR_PTR: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+      wr_ptr <= (others => '0');\r
+    elsif( rising_edge(CLK) ) then\r
+      if   ( ld_wr_ptr_x = '1' ) then\r
+        wr_ptr <= unsigned(last_wr_ptr);\r
+      elsif( ce_wr_ptr_x = '1' ) then\r
+        wr_ptr <= wr_ptr + 1;\r
+      end if;\r
+    end if;\r
+  end process PROC_WR_PTR;\r
+\r
+  -- last write pointer: used to drop a broken frame, in case\r
+  PROC_LAST_WR_PTR: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+      last_wr_ptr <= (others => '0');\r
+    elsif( rising_edge(CLK) ) then\r
+      if( (STATE = RX_READY) and (MAC_RX_WR_IN = '1') ) then\r
+        last_wr_ptr <= std_logic_vector(wr_ptr);\r
+      end if;\r
+    end if;\r
+  end process PROC_LAST_WR_PTR;\r
+\r
+  -- ring buffer fill level\r
+  rb_used_x <= wr_ptr - rd_ptr;\r
+  \r
+  -- ring buffer full \r
+  -- TAKE CARE: the last byte of a frame is taken into account\r
+  --            by "one less" for the full condition\r
+  rb_full_x  <= '1' when (rb_used_x(11 downto 1) = b"1111_1111_111") else '0';\r
+\r
+  -- ring buffer empty\r
+  rb_empty_x <= '1' when (rb_used_x(11 downto 0) = b"0000_0000_0000") else '0';\r
+\r
+  MAC_RX_FIFOFULL_OUT <= rb_full_x;\r
+  \r
+  -- DPRAM as ring buffer\r
+  THE_DP_RAM: entity work.rb_4k_9\r
+  port map(\r
+    WRADDRESS         => std_logic_vector(wr_ptr),\r
+    RDADDRESS         => std_logic_vector(rd_ptr),\r
+    DATA(8)           => MAC_RX_EOF_IN,\r
+    DATA(7 downto 0)  => MAC_RX_DATA_IN,\r
+    WE                => wr_ram_x,\r
+    RDCLOCK           => CLK,\r
+    RDCLOCKEN         => '1',\r
+    RESET             => RESET,\r
+    WRCLOCK           => CLK,\r
+    WRCLOCKEN         => '1',\r
+    Q                 => ram_q\r
+  );\r
+\r
+  -- write signal \r
+  wr_ram_x    <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) or -- first byte of frame\r
+                          ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0'))    -- all other bytes of frame\r
+                     else '0';\r
+  ce_wr_ptr_x <= '1' when ((STATE = RX_READY) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0')) or\r
+                          ((STATE = RX_FRAME) and (MAC_RX_WR_IN = '1') and (rb_full_x = '0'))  \r
+                     else '0';\r
+\r
+  -- FrameError: catches problem with FIFOFULL during a frame write.\r
+  PROC_FRAME_ERROR: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+      frame_error <= '0';\r
+    elsif( rising_edge(CLK) ) then\r
+      if   ( (frame_active = '1') and (rb_full_x = '1') and (MAC_RX_WR_IN = '1') ) then\r
+        frame_error <= '1';\r
+      elsif( (frame_active = '0') ) then -- could be better!\r
+        frame_error <= '0';\r
+      end if;\r
+    end if;\r
+  end process PROC_FRAME_ERROR;\r
+                     \r
+  -- FrameReq signal, one pulse only\r
+  PROC_FRAME_REQ: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+      frame_requested <= '0';\r
+    elsif( rising_edge(CLK) ) then\r
+      if   ( (FRAME_REQ_IN = '1') and (frame_requested = '0') ) then\r
+        frame_requested <= '1';\r
+      elsif( ((ram_q(8) = '1') and (frame_requested = '1')) or (empty_read_ack = '1') ) then\r
+        frame_requested <= '0';\r
+      end if;\r
+    end if;\r
+  end process PROC_FRAME_REQ;\r
+  \r
+  -- NormalReadAck signal: ends a normal data transfer by EOF\r
+  normal_read_ack_x <= ram_q(8) and fifo_wr_int;\r
+  \r
+  -- read signal\r
+  rd_ram_x    <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty_x = '0')) else '0';\r
+  ce_rd_ptr_x <= '1' when ((frame_requested = '1') and (ram_q(8) = '0') and (FIFO_FULL_IN = '0') and (rb_empty_x = '0')) else '0';\r
+\r
+    empty_read_ack  <= FRAME_REQ_IN and rb_empty_x          when rising_edge(CLK);\r
+    sof_int         <= FRAME_REQ_IN and not frame_requested when rising_edge(CLK);  \r
+    FRAME_START_OUT <= sof_int                              when rising_edge(CLK);\r
+    fifo_wr_int     <= rd_ram_x                             when rising_edge(CLK);\r
+    FIFO_WR_OUT     <= fifo_wr_int                          when rising_edge(CLK);\r
+    FRAME_ACK_OUT   <= normal_read_ack_x or empty_read_ack  when rising_edge(CLK);  \r
+    FIFO_Q_OUT      <= ram_q                                when rising_edge(CLK);\r
+  \r
+  -- FramesAvailable counter\r
+  PROC_FRAMES_AVAIL: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+      frames_avail <= (others => '0');\r
+    elsif( rising_edge(CLK) ) then\r
+      if   ( (STATE = FRAME_OK) and (normal_read_ack_x = '0') ) then\r
+        -- one frame written successfully\r
+        frames_avail <= frames_avail + 1;\r
+      elsif( (STATE /= FRAME_OK) and (normal_read_ack_x = '1') ) then\r
+        -- one frame read successfully\r
+        frames_avail <= frames_avail - 1;\r
+      end if;\r
+    end if;\r
+  end process PROC_FRAMES_AVAIL;\r
+  \r
+  FRAME_AVAIL_OUT <= '1' when (frames_avail /= x"00") else '0';\r
+\r
+  -----------------------------------------------------------\r
+  -- statemachine: clocked process\r
+  -----------------------------------------------------------\r
+  PROC_FSM: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+      STATE <= RX_DENY;\r
+    elsif( rising_edge(CLK) ) then\r
+      STATE <= NEXT_STATE;\r
+    end if;\r
+  end process PROC_FSM;\r
+\r
+  PROC_STATE_TRANSITIONS: process( STATE, MAC_RX_WR_IN, MAC_RX_EOF_IN, MAC_RX_ERROR_IN, frame_active, rb_full_x )\r
+  begin\r
+    ld_wr_ptr_x <= '0';\r
+    \r
+    case STATE is\r
+\r
+      when RX_DENY =>\r
+        if( (frame_active = '0') and (rb_full_x = '0') ) then\r
+          NEXT_STATE <= RX_READY;\r
+        else\r
+          NEXT_STATE <= RX_DENY;\r
+        end if;\r
+      \r
+      when RX_READY =>\r
+        if( MAC_RX_WR_IN = '1' ) then\r
+          NEXT_STATE <= RX_FRAME;\r
+        else\r
+          NEXT_STATE <= RX_READY;\r
+        end if;\r
+        \r
+      when RX_FRAME =>\r
+        if   ( (MAC_RX_EOF_IN = '1') and (MAC_RX_ERROR_IN = '0') and (rb_full_x = '0') ) then\r
+          NEXT_STATE <= FRAME_OK;\r
+        elsif( (MAC_RX_EOF_IN = '1') and ((MAC_RX_ERROR_IN = '1') or (rb_full_x = '1')) ) then\r
+          NEXT_STATE <= FRAME_BAD;\r
+          ld_wr_ptr_x <= '1';\r
+        else\r
+          NEXT_STATE <= RX_FRAME;\r
+        end if;\r
+      \r
+      when FRAME_OK =>\r
+        NEXT_STATE <= FORWARD;\r
+        \r
+      when FORWARD =>\r
+        if( rb_full_x = '0' ) then\r
+          NEXT_STATE <= RX_READY;\r
+        else\r
+          NEXT_STATE <= RX_DENY;\r
+        end if;\r
+\r
+      when FRAME_BAD =>\r
+        NEXT_STATE <= SKIP;\r
+        \r
+      when SKIP =>\r
+        if( rb_full_x = '0' ) then\r
+          NEXT_STATE <= RX_READY;\r
+        else\r
+          NEXT_STATE <= RX_DENY;\r
+        end if;\r
+\r
+      when others  =>\r
+        NEXT_STATE <= RX_DENY;\r
+    end case;\r
+  end process PROC_STATE_TRANSITIONS;\r
+\r
+end architecture gbe_rx_rb_arch;\r
diff --git a/gbe_trb/base/gbe_sgl_ctrl.vhd b/gbe_trb/base/gbe_sgl_ctrl.vhd
new file mode 100644 (file)
index 0000000..d9c424b
--- /dev/null
@@ -0,0 +1,351 @@
+library ieee;\r
+  use ieee.std_logic_1164.all;\r
+  use ieee.numeric_std.all;\r
+\r
+library work;\r
+\r
+entity gbe_sgl_ctrl is\r
+  port(\r
+    CLK                   : in  std_logic;\r
+    RESET                 : in  std_logic;\r
+    -- UL port\r
+    UL_FIFOFULL_IN        : in  std_logic := '0'; -- UL TX FIFO is full\r
+    UL_FRAME_AVAIL_IN     : in  std_logic := '0'; -- UL RX has frames available for scattering\r
+    UL_FRAME_REQ_OUT      : out std_logic;        -- UL RX request to send\r
+    UL_FRAME_ACK_IN       : in  std_logic := '0'; -- UL RX sent acknowledge\r
+    -- DL ports (includes SCTRL)\r
+    DL_FIFOFULL_IN        : in  std_logic_vector(15 downto 0) := (others => '0'); -- DL TXn FIFO is full\r
+    DL_FRAME_AVAIL_IN     : in  std_logic_vector(15 downto 0) := (others => '0'); -- DL RXn has frames available for scattering\r
+    DL_FRAME_REQ_OUT      : out std_logic_vector(15 downto 0);                    -- DL RXn request to send\r
+    DL_FRAME_ACK_IN       : in  std_logic_vector(15 downto 0) := (others => '0'); -- DL RXn sent acknowledge\r
+    -- LOCAL port\r
+    LOCAL_FIFOFULL_IN     : in  std_logic := '0'; -- LOCAL TX FIFO is full\r
+    LOCAL_FRAME_AVAIL_IN  : in  std_logic := '0'; -- LOCAL RX has frames available\r
+    LOCAL_FRAME_REQ_OUT   : out std_logic;        -- LOCAL RX request to send\r
+    LOCAL_FRAME_ACK_IN    : in  std_logic := '0'; -- LOCAL RX sent acknowledge\r
+    --\r
+    DL_RX_PORT_SEL_OUT    : out std_logic_vector(15 downto 0);\r
+    DL_RX_PORT_MUX_OUT    : out std_logic_vector(3 downto 0);\r
+    DL_TX_PORT_SEL_OUT    : out std_logic; -- '0' => LOCAL, '1' UL\r
+    LOCAL_TX_PORT_SEL_OUT : out std_logic;\r
+    UL_TX_PORT_SEL_OUT    : out std_logic;\r
+    --\r
+    DEBUG                 : out std_logic_vector(15 downto 0)\r
+  );\r
+end entity gbe_sgl_ctrl;\r
+\r
+architecture gbe_sgl_ctrl_arch of gbe_sgl_ctrl is\r
+\r
+-- Components\r
+\r
+-- state machine signals\r
+  type state_t is (IDLE,SC_START,SC_PORT,SC_DELAY,SC_CLEANUP,\r
+                    GA_START,GA_STORE,GA_PORT,GA_DELAY,GA_CLEANUP,\r
+                    LC_START,LC_PORT,LC_DELAY,LC_CLEANUP);\r
+  signal STATE, NEXT_STATE    : state_t;\r
+\r
+-- Signals\r
+  signal scatter_fifofull_x     : std_logic;\r
+  signal gather_fifofull_x      : std_logic;\r
+  signal local_fifofull_x       : std_logic;\r
+  signal gather_needed_x        : std_logic;\r
+  signal store_ports_x          : std_logic;\r
+  signal stored_ports           : std_logic_vector(15 downto 0);\r
+  signal all_ports_done_x       : std_logic;\r
+  signal select_ports           : std_logic_vector(15 downto 0);\r
+  signal req_ports              : std_logic_vector(15 downto 0);\r
+  signal next_mux_x             : std_logic_vector(3 downto 0);\r
+  signal mux_ports              : std_logic_vector(3 downto 0);\r
+  signal next_port_x            : std_logic_vector(15 downto 0);\r
+\r
+  signal ul_frame_req_x         : std_logic;\r
+  signal ul_frame_req           : std_logic;\r
+  signal local_frame_req_x      : std_logic;\r
+  signal local_frame_req        : std_logic;\r
+\r
+  signal dl_tx_port_sel_x       : std_logic;\r
+  signal local_tx_port_sel_x    : std_logic;\r
+  signal ul_tx_port_sel_x       : std_logic;\r
+\r
+  signal bsm                    : std_logic_vector(3 downto 0);\r
+  \r
+begin\r
+\r
+  -- Debug signals for hardware\r
+  DEBUG(15 downto 4) <= (others => '0');\r
+  DEBUG(3 downto 0)  <= bsm;\r
+\r
+  -- SCATTER: fifofull is created from DL and LOCAL ports (not SCTRL)\r
+  scatter_fifofull_x <= '1' when ((DL_FIFOFULL_IN(15 downto 1) /= b"0000_0000_0000_000") or (LOCAL_FIFOFULL_IN = '1'))\r
+                        else '0';\r
+\r
+  -- GATHER: fifofull is created from UL and LOCAL\r
+  gather_fifofull_x <= '1' when ((UL_FIFOFULL_IN = '1') or (LOCAL_FIFOFULL_IN = '1'))\r
+                        else '0';\r
+\r
+  -- LOCAL: fifofull is created from UL and DL ()\r
+  local_fifofull_x <= '1' when ((DL_FIFOFULL_IN(15 downto 1) /= b"0000_0000_0000_000") or (UL_FIFOFULL_IN = '1'))\r
+                      else '0';\r
+\r
+  -- GATHER:\r
+  gather_needed_x <= '1' when (DL_FRAME_AVAIL_IN /= x"0000")\r
+                     else '0';\r
+\r
+  -- store the src port status\r
+  GEN_REGS: for I in 0 to 15 generate\r
+    THE_SRC_STORE_PROC: process( CLK, RESET )\r
+    begin\r
+      if   ( RESET = '1' ) then\r
+        stored_ports(I) <= '0';\r
+      elsif( rising_edge(CLK) ) then\r
+        if   ( store_ports_x = '1' ) then\r
+          stored_ports(I) <= DL_FRAME_AVAIL_IN(I);\r
+        elsif( DL_FRAME_ACK_IN(I) = '1' ) then\r
+          stored_ports(I) <= '0';\r
+        end if;\r
+      end if;\r
+    end process THE_SRC_STORE_PROC;\r
+  end generate;\r
+\r
+  all_ports_done_x <= '1' when stored_ports = x"0000" else '0';\r
+\r
+  -- select the port data\r
+  THE_SELECT_PORT_PROC: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+      select_ports <= (others => '0');\r
+      mux_ports    <= (others => '0');\r
+    elsif( rising_edge(CLK) ) then\r
+      select_ports <= next_port_x;\r
+      mux_ports    <= next_mux_x;\r
+    end if;\r
+  end process THE_SELECT_PORT_PROC;\r
+\r
+  DL_RX_PORT_SEL_OUT <= select_ports;\r
+  DL_RX_PORT_MUX_OUT <= mux_ports;\r
+\r
+  -- port frame request, one clock cycle pulse\r
+  req_ports <= not select_ports and next_port_x when rising_edge(CLK);\r
+\r
+  DL_FRAME_REQ_OUT <= req_ports;\r
+\r
+  -- priority decoced "next port to serve" signals\r
+  THE_NEXT_PORT_PROC: process( stored_ports )\r
+  begin\r
+    if   ( stored_ports(0) = '1' ) then\r
+      next_port_x <= x"0001";\r
+      next_mux_x  <= x"0";\r
+    elsif( stored_ports(1) = '1' ) then\r
+      next_port_x <= x"0002";\r
+      next_mux_x  <= x"1";\r
+    elsif( stored_ports(2) = '1' ) then\r
+      next_port_x <= x"0004";\r
+      next_mux_x  <= x"2";\r
+    elsif( stored_ports(3) = '1' ) then\r
+      next_port_x <= x"0008";\r
+      next_mux_x  <= x"3";\r
+    elsif( stored_ports(4) = '1' ) then\r
+      next_port_x <= x"0010";\r
+      next_mux_x  <= x"4";\r
+    elsif( stored_ports(5) = '1' ) then\r
+      next_port_x <= x"0020";\r
+      next_mux_x  <= x"5";\r
+    elsif( stored_ports(6) = '1' ) then\r
+      next_port_x <= x"0040";\r
+      next_mux_x  <= x"6";\r
+    elsif( stored_ports(7) = '1' ) then\r
+      next_port_x <= x"0080";\r
+      next_mux_x  <= x"7";\r
+    elsif( stored_ports(8) = '1' ) then\r
+      next_port_x <= x"0100";\r
+      next_mux_x  <= x"8";\r
+    elsif( stored_ports(9) = '1' ) then\r
+      next_port_x <= x"0200";\r
+      next_mux_x  <= x"9";\r
+    elsif( stored_ports(10) = '1' ) then\r
+      next_port_x <= x"0400";\r
+      next_mux_x  <= x"a";\r
+    elsif( stored_ports(11) = '1' ) then\r
+      next_port_x <= x"0800";\r
+      next_mux_x  <= x"b";\r
+    elsif( stored_ports(12) = '1' ) then\r
+      next_port_x <= x"1000";\r
+      next_mux_x  <= x"c";\r
+    elsif( stored_ports(13) = '1' ) then\r
+      next_port_x <= x"2000";\r
+      next_mux_x  <= x"d";\r
+    elsif( stored_ports(14) = '1' ) then\r
+      next_port_x <= x"4000";\r
+      next_mux_x  <= x"e";\r
+    elsif( stored_ports(15) = '1' ) then\r
+      next_port_x <= x"8000";\r
+      next_mux_x  <= x"f";\r
+    else\r
+      next_port_x <= x"0000";\r
+      next_mux_x  <= x"0";\r
+    end if;\r
+  end process THE_NEXT_PORT_PROC;\r
+\r
+  -----------------------------------------------------------\r
+  -- Outputs\r
+  -----------------------------------------------------------\r
+  UL_FRAME_REQ_OUT      <= ul_frame_req;\r
+  LOCAL_FRAME_REQ_OUT   <= local_frame_req;\r
+  DL_TX_PORT_SEL_OUT    <= dl_tx_port_sel_x;\r
+  LOCAL_TX_PORT_SEL_OUT <= local_tx_port_sel_x;\r
+  UL_TX_PORT_SEL_OUT    <= ul_tx_port_sel_x;\r
+\r
+  -----------------------------------------------------------\r
+  -- statemachine: clocked process\r
+  -----------------------------------------------------------\r
+  THE_FSM: process( CLK, RESET )\r
+  begin\r
+    if   ( RESET = '1' ) then\r
+      STATE <= IDLE;\r
+      ul_frame_req <= '0';\r
+      local_frame_req <= '0';\r
+    elsif( rising_edge(CLK) ) then\r
+      STATE <= NEXT_STATE;\r
+      ul_frame_req <= ul_frame_req_x;\r
+      local_frame_req <= local_frame_req_x;\r
+    end if;\r
+  end process THE_FSM;\r
+\r
+  -----------------------------------------------------------\r
+  --\r
+  -----------------------------------------------------------\r
+  THE_STATE_TRANSITIONS: process( STATE, UL_FRAME_AVAIL_IN, LOCAL_FRAME_AVAIL_IN, UL_FRAME_ACK_IN,\r
+                                   LOCAL_FRAME_ACK_IN, scatter_fifofull_x, gather_fifofull_x,\r
+                                   local_fifofull_x, all_ports_done_x )\r
+  begin\r
+    ul_frame_req_x <= '0';\r
+    local_frame_req_x <= '0';\r
+    store_ports_x <= '0';\r
+    dl_tx_port_sel_x <= '0';\r
+    local_tx_port_sel_x <= '0';\r
+    ul_tx_port_sel_x <= '0';\r
+\r
+    case STATE is\r
+      when IDLE =>\r
+        bsm <= x"0";\r
+        if   ( (UL_FRAME_AVAIL_IN = '1') and (scatter_fifofull_x = '0') ) then\r
+          NEXT_STATE <= SC_START;\r
+        elsif( (gather_needed_x = '1') and (gather_fifofull_x = '0') ) then\r
+          NEXT_STATE <= GA_START;\r
+        elsif( (LOCAL_FRAME_AVAIL_IN = '1') and (local_fifofull_x = '0') ) then\r
+          NEXT_STATE <= LC_START;\r
+        else \r
+          NEXT_STATE <= IDLE;\r
+        end if;\r
+\r
+      when SC_START =>\r
+        bsm <= x"1";\r
+        NEXT_STATE <= SC_PORT;\r
+        ul_frame_req_x <= '1';\r
+        dl_tx_port_sel_x <= '1';\r
+        local_tx_port_sel_x <= '1';\r
+\r
+      when SC_PORT =>\r
+        bsm <= x"2";\r
+        if( UL_FRAME_ACK_IN = '1' ) then\r
+          NEXT_STATE <= SC_DELAY;\r
+        else\r
+          NEXT_STATE <= SC_PORT;\r
+        end if;\r
+        dl_tx_port_sel_x <= '1';\r
+        local_tx_port_sel_x <= '1';\r
+\r
+      when SC_DELAY =>\r
+        bsm <= x"3";\r
+        NEXT_STATE <= SC_CLEANUP;\r
+        dl_tx_port_sel_x <= '1';\r
+        local_tx_port_sel_x <= '1';\r
+\r
+      when SC_CLEANUP =>\r
+        bsm <= x"4";\r
+        if   ( (gather_needed_x = '1') and (gather_fifofull_x = '0') ) then\r
+          NEXT_STATE <= GA_START;\r
+        elsif( (LOCAL_FRAME_AVAIL_IN = '1') and (local_fifofull_x = '0') ) then\r
+          NEXT_STATE <= LC_START;\r
+        elsif( (UL_FRAME_AVAIL_IN = '1') and (scatter_fifofull_x = '0') ) then\r
+          NEXT_STATE <= SC_START;\r
+        else\r
+          NEXT_STATE <= IDLE;\r
+        end if;\r
+        dl_tx_port_sel_x <= '1'; -- maybe not needed\r
+        local_tx_port_sel_x <= '1'; -- maybe not needed\r
+\r
+      when GA_START =>\r
+        bsm <= x"5";\r
+        NEXT_STATE <= GA_STORE;\r
+        store_ports_x <= '1';\r
+        ul_tx_port_sel_x <= '1';\r
+\r
+      when GA_STORE =>\r
+        bsm <= x"6";\r
+        NEXT_STATE <= GA_PORT;\r
+        ul_tx_port_sel_x <= '1';\r
+\r
+      when GA_PORT =>\r
+        bsm <= x"7";\r
+        if( all_ports_done_x = '1' ) then\r
+          NEXT_STATE <= GA_DELAY;\r
+        else\r
+          NEXT_STATE <= GA_PORT;\r
+        end if;\r
+        ul_tx_port_sel_x <= '1';\r
+\r
+      when GA_DELAY =>\r
+        bsm <= x"8";\r
+        NEXT_STATE <= GA_CLEANUP;\r
+        ul_tx_port_sel_x <= '1';\r
+\r
+      when GA_CLEANUP =>\r
+        bsm <= x"9";\r
+        if   ( (LOCAL_FRAME_AVAIL_IN = '1') and (local_fifofull_x = '0') ) then\r
+          NEXT_STATE <= LC_START;\r
+        elsif( (UL_FRAME_AVAIL_IN = '1') and (scatter_fifofull_x = '0') ) then\r
+          NEXT_STATE <= SC_START;\r
+        elsif( (gather_needed_x = '1') and (gather_fifofull_x = '0') ) then\r
+          NEXT_STATE <= GA_START;\r
+        else\r
+          NEXT_STATE <= IDLE;\r
+        end if;\r
+        ul_tx_port_sel_x <= '1'; -- maybe not needed\r
+\r
+      when LC_START =>\r
+        bsm <= x"a";\r
+        NEXT_STATE <= LC_PORT;\r
+        local_frame_req_x <= '1';\r
+\r
+      when LC_PORT =>\r
+        bsm <= x"b";\r
+        if( LOCAL_FRAME_ACK_IN = '1' ) then\r
+          NEXT_STATE <= LC_DELAY;\r
+        else\r
+          NEXT_STATE <= LC_PORT;\r
+        end if;\r
+\r
+      when LC_DELAY =>\r
+        bsm <= x"c";\r
+        NEXT_STATE <= LC_CLEANUP;\r
+\r
+      when LC_CLEANUP =>\r
+        bsm <= x"d";\r
+        if   ( (UL_FRAME_AVAIL_IN = '1') and (scatter_fifofull_x = '0') ) then\r
+          NEXT_STATE <= SC_START;\r
+        elsif( (gather_needed_x = '1') and (gather_fifofull_x = '0') ) then\r
+          NEXT_STATE <= GA_START;\r
+        elsif( (LOCAL_FRAME_AVAIL_IN = '1') and (local_fifofull_x = '0') ) then\r
+          NEXT_STATE <= LC_START;\r
+        else\r
+          NEXT_STATE <= IDLE;\r
+        end if;\r
+\r
+      when others  =>\r
+        bsm <= x"f";\r
+        NEXT_STATE <= IDLE;\r
+    end case;\r
+  end process THE_STATE_TRANSITIONS;\r
+\r
+end architecture gbe_sgl_ctrl_arch;\r
diff --git a/gbe_trb/base/gbe_transmit_control.vhd b/gbe_trb/base/gbe_transmit_control.vhd
new file mode 100644 (file)
index 0000000..53d1c9a
--- /dev/null
@@ -0,0 +1,302 @@
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.gbe_protocols.all;
+
+entity gbe_transmit_control is
+port (
+  CLK                      : in  std_logic;
+  RESET                    : in  std_logic;
+-- signal to/from main controller
+  TC_DATAREADY_IN          : in  std_logic;
+  TC_RD_EN_OUT             : out std_logic;
+  TC_DATA_IN               : in  std_logic_vector(7 downto 0);
+  TC_FRAME_SIZE_IN         : in  std_logic_vector(15 downto 0);
+  TC_FRAME_TYPE_IN         : in  std_logic_vector(15 downto 0);
+  TC_IP_PROTOCOL_IN        : in  std_logic_vector(7 downto 0);  
+  TC_DEST_MAC_IN           : in  std_logic_vector(47 downto 0);
+  TC_DEST_IP_IN            : in  std_logic_vector(31 downto 0);
+  TC_DEST_UDP_IN           : in  std_logic_vector(15 downto 0);
+  TC_SRC_MAC_IN            : in  std_logic_vector(47 downto 0);
+  TC_SRC_IP_IN             : in  std_logic_vector(31 downto 0);
+  TC_SRC_UDP_IN            : in  std_logic_vector(15 downto 0);
+  TC_TRANSMISSION_DONE_OUT : out std_logic;
+  TC_IDENT_IN              : in  std_logic_vector(15 downto 0);
+  TC_MAX_FRAME_IN          : in  std_logic_vector(15 downto 0);
+-- signal to/from frame constructor
+  FC_DATA_OUT              : out std_logic_vector(7 downto 0);
+  FC_WR_EN_OUT             : out std_logic;
+  FC_READY_IN              : in  std_logic;
+  FC_H_READY_IN            : in  std_logic;
+  FC_FRAME_TYPE_OUT        : out std_logic_vector(15 downto 0);
+  FC_IP_SIZE_OUT           : out std_logic_vector(15 downto 0);
+  FC_UDP_SIZE_OUT          : out std_logic_vector(15 downto 0);
+  FC_IDENT_OUT             : out std_logic_vector(15 downto 0);  -- internal packet counter
+  FC_FLAGS_OFFSET_OUT      : out std_logic_vector(15 downto 0);
+  FC_SOD_OUT               : out std_logic;
+  FC_EOD_OUT               : out std_logic;
+  FC_IP_PROTOCOL_OUT       : out std_logic_vector(7 downto 0);
+--
+  DEST_MAC_ADDRESS_OUT     : out std_logic_vector(47 downto 0);
+  DEST_IP_ADDRESS_OUT      : out std_logic_vector(31 downto 0);
+  DEST_UDP_PORT_OUT        : out std_logic_vector(15 downto 0);
+  SRC_MAC_ADDRESS_OUT      : out std_logic_vector(47 downto 0);
+  SRC_IP_ADDRESS_OUT       : out std_logic_vector(31 downto 0);
+  SRC_UDP_PORT_OUT         : out std_logic_vector(15 downto 0);
+--
+  MONITOR_TX_PACKETS_OUT   : out std_logic_vector(31 downto 0);
+--  
+  DEBUG_OUT                : out std_logic_vector(63 downto 0)
+);
+end gbe_transmit_control;
+
+architecture gbe_transmit_control_arch of gbe_transmit_control is
+
+attribute syn_encoding : string;
+
+type transmit_states is (IDLE, PREPARE_HEADERS, WAIT_FOR_H, TRANSMIT, SEND_ONE, SEND_TWO, CLOSE, WAIT_FOR_TRANS, DIVIDE, CLEANUP);
+signal transmit_current_state, transmit_next_state : transmit_states;
+attribute syn_encoding of transmit_current_state : signal is "onehot";
+
+signal tc_rd, tc_rd_q, tc_rd_qq : std_logic;
+signal local_end : std_logic_vector(15 downto 0);
+
+signal actual_frame_bytes, full_packet_size, ip_size, packet_loaded_bytes : std_logic_vector(15 downto 0);
+signal go_to_divide, more_fragments : std_logic;
+signal first_frame : std_logic;
+signal mon_packets_sent_ctr : std_logic_vector(31 downto 0); 
+signal state : std_logic_vector(3 downto 0);
+
+begin
+
+TRANSMIT_MACHINE_PROC : process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    transmit_current_state <= IDLE;
+  elsif( rising_edge(CLK) ) then
+    transmit_current_state <= transmit_next_state;
+  end if;
+end process TRANSMIT_MACHINE_PROC;
+
+TRANSMIT_MACHINE : process(transmit_current_state, FC_H_READY_IN, TC_DATAREADY_IN, FC_READY_IN, local_end, TC_MAX_FRAME_IN, actual_frame_bytes, go_to_divide)
+begin
+  state <= x"0";
+  case transmit_current_state is
+  
+  when IDLE =>
+      state <= x"1";
+      if (TC_DATAREADY_IN = '1') then
+        transmit_next_state <= PREPARE_HEADERS;
+      else
+        transmit_next_state <= IDLE;
+      end if;
+      
+    when PREPARE_HEADERS =>
+      state <= x"2";
+      transmit_next_state<= WAIT_FOR_H;
+    
+    when WAIT_FOR_H =>
+      state <= x"3";
+      if (FC_H_READY_IN = '1') then
+        transmit_next_state <= TRANSMIT;
+      else
+        transmit_next_state <= WAIT_FOR_H;
+      end if;
+    
+    when TRANSMIT =>
+      state <= x"4";
+      if (local_end = x"0000") then
+        transmit_next_state <= SEND_ONE;
+      else
+        if (actual_frame_bytes = TC_MAX_FRAME_IN - x"1") then
+          transmit_next_state <= SEND_ONE;
+        else
+          transmit_next_state <= TRANSMIT;
+        end if;
+      end if;
+      
+    when SEND_ONE =>
+      state <= x"5";
+      transmit_next_state <= SEND_TWO;
+      
+    when SEND_TWO =>
+      state <= x"6";
+      transmit_next_state <= CLOSE;
+      
+    when CLOSE =>
+      state <= x"7";
+      transmit_next_state <= WAIT_FOR_TRANS;
+      
+    when WAIT_FOR_TRANS =>
+      state <= x"8";
+      if (FC_READY_IN = '1') then
+        if (go_to_divide = '1') then
+          transmit_next_state <= DIVIDE;
+        else
+          transmit_next_state <= CLEANUP;
+        end if;
+      else
+        transmit_next_state <= WAIT_FOR_TRANS;
+      end if;
+    
+    when DIVIDE =>
+      state <= x"9";
+      transmit_next_state <= PREPARE_HEADERS;
+      
+    when CLEANUP =>
+      state <= x"a";
+      transmit_next_state <= IDLE;
+  
+  end case;
+end process TRANSMIT_MACHINE;
+
+tc_rd               <= '1' when transmit_current_state = TRANSMIT else '0';
+
+TC_RD_EN_OUT        <= tc_rd;
+
+SYNC_PROC : process( CLK )
+begin
+  if( rising_edge(CLK) ) then    
+    tc_rd_q <= tc_rd;
+    tc_rd_qq <= tc_rd_q;
+    FC_WR_EN_OUT <= tc_rd_qq;
+  end if;
+end process SYNC_PROC;
+
+ACTUAL_FRAME_BYTES_PROC : process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( transmit_current_state = IDLE or transmit_current_state = DIVIDE ) then
+      actual_frame_bytes <= (others => '0');
+    elsif( transmit_current_state = TRANSMIT ) then
+      actual_frame_bytes <= actual_frame_bytes + x"1";
+    end if;
+  end if;
+end process ACTUAL_FRAME_BYTES_PROC;
+
+GO_TO_DIVIDE_PROC : process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( transmit_current_state = IDLE or transmit_current_state = DIVIDE ) then
+      go_to_divide <= '0';
+    elsif( transmit_current_state = TRANSMIT and actual_frame_bytes = TC_MAX_FRAME_IN - x"1" ) then
+      go_to_divide <= '1';
+    elsif( transmit_current_state = SEND_ONE and full_packet_size = packet_loaded_bytes ) then
+      go_to_divide <= '0';
+    end if;    
+  end if;
+end process GO_TO_DIVIDE_PROC;
+
+LOCAL_END_PROC : process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( transmit_current_state = IDLE and TC_DATAREADY_IN = '1' ) then
+      local_end <= TC_FRAME_SIZE_IN - x"1";
+      full_packet_size <= TC_FRAME_SIZE_IN;
+    elsif( transmit_current_state = TRANSMIT ) then
+      local_end <= local_end - x"1";
+      full_packet_size <= full_packet_size;
+    end if; 
+  end if;
+end process LOCAL_END_PROC;
+
+FC_DATA_OUT         <= TC_DATA_IN;
+FC_SOD_OUT      <= '1' when transmit_current_state = WAIT_FOR_H else '0';
+FC_EOD_OUT      <= '1' when transmit_current_state = CLOSE else '0';
+
+process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( transmit_current_state = PREPARE_HEADERS ) then
+      if( local_end >= TC_MAX_FRAME_IN ) then
+        ip_size <= TC_MAX_FRAME_IN;
+      else
+        ip_size <= local_end + x"1";
+      end if;
+    else
+      ip_size <= ip_size;
+    end if;
+  end if;
+end process;
+FC_IP_SIZE_OUT     <= ip_size; 
+FC_UDP_SIZE_OUT    <= full_packet_size;
+
+FC_FLAGS_OFFSET_OUT(15 downto 14) <= "00";
+FC_FLAGS_OFFSET_OUT(13) <= more_fragments;
+
+MORE_FRAGMENTS_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( transmit_current_state = PREPARE_HEADERS ) then
+      if( local_end >= TC_MAX_FRAME_IN ) then
+        more_fragments <= '1';
+      else
+        more_fragments <= '0';
+      end if;
+    end if;
+  end if;
+end process MORE_FRAGMENTS_PROC;
+
+FC_FLAGS_OFFSET_OUT(12 downto 0) <= ('0' & x"000") when first_frame = '1' else (packet_loaded_bytes(15 downto 3) + x"1");
+
+PACKET_LOADED_BYTES_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( transmit_current_state = IDLE ) then
+      packet_loaded_bytes <= x"0000";
+    elsif( transmit_current_state = TRANSMIT ) then
+      packet_loaded_bytes <= packet_loaded_bytes + x"1";
+    end if;
+  end if;
+end process PACKET_LOADED_BYTES_PROC;
+
+FIRST_FRAME_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( transmit_current_state = IDLE ) then
+      first_frame <= '1';
+    elsif( transmit_current_state = DIVIDE ) then
+      first_frame <= '0';
+    end if;
+  end if;  
+end process FIRST_FRAME_PROC;
+
+
+TC_TRANSMISSION_DONE_OUT <= '1' when transmit_current_state = CLEANUP else '0';
+
+FC_FRAME_TYPE_OUT    <= TC_FRAME_TYPE_IN;
+FC_IP_PROTOCOL_OUT   <= TC_IP_PROTOCOL_IN;
+DEST_MAC_ADDRESS_OUT <= TC_DEST_MAC_IN;
+DEST_IP_ADDRESS_OUT  <= TC_DEST_IP_IN;
+DEST_UDP_PORT_OUT    <= TC_DEST_UDP_IN;
+SRC_MAC_ADDRESS_OUT  <= TC_SRC_MAC_IN;
+SRC_IP_ADDRESS_OUT   <= TC_SRC_IP_IN;
+SRC_UDP_PORT_OUT     <= TC_SRC_UDP_IN;
+FC_IDENT_OUT         <= TC_IDENT_IN;
+
+-- monitoring
+
+process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    mon_packets_sent_ctr <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if( transmit_current_state = CLEANUP ) then
+      mon_packets_sent_ctr <= mon_packets_sent_ctr + x"1";
+    end if;
+  end if;
+end process;
+
+MONITOR_TX_PACKETS_OUT <= mon_packets_sent_ctr;
+
+DEBUG_OUT(3 downto 0) <= state;
+DEBUG_OUT(4) <= FC_READY_IN;
+
+end gbe_transmit_control_arch;
+
+
diff --git a/gbe_trb/base/gbe_type_validator.vhd b/gbe_trb/base/gbe_type_validator.vhd
new file mode 100644 (file)
index 0000000..4da7ad7
--- /dev/null
@@ -0,0 +1,130 @@
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.gbe_protocols.all;
+
+--********
+-- contains valid frame types codes and performs checking of type and vlan id
+-- by default there is place for 32 frame type which is hardcoded value
+-- due to allow register which is set by slow control
+
+entity gbe_type_validator is
+port (
+  CLK                      : in  std_logic;  -- 125MHz clock input
+  RESET                    : in  std_logic;
+  -- ethernet level
+  FRAME_TYPE_IN            : in  std_logic_vector(15 downto 0);  -- recovered frame type       
+  SAVED_VLAN_ID_IN         : in  std_logic_vector(15 downto 0);  -- recovered vlan id
+  ALLOWED_TYPES_IN         : in  std_logic_vector(31 downto 0);  -- signal from gbe_setup
+  VLAN_ID_IN               : in  std_logic_vector(31 downto 0);  -- two values from gbe setup
+  -- IP level
+  IP_PROTOCOLS_IN          : in  std_logic_vector(7 downto 0);
+  ALLOWED_IP_PROTOCOLS_IN  : in  std_logic_vector(31 downto 0);
+  -- UDP level
+  UDP_PROTOCOL_IN          : in  std_logic_vector(15 downto 0);
+  ALLOWED_UDP_PROTOCOLS_IN : in  std_logic_vector(31 downto 0);
+  -- result
+  VALID_OUT                : out std_logic
+);
+end gbe_type_validator;
+
+architecture gbe_type_validator_arch of gbe_type_validator is
+
+signal result                  : std_logic_vector(c_MAX_FRAME_TYPES - 1 downto 0);
+signal ip_result               : std_logic_vector(c_MAX_IP_PROTOCOLS - 1 downto 0);
+signal udp_result              : std_logic_vector(c_MAX_UDP_PROTOCOLS - 1 downto 0);
+signal partially_valid         : std_logic;  -- only protocols, vlan to be checked
+signal zeros                   : std_logic_vector(c_MAX_FRAME_TYPES - 1 downto 0);
+
+begin
+  
+  zeros <= (others => '0');
+
+-- checks for allowed IP protocols (UDP, ICMP)
+IP_RESULTS_GEN: for i in 0 to c_MAX_IP_PROTOCOLS - 1 generate
+process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( (IP_PROTOCOLS(i) = IP_PROTOCOLS_IN) and (ALLOWED_IP_PROTOCOLS_IN(i) = '1') )then
+      ip_result(i) <= '1';
+    else
+      ip_result(i) <= '0';
+    end if;
+  end if;
+end process;
+end generate IP_RESULTS_GEN;
+
+-- checks for allowed UDP destination ports (DHCP, SCTRL)
+UDP_RESULTS_GEN: for i in 0 to c_MAX_UDP_PROTOCOLS - 1 generate
+process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( (UDP_PROTOCOLS(i) = UDP_PROTOCOL_IN) and (ALLOWED_UDP_PROTOCOLS_IN(i) = '1') ) then
+      udp_result(i) <= '1';
+    else
+      udp_result(i) <= '0';
+    end if;
+  end if;
+end process;
+end generate UDP_RESULTS_GEN;
+
+-- checks for allowed frame type (IPv4, ARP)
+FRAME_RESULTS_GEN: for i in 0 to c_MAX_FRAME_TYPES - 1 generate
+process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( (FRAME_TYPES(i) = FRAME_TYPE_IN) and (ALLOWED_TYPES_IN(i) = '1') ) then
+      result(i) <= '1';
+    else
+      result(i) <= '0';
+    end if;
+  end if;
+end process;
+end generate FRAME_RESULTS_GEN;
+
+PARTIALLY_VALID_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( RESET = '1' ) then
+      partially_valid <= '0';
+    elsif( FRAME_TYPE_IN = x"0800" ) then  -- ip frame
+      if   ( IP_PROTOCOLS_IN = x"11" ) then -- in case of udp inside ip
+        partially_valid <= or_all(udp_result);
+      elsif( (IP_PROTOCOLS_IN = x"01") or (IP_PROTOCOLS_IN = x"dd") or (IP_PROTOCOLS_IN = x"ee") ) then  -- in case of ICMP
+        partially_valid <= '1';
+      else  -- do not accept other protocols than udp and icmp inside ip
+        partially_valid <= '0';
+      end if;
+    elsif( result /= zeros ) then-- other frame
+      partially_valid <= '1';
+    else
+      partially_valid <= '0';                  
+    end if;
+  end if;
+end process PARTIALLY_VALID_PROC;
+
+VALID_OUT_PROC: process( CLK )
+begin
+  if rising_edge(CLK) then
+    if( partially_valid = '1' ) then
+      if   ( SAVED_VLAN_ID_IN = x"0000" ) then
+        VALID_OUT <= '1';
+      elsif( VLAN_ID_IN = x"0000_0000" ) then
+        VALID_OUT <= '0';
+      elsif( (SAVED_VLAN_ID_IN = VLAN_ID_IN(15 downto 0)) or (SAVED_VLAN_ID_IN = VLAN_ID_IN(31 downto 16)) ) then
+        VALID_OUT <= '1';
+      else
+        VALID_OUT <= '0';
+      end if;
+    else
+      VALID_OUT <= '0';
+    end if;
+  end if;
+end process VALID_OUT_PROC;
+
+end gbe_type_validator_arch;
index 067febd7e101cef881c2b29050d606115f91f661..80837483f6ff466195922f733d75e346a3bbeaa4 100644 (file)
@@ -1,14 +1,9 @@
-library IEEE;
-use IEEE.std_logic_1164.all;
-use IEEE.std_logic_ARITH.all;
-use IEEE.std_logic_UNSIGNED.all;
+library ieee;
+  use ieee.std_logic_1164.all;
+  use ieee.numeric_std.all;
 
 library work;
-use work.trb_net_std.all;
-use work.trb_net_components.all;
-
---use work.trb_net_gbe_components.all;
-use work.gbe_protocols.all;
+  use work.gbe_protocols.all;
 
 entity gbe_wrapper_fifo is
   generic(
@@ -76,7 +71,7 @@ entity gbe_wrapper_fifo is
   );
 end entity gbe_wrapper_fifo;
 
-architecture RTL of gbe_wrapper_fifo is
+architecture gbe_wrapper_fifo_arch of gbe_wrapper_fifo is
 
   signal mac                        : std_logic_vector(47 downto 0);
 
@@ -125,7 +120,7 @@ begin
 
   -------------------------------------------------------------------------------------------------
   -- HACK: replace the borken internal FIFO by a ring buffer
-  THE_FRAME_TX: entity rx_rb 
+  THE_FRAME_TX: entity work.gbe_rx_rb 
   port map(
     CLK                 => CLK_125_IN,
     RESET               => RESET,
@@ -146,20 +141,19 @@ begin
   );
   -------------------------------------------------------------------------------------------------
 
-  -- debug(127 downto 64) are local
-  -- debug(63 downto 0) are media interface
+--  debug(127 downto 64) are local
+--  debug(63 downto 0) are media interface
 --  DEBUG_OUT <= monitor_gen_dbg(95 downto 64);
 
   mac <= MC_UNIQUE_ID_IN(15 downto 8) & MC_UNIQUE_ID_IN(23 downto 16) & MC_UNIQUE_ID_IN(31 downto 24) & x"0" & MC_UNIQUE_ID_IN(35 downto 32) & x"7ada";
 
-  MAKE_RESET_OUT <= '1' when  make_reset = '1' else '0';
-  
-  ISSUE_REBOOT_OUT <= '0' when issue_reboot = '0' else '1';
+  MAKE_RESET_OUT   <= '1' when make_reset = '1'   else '0';
+  ISSUE_REBOOT_OUT <= '1' when issue_reboot = '1' else '0';
 
-  STATUS_OUT(7 downto 1)  <= (others => '0');
-  STATUS_OUT(0)           <= dhcp_done; -- DHCP has completed
-  
-  gbe_inst : entity work.gbe_logic_wrapper
+  STATUS_OUT(7 downto 1) <= (others => '0');
+  STATUS_OUT(0)          <= dhcp_done;
+
+  THE_GBE_LOGIC_WRAPPER : entity work.gbe_logic_wrapper
   generic map(
     INCLUDE_SLOWCTRL         => LINK_HAS_SLOWCTRL,
     INCLUDE_DHCP             => LINK_HAS_DHCP,
@@ -231,10 +225,7 @@ begin
     DEBUG_OUT                => DEBUG_OUT --open
   );
 
-  -- sum_rx_*  ???
-  -- sum_tx_*  ???
-
-  NOSCTRL_MAP_GEN : if (LINK_HAS_SLOWCTRL = '0') generate
+  NOSCTRL_MAP_GEN : if( LINK_HAS_SLOWCTRL = '0' ) generate
     mlt_gsc_clk              <= '0';
     GSC_INIT_DATAREADY_OUT   <= '0';
     GSC_INIT_DATA_OUT        <= (others => '0');
@@ -247,7 +238,7 @@ begin
     mlt_gsc_busy             <= '0';
   end generate NOSCTRL_MAP_GEN;
 
-  SCTRL_MAP_GEN : if (LINK_HAS_SLOWCTRL = '1') generate
+  SCTRL_MAP_GEN : if( LINK_HAS_SLOWCTRL = '1' ) generate
     mlt_gsc_clk              <= GSC_CLK_IN;
     GSC_INIT_DATAREADY_OUT   <= mlt_gsc_init_dataready;
     GSC_INIT_DATA_OUT        <= mlt_gsc_init_data;
@@ -260,4 +251,4 @@ begin
     mlt_gsc_busy             <= GSC_BUSY_IN;
   end generate SCTRL_MAP_GEN;
 
-end architecture RTL;
+end architecture gbe_wrapper_fifo_arch;
old mode 100755 (executable)
new mode 100644 (file)
index 06ef0af188ba65cc496d97b052101ef360576de8..d9c424bbe23e27e2d7c33a7805c7daa1bfe930be 100644 (file)
@@ -1,10 +1,10 @@
 library ieee;\r
-use ieee.std_logic_1164.all;\r
-use ieee.numeric_std.all;\r
+  use ieee.std_logic_1164.all;\r
+  use ieee.numeric_std.all;\r
 \r
 library work;\r
 \r
-entity sgl_ctrl is\r
+entity gbe_sgl_ctrl is\r
   port(\r
     CLK                   : in  std_logic;\r
     RESET                 : in  std_logic;\r
@@ -32,9 +32,9 @@ entity sgl_ctrl is
     --\r
     DEBUG                 : out std_logic_vector(15 downto 0)\r
   );\r
-end entity sgl_ctrl;\r
+end entity gbe_sgl_ctrl;\r
 \r
-architecture sgl_ctrl_arch of sgl_ctrl is\r
+architecture gbe_sgl_ctrl_arch of gbe_sgl_ctrl is\r
 \r
 -- Components\r
 \r
@@ -187,6 +187,7 @@ begin
   end process THE_NEXT_PORT_PROC;\r
 \r
   -----------------------------------------------------------\r
+  -- Outputs\r
   -----------------------------------------------------------\r
   UL_FRAME_REQ_OUT      <= ul_frame_req;\r
   LOCAL_FRAME_REQ_OUT   <= local_frame_req;\r
@@ -347,4 +348,4 @@ begin
     end case;\r
   end process THE_STATE_TRANSITIONS;\r
 \r
-end architecture;\r
+end architecture gbe_sgl_ctrl_arch;\r
old mode 100755 (executable)
new mode 100644 (file)
old mode 100755 (executable)
new mode 100644 (file)
diff --git a/gbe_trb/protocols/gbe_response_constructor_ARP.vhd b/gbe_trb/protocols/gbe_response_constructor_ARP.vhd
new file mode 100644 (file)
index 0000000..eec56dc
--- /dev/null
@@ -0,0 +1,262 @@
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.gbe_protocols.all;
+
+entity gbe_response_constructor_ARP is
+port (
+  CLK                    : in  std_logic;  -- system clock
+  RESET                  : in  std_logic;
+-- INTERFACE  
+  MY_MAC_IN              : in  std_logic_vector(47 downto 0);
+  MY_IP_IN               : in  std_logic_vector(31 downto 0);
+  PS_DATA_IN             : in  std_logic_vector(8 downto 0);
+  PS_WR_EN_IN            : in  std_logic;
+  PS_ACTIVATE_IN         : in  std_logic;
+  PS_RESPONSE_READY_OUT  : out std_logic;
+  PS_BUSY_OUT            : out std_logic;
+  PS_SELECTED_IN         : in  std_logic;
+  PS_SRC_MAC_ADDRESS_IN  : in  std_logic_vector(47 downto 0);
+  PS_DEST_MAC_ADDRESS_IN : in  std_logic_vector(47 downto 0);
+  PS_SRC_IP_ADDRESS_IN   : in  std_logic_vector(31 downto 0);
+  PS_DEST_IP_ADDRESS_IN  : in  std_logic_vector(31 downto 0);
+  PS_SRC_UDP_PORT_IN     : in  std_logic_vector(15 downto 0);
+  PS_DEST_UDP_PORT_IN    : in  std_logic_vector(15 downto 0);
+--
+  TC_RD_EN_IN            : in  std_logic;
+  TC_DATA_OUT            : out std_logic_vector(8 downto 0);
+  TC_FRAME_SIZE_OUT      : out std_logic_vector(15 downto 0);
+  TC_FRAME_TYPE_OUT      : out std_logic_vector(15 downto 0);
+  TC_IP_PROTOCOL_OUT     : out std_logic_vector(7 downto 0);  
+  TC_IDENT_OUT           : out std_logic_vector(15 downto 0);  
+  TC_DEST_MAC_OUT        : out std_logic_vector(47 downto 0);
+  TC_DEST_IP_OUT         : out std_logic_vector(31 downto 0);
+  TC_DEST_UDP_OUT        : out std_logic_vector(15 downto 0);
+  TC_SRC_MAC_OUT         : out std_logic_vector(47 downto 0);
+  TC_SRC_IP_OUT          : out std_logic_vector(31 downto 0);
+  TC_SRC_UDP_OUT         : out std_logic_vector(15 downto 0);
+-- END OF INTERFACE
+-- debug
+  DEBUG_OUT              : out std_logic_vector(63 downto 0)
+);
+end gbe_response_constructor_ARP;
+
+architecture gbe_response_constructor_ARP_arch of gbe_response_constructor_ARP is
+
+attribute syn_encoding  : string;
+
+type dissect_states is (IDLE, READ_FRAME, DECIDE, LOAD_FRAME, WAIT_FOR_LOAD, CLEANUP);
+signal dissect_current_state, dissect_next_state : dissect_states;
+attribute syn_encoding of dissect_current_state: signal is "onehot";
+
+type stats_states is (IDLE, LOAD_SENT, LOAD_RECEIVED, CLEANUP);
+signal stats_current_state, stats_next_state : stats_states;
+attribute syn_encoding of stats_current_state : signal is "onehot";
+
+signal saved_opcode             : std_logic_vector(15 downto 0);
+signal saved_sender_ip          : std_logic_vector(31 downto 0);
+signal saved_target_ip          : std_logic_vector(31 downto 0);
+signal data_ctr                 : integer range 0 to 30;
+signal values                   : std_logic_vector(223 downto 0);
+signal tc_data                  : std_logic_vector(8 downto 0);
+
+signal state                    : std_logic_vector(3 downto 0);
+signal rec_frames               : std_logic_vector(15 downto 0);
+signal sent_frames              : std_logic_vector(15 downto 0);
+signal stat_data_temp           : std_logic_vector(31 downto 0);
+
+signal tc_wr                    : std_logic;
+
+attribute syn_preserve : boolean;
+attribute syn_keep : boolean;
+attribute syn_keep of state : signal is true;
+attribute syn_preserve of state : signal is true;
+
+begin
+
+values(15 downto 0)    <= x"0100";  -- hardware type
+values(31 downto 16)   <= x"0008";  -- protocol type
+values(39 downto 32)   <= x"06";  -- hardware size
+values(47 downto 40)   <= x"04";  -- protocol size
+values(63 downto 48)   <= x"0200"; --opcode (reply)
+values(111 downto 64)  <= MY_MAC_IN;  -- sender (my) mac
+values(143 downto 112) <= MY_IP_IN;
+values(191 downto 144) <= PS_SRC_MAC_ADDRESS_IN;  -- target mac
+values(223 downto 192) <= saved_sender_ip;  -- target ip
+
+DISSECT_MACHINE_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    dissect_current_state <= IDLE;
+  elsif( rising_edge(CLK) ) then
+    dissect_current_state <= dissect_next_state;
+  end if;
+end process DISSECT_MACHINE_PROC;
+
+DISSECT_MACHINE : process(dissect_current_state, MY_IP_IN, PS_WR_EN_IN, PS_ACTIVATE_IN, PS_DATA_IN, data_ctr, PS_SELECTED_IN, saved_target_ip)
+begin
+  case dissect_current_state is
+  
+    when IDLE =>
+      state <= x"1";
+      if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then
+        dissect_next_state <= READ_FRAME;
+      else
+        dissect_next_state <= IDLE;
+      end if;
+    
+    when READ_FRAME =>
+      state <= x"2";
+      if (PS_DATA_IN(8) = '1') then
+        dissect_next_state <= DECIDE;
+      else
+        dissect_next_state <= READ_FRAME;
+      end if;
+      
+    when DECIDE =>
+      state <= x"3";
+      if (saved_target_ip = MY_IP_IN) then
+        dissect_next_state <= WAIT_FOR_LOAD;
+      -- in case the request is not for me, drop it
+      else
+        dissect_next_state <= IDLE;
+      end if;
+      
+    when WAIT_FOR_LOAD =>
+      state <= x"4";
+      if (PS_SELECTED_IN = '1') then
+        dissect_next_state <= LOAD_FRAME;
+      else
+        dissect_next_state <= WAIT_FOR_LOAD;
+      end if;
+    
+    when LOAD_FRAME =>
+      state <= x"5";
+      if (data_ctr = 28) then
+        dissect_next_state <= CLEANUP;
+      else
+        dissect_next_state <= LOAD_FRAME;
+      end if;
+    
+    when CLEANUP =>
+      state <= x"e";
+      dissect_next_state <= IDLE;
+  
+  end case;
+end process DISSECT_MACHINE;
+
+DATA_CTR_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    data_ctr <= 1;
+  elsif( rising_edge(CLK) ) then
+    if   ( (dissect_current_state = IDLE) and (PS_WR_EN_IN = '0') ) then
+      data_ctr <= 1;
+    elsif( dissect_current_state = WAIT_FOR_LOAD ) then
+      data_ctr <= 1;
+    elsif( dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then
+      data_ctr <= data_ctr + 1;
+    elsif( dissect_current_state = READ_FRAME and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then  -- in case of saving data from incoming frame
+      data_ctr <= data_ctr + 1;
+    elsif( dissect_current_state = LOAD_FRAME and PS_SELECTED_IN = '1' and TC_RD_EN_IN = '1' ) then  -- in case of constructing response
+      data_ctr <= data_ctr + 1;
+    end if;
+  end if;
+end process DATA_CTR_PROC;
+
+SAVE_VALUES_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    saved_opcode    <= (others => '0');
+    saved_sender_ip <= (others => '0');
+    saved_target_ip <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if (dissect_current_state = READ_FRAME) then
+      case (data_ctr) is
+        
+        when 6 =>
+          saved_opcode(7 downto 0)      <= PS_DATA_IN(7 downto 0);
+        when 7 =>
+          saved_opcode(15 downto 8)     <= PS_DATA_IN(7 downto 0);
+        when 13 =>
+          saved_sender_ip(7 downto 0)   <= PS_DATA_IN(7 downto 0);
+        when 14 =>
+          saved_sender_ip(15 downto 8)  <= PS_DATA_IN(7 downto 0);
+        when 15 =>
+          saved_sender_ip(23 downto 16) <= PS_DATA_IN(7 downto 0);
+        when 16 =>
+          saved_sender_ip(31 downto 24) <= PS_DATA_IN(7 downto 0);
+        when 23 =>
+          saved_target_ip(7 downto 0)   <= PS_DATA_IN(7 downto 0);
+        when 24 =>
+          saved_target_ip(15 downto 8)  <= PS_DATA_IN(7 downto 0);
+        when 25 =>
+          saved_target_ip(23 downto 16) <= PS_DATA_IN(7 downto 0);
+        when 26 =>
+          saved_target_ip(31 downto 24) <= PS_DATA_IN(7 downto 0);
+          
+        when others => null;
+      end case;
+    end if;
+  end if;
+end process SAVE_VALUES_PROC;
+
+TC_DATA_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    tc_data(8) <= '0';
+    
+    if (dissect_current_state = LOAD_FRAME) then
+      for i in 0 to 7 loop
+        tc_data(i) <= values((data_ctr - 1) * 8 + i);
+      end loop;
+      -- mark the last byte
+      if (data_ctr = 28) then
+        tc_data(8) <= '1';
+      end if;
+    else
+      tc_data(7 downto 0) <= (others => '0');  
+    end if;
+    
+    TC_DATA_OUT <= tc_data;
+    
+  end if;  
+end process TC_DATA_PROC;
+
+PS_RESPONSE_SYNC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( dissect_current_state = WAIT_FOR_LOAD or dissect_current_state = LOAD_FRAME or dissect_current_state = CLEANUP ) then
+      PS_RESPONSE_READY_OUT <= '1';
+    else
+      PS_RESPONSE_READY_OUT <= '0';
+    end if;
+    
+    if( dissect_current_state = IDLE ) then
+      PS_BUSY_OUT <= '0';
+    else
+      PS_BUSY_OUT <= '1';
+    end if;
+  end if;  
+end process PS_RESPONSE_SYNC;
+
+TC_FRAME_SIZE_OUT   <= x"001c";  -- fixed frame size
+
+TC_FRAME_TYPE_OUT   <= x"0608";
+TC_DEST_MAC_OUT     <= PS_SRC_MAC_ADDRESS_IN;
+TC_DEST_IP_OUT      <= x"00000000";  -- doesnt matter
+TC_DEST_UDP_OUT     <= x"0000";  -- doesnt matter
+TC_SRC_MAC_OUT      <= MY_MAC_IN;
+TC_SRC_IP_OUT       <= x"00000000";  -- doesnt matter
+TC_SRC_UDP_OUT      <= x"0000";  -- doesnt matter
+TC_IP_PROTOCOL_OUT  <= x"00"; -- doesnt matter
+TC_IDENT_OUT        <= (others => '0');  -- doesn't matter
+
+end gbe_response_constructor_ARP_arch;
+
+
diff --git a/gbe_trb/protocols/gbe_response_constructor_DHCP.vhd b/gbe_trb/protocols/gbe_response_constructor_DHCP.vhd
new file mode 100644 (file)
index 0000000..52c6df6
--- /dev/null
@@ -0,0 +1,699 @@
+LIBRARY IEEE;
+
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.trb_net_gbe_protocols.all;
+
+entity gbe_response_constructor_DHCP is
+port(
+  CLK                    : in  std_logic;  -- system clock
+  RESET                  : in  std_logic;
+-- INTERFACE
+  MY_MAC_IN              : in  std_logic_vector(47 downto 0);
+  MY_IP_IN               : in  std_logic_vector(31 downto 0);
+  PS_DATA_IN             : in  std_logic_vector(8 downto 0);
+  PS_WR_EN_IN            : in  std_logic;
+  PS_ACTIVATE_IN         : in  std_logic;
+  PS_RESPONSE_READY_OUT  : out std_logic;
+  PS_BUSY_OUT            : out std_logic;
+  PS_SELECTED_IN         : in  std_logic;
+  PS_SRC_MAC_ADDRESS_IN  : in  std_logic_vector(47 downto 0);
+  PS_DEST_MAC_ADDRESS_IN : in  std_logic_vector(47 downto 0);
+  PS_SRC_IP_ADDRESS_IN   : in  std_logic_vector(31 downto 0);
+  PS_DEST_IP_ADDRESS_IN  : in  std_logic_vector(31 downto 0);
+  PS_SRC_UDP_PORT_IN     : in  std_logic_vector(15 downto 0);
+  PS_DEST_UDP_PORT_IN    : in  std_logic_vector(15 downto 0);
+--
+  TC_RD_EN_IN            : in  std_logic;
+  TC_DATA_OUT            : out std_logic_vector(8 downto 0);
+  TC_FRAME_SIZE_OUT      : out std_logic_vector(15 downto 0);
+  TC_FRAME_TYPE_OUT      : out std_logic_vector(15 downto 0);
+  TC_IP_PROTOCOL_OUT     : out std_logic_vector(7 downto 0);  
+  TC_IDENT_OUT           : out std_logic_vector(15 downto 0);  
+  TC_DEST_MAC_OUT        : out std_logic_vector(47 downto 0);
+  TC_DEST_IP_OUT         : out std_logic_vector(31 downto 0);
+  TC_DEST_UDP_OUT        : out std_logic_vector(15 downto 0);
+  TC_SRC_MAC_OUT         : out std_logic_vector(47 downto 0);
+  TC_SRC_IP_OUT          : out std_logic_vector(31 downto 0);
+  TC_SRC_UDP_OUT         : out std_logic_vector(15 downto 0);
+-- END OF INTERFACE
+  MY_IP_OUT              : out std_logic_vector(31 downto 0);
+  DHCP_START_IN          : in  std_logic;
+  DHCP_DONE_OUT          : out std_logic;
+-- debug
+  DEBUG_OUT              : out  std_logic_vector(63 downto 0)
+);
+end gbe_response_constructor_DHCP;
+
+
+architecture gbe_response_constructor_DHCP_arch of gbe_response_constructor_DHCP is
+
+attribute syn_encoding  : string;
+
+type main_states is (BOOTING, DELAY, SENDING_DISCOVER, WAITING_FOR_OFFER, SENDING_REQUEST, WAITING_FOR_ACK, ESTABLISHED);
+signal main_current_state, main_next_state : main_states;
+attribute syn_encoding of main_current_state: signal is "onehot";
+
+type receive_states is (IDLE, DISCARD, CLEANUP, SAVE_VALUES);
+signal receive_current_state, receive_next_state : receive_states;
+attribute syn_encoding of receive_current_state: signal is "onehot";
+
+type discover_states is (IDLE, WAIT_FOR_LOAD, BOOTP_HEADERS, CLIENT_IP, YOUR_IP, ZEROS1, MY_MAC, ZEROS2, VENDOR_VALS, VENDOR_VALS2, TERMINATION, CLEANUP);
+signal construct_current_state, construct_next_state : discover_states;
+attribute syn_encoding of construct_current_state: signal is "onehot";
+
+type stats_states is (IDLE, LOAD_SENT, LOAD_RECEIVED, LOAD_DISCARDED, CLEANUP);
+signal stats_current_state, stats_next_state : stats_states;
+attribute syn_encoding of stats_current_state : signal is "onehot";
+
+signal state                    : std_logic_vector(3 downto 0);
+signal rec_frames               : std_logic_vector(15 downto 0);
+signal sent_frames              : std_logic_vector(15 downto 0);
+
+signal wait_ctr                 : std_logic_vector(31 downto 0);  -- wait for 5 sec before sending request
+signal load_ctr                 : integer range 0 to 600 := 0;
+
+signal bootp_hdr                : std_logic_vector(95 downto 0);
+
+signal tc_data                  : std_logic_vector(8 downto 0);
+signal vendor_values            : std_logic_vector(175 downto 0);
+signal save_ctr                 : integer range 0 to 600 := 0;
+signal saved_transaction_id     : std_logic_vector(31 downto 0);
+signal saved_proposed_ip        : std_logic_vector(31 downto 0);
+signal saved_dhcp_type          : std_logic_vector(23 downto 0);
+signal saved_true_ip            : std_logic_vector(31 downto 0);
+signal transaction_id           : std_logic_vector(31 downto 0);
+signal client_ip_reg            : std_logic_vector(31 downto 0);
+signal your_ip_reg              : std_logic_vector(31 downto 0);
+signal saved_server_mac         : std_logic_vector(47 downto 0);
+signal saved_server_ip          : std_logic_vector(31 downto 0);
+signal state2                   : std_logic_vector(3 downto 0);
+signal state3                   : std_logic_vector(3 downto 0);
+signal vendor_values2           : std_logic_vector(47 downto 0);
+
+signal discarded_ctr            : std_logic_vector(15 downto 0);
+
+signal stat_data_temp           : std_logic_vector(31 downto 0);
+
+attribute syn_preserve : boolean;
+attribute syn_keep : boolean;
+attribute syn_keep of state, state2 : signal is true;
+attribute syn_preserve of state, state2 : signal is true;
+
+signal wait_value : std_logic_vector(31 downto 0);
+
+signal my_ip : std_logic_vector(31 downto 0);
+
+begin
+
+-- ****
+-- fixing the constant values for DHCP request headers
+TC_DEST_MAC_OUT               <= x"ffffffffffff" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else saved_server_mac;
+TC_DEST_IP_OUT                <= x"ffffffff" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else saved_server_ip;
+TC_DEST_UDP_OUT               <= x"4300";
+TC_SRC_MAC_OUT                <= MY_MAC_IN;
+TC_SRC_IP_OUT                 <= x"00000000" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else saved_proposed_ip;
+TC_SRC_UDP_OUT                <= x"4400";
+TC_IP_PROTOCOL_OUT            <= x"11"; -- udp
+bootp_hdr(7 downto 0)         <= x"01";  -- message type(request)
+bootp_hdr(15 downto 8)        <= x"01";  -- hardware type (eth)
+bootp_hdr(23 downto 16)       <= x"06";  -- hardware address length
+bootp_hdr(31 downto 24)       <= x"00";  -- hops
+bootp_hdr(63 downto 32)       <= transaction_id;  -- transaction id;
+bootp_hdr(95 downto 64)       <= x"0000_0000";  -- seconds elapsed/flags
+transaction_id                <= x"cefa" & MY_MAC_IN(47 downto 40) & MY_MAC_IN(23 downto 16);
+vendor_values(31 downto 0)    <= x"63538263"; -- magic cookie (dhcp message)
+vendor_values(55 downto 32)   <= x"010135" when (main_current_state = BOOTING or main_current_state = SENDING_DISCOVER) else x"030135"; -- dhcp discover, then dhcp request
+vendor_values(79 downto 56)   <= x"01073d"; -- client identifier
+vendor_values(127 downto 80)  <= MY_MAC_IN;  -- client identifier
+vendor_values(143 downto 128) <= x"040c";  -- client name
+--vendor_values(175 downto 144) <= x"33425254";  -- client name (TRB3)
+vendor_values(175 downto 144) <= x"6f72694b";  -- client name (Kiro)
+vendor_values2(15 downto 0)   <= x"0436";  -- server identifier
+vendor_values2(47 downto 16)  <= saved_server_ip;
+
+--*****************
+-- setting of global variable for IP address
+my_ip <= saved_true_ip when main_current_state = ESTABLISHED else (others => '0');
+MY_IP_OUT <= my_ip;
+--
+--*****************
+
+SAVE_SERVER_ADDR_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( main_current_state = BOOTING ) then
+      saved_server_mac <= (others => '0');
+      saved_server_ip  <= (others => '0');
+    elsif( (main_current_state = WAITING_FOR_OFFER) and (receive_current_state = SAVE_VALUES and save_ctr = 1) ) then
+      saved_server_mac <= PS_SRC_MAC_ADDRESS_IN;
+      saved_server_ip  <= PS_SRC_IP_ADDRESS_IN;
+    end if;
+  end if;
+end process SAVE_SERVER_ADDR_PROC;
+
+
+-- **** MAIN MACHINE PART
+
+MAIN_MACHINE_PROC: process( CLK, RESET)
+begin
+  if   ( RESET = '1' ) then
+    main_current_state <= BOOTING;
+  elsif( rising_edge(CLK) ) then
+    main_current_state <= main_next_state;
+  end if;
+end process MAIN_MACHINE_PROC;
+
+wait_value <= x"2000_0000";
+
+MAIN_MACHINE : process(main_current_state, DHCP_START_IN, construct_current_state, wait_ctr, receive_current_state, PS_DATA_IN, wait_value)
+begin
+  state2 <= x"0";
+
+  case (main_current_state) is
+  
+    when BOOTING =>
+      state2 <= x"1";
+      if (DHCP_START_IN = '1') then
+        main_next_state <= DELAY;
+      else
+        main_next_state <= BOOTING;
+      end if;
+      
+    when DELAY =>
+      state2 <= x"2";
+      if (wait_ctr = wait_value) then
+        main_next_state <= SENDING_DISCOVER;
+      else
+        main_next_state <= DELAY;
+      end if;
+    
+    when SENDING_DISCOVER =>
+      state2 <= x"3";
+      if (construct_current_state = CLEANUP) then
+        main_next_state <= WAITING_FOR_OFFER;
+      else
+        main_next_state <= SENDING_DISCOVER;
+      end if;
+    
+    when WAITING_FOR_OFFER =>
+      state2 <= x"4"; 
+      if (receive_current_state = SAVE_VALUES) and (PS_DATA_IN(8) = '1') then
+        main_next_state <= SENDING_REQUEST;
+      elsif (wait_ctr = x"2000_0000") then
+        main_next_state <= BOOTING;
+      else
+        main_next_state <= WAITING_FOR_OFFER;
+      end if;
+    
+    when SENDING_REQUEST =>
+      state2 <= x"5";
+      if (construct_current_state = CLEANUP) then
+        main_next_state <= WAITING_FOR_ACK;
+      else
+        main_next_state <= SENDING_REQUEST;
+      end if;
+    
+    when WAITING_FOR_ACK =>
+      state2 <= x"6";
+      if (receive_current_state = SAVE_VALUES) and (PS_DATA_IN(8) = '1') then
+        main_next_state <= ESTABLISHED;
+      elsif (wait_ctr = x"2000_0000") then
+        main_next_state <= BOOTING;
+      else
+        main_next_state <= WAITING_FOR_ACK;
+      end if;
+    
+    when ESTABLISHED =>
+      state2 <= x"7";
+        main_next_state <= ESTABLISHED;
+
+    when others => main_next_state <= BOOTING;
+  
+  end case;
+
+end process MAIN_MACHINE;
+
+WAIT_CTR_PROC : process(CLK)
+begin
+  if rising_edge(CLK) then
+    if (main_current_state = SENDING_DISCOVER or main_current_state = SENDING_REQUEST or main_current_state = BOOTING) then
+      wait_ctr <= (others => '0');
+    elsif (main_current_state = WAITING_FOR_ACK and receive_current_state = SAVE_VALUES and PS_DATA_IN(8) = '1') then
+      wait_ctr <= (others => '0');
+    elsif (main_current_state = WAITING_FOR_ACK or main_current_state = WAITING_FOR_OFFER or main_current_state = DELAY or main_current_state = ESTABLISHED) then
+      wait_ctr <= wait_ctr + x"1";
+    else
+      wait_ctr <= wait_ctr;
+    end if;
+  end if;
+end process WAIT_CTR_PROC;
+
+DHCP_DONE_OUT <= '1' when main_current_state = ESTABLISHED else '0';
+
+
+-- **** MESSAGES RECEIVING PART
+
+RECEIVE_MACHINE_PROC : process(RESET, CLK)
+begin
+  if RESET = '1' then
+    receive_current_state <= IDLE;
+  elsif rising_edge(CLK) then
+    receive_current_state <= receive_next_state;
+  end if;
+end process RECEIVE_MACHINE_PROC;
+
+RECEIVE_MACHINE : process(receive_current_state, main_current_state, bootp_hdr, saved_dhcp_type, saved_transaction_id, PS_DATA_IN, PS_DEST_MAC_ADDRESS_IN, MY_MAC_IN, PS_ACTIVATE_IN, PS_WR_EN_IN, save_ctr)
+begin
+  state3 <= x"0";
+  
+  case receive_current_state is
+  
+    when IDLE =>
+      state3 <= x"1";
+      if (PS_ACTIVATE_IN = '1' and PS_WR_EN_IN = '1') then
+        if (main_current_state = WAITING_FOR_OFFER or main_current_state = WAITING_FOR_ACK) then  -- ready to receive dhcp frame
+          if (PS_DEST_MAC_ADDRESS_IN = MY_MAC_IN) then -- check if i'm the addressee (discards broadcasts also)
+            receive_next_state <= SAVE_VALUES;
+          else
+            receive_next_state <= DISCARD;  -- discard if the frame is not for me
+          end if;
+        else
+          receive_next_state <= DISCARD;  -- discard if the frame arrived at wrong time
+        end if;
+      else
+        receive_next_state <= IDLE;
+      end if;
+      
+    when SAVE_VALUES =>
+      state3 <= x"2";
+      if (PS_DATA_IN(8) = '1') then
+        receive_next_state <= CLEANUP;
+      -- check if the same transaction
+      elsif (save_ctr = 9) and (saved_transaction_id /= bootp_hdr(63 downto 32)) then
+        receive_next_state <= DISCARD;
+      -- if the wrong message at the wrong time
+      elsif (main_current_state = WAITING_FOR_OFFER) and (save_ctr = 242) and (saved_dhcp_type /= x"020135") then
+        receive_next_state <= DISCARD;
+      -- if the wrong message at the wrong time
+      elsif (main_current_state = WAITING_FOR_ACK) and (save_ctr = 242) and (saved_dhcp_type /= x"050135") then
+        receive_next_state <= DISCARD;
+      else
+        receive_next_state <= SAVE_VALUES;
+      end if;
+    
+    when DISCARD =>
+      state3 <= x"3";
+      if (PS_DATA_IN(8) = '1') then
+        receive_next_state <= CLEANUP;
+      else
+        receive_next_state <= DISCARD;
+      end if;
+      
+    when CLEANUP =>
+      state3 <= x"4";
+      receive_next_state <= IDLE;
+      
+    when others => receive_next_state <= IDLE;
+  
+  end case;
+
+end process RECEIVE_MACHINE;
+
+SAVE_CTR_PROC : process(CLK)
+begin
+  if rising_edge(CLK) then
+    if (receive_current_state = IDLE) then
+      save_ctr <= 0;
+    elsif (receive_current_state = SAVE_VALUES and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then
+      save_ctr <= save_ctr + 1;
+    else
+      save_ctr <= save_ctr;
+    end if;
+  end if;
+end process SAVE_CTR_PROC;
+
+SAVE_VALUES_PROC : process(CLK)
+begin
+  if rising_edge(CLK) then
+    if (main_current_state = BOOTING) then
+      saved_transaction_id <= (others => '0');
+      saved_proposed_ip    <= (others => '0');
+      saved_true_ip        <= (others => '0');
+      saved_dhcp_type      <= (others => '0');
+    -- dissection of DHCP Offer message
+    elsif (main_current_state = WAITING_FOR_OFFER and receive_current_state = SAVE_VALUES) then
+    
+      saved_true_ip <= saved_true_ip;
+    
+      case save_ctr is
+      
+        when 3 =>
+          saved_transaction_id(7 downto 0) <= PS_DATA_IN(7 downto 0);
+        
+        when 4 =>
+          saved_transaction_id(15 downto 8) <= PS_DATA_IN(7 downto 0);
+      
+        when 5 =>
+          saved_transaction_id(23 downto 16) <= PS_DATA_IN(7 downto 0);
+          
+        when 6 =>
+          saved_transaction_id(31 downto 24) <= PS_DATA_IN(7 downto 0);
+          
+          
+        when 15 =>
+          saved_proposed_ip(7 downto 0) <= PS_DATA_IN(7 downto 0);
+        
+        when 16 =>
+          saved_proposed_ip(15 downto 8) <= PS_DATA_IN(7 downto 0);
+          
+        when 17 =>
+          saved_proposed_ip(23 downto 16) <= PS_DATA_IN(7 downto 0);
+          
+        when 18 =>
+          saved_proposed_ip(31 downto 24) <= PS_DATA_IN(7 downto 0);
+          
+          
+        when 239 =>
+          saved_dhcp_type(7 downto 0) <= PS_DATA_IN(7 downto 0);
+          
+        when 240 =>
+          saved_dhcp_type(15 downto 8) <= PS_DATA_IN(7 downto 0);
+          
+        when 241 =>
+          saved_dhcp_type(23 downto 16) <= PS_DATA_IN(7 downto 0);
+          
+        when others => null;
+          
+      end case;
+    -- dissection on DHCP Ack message
+    elsif (main_current_state = WAITING_FOR_ACK and receive_current_state = SAVE_VALUES) then
+    
+      saved_proposed_ip <= saved_proposed_ip;
+    
+      case save_ctr is
+      
+        when 3 =>
+          saved_transaction_id(7 downto 0) <= PS_DATA_IN(7 downto 0);
+        
+        when 4 =>
+          saved_transaction_id(15 downto 8) <= PS_DATA_IN(7 downto 0);
+      
+        when 5 =>
+          saved_transaction_id(23 downto 16) <= PS_DATA_IN(7 downto 0);
+          
+        when 6 =>
+          saved_transaction_id(31 downto 24) <= PS_DATA_IN(7 downto 0);
+          
+          
+        when 15 =>
+          saved_true_ip(7 downto 0) <= PS_DATA_IN(7 downto 0);
+        
+        when 16 =>
+          saved_true_ip(15 downto 8) <= PS_DATA_IN(7 downto 0);
+          
+        when 17 =>
+          saved_true_ip(23 downto 16) <= PS_DATA_IN(7 downto 0);
+          
+        when 18 =>
+          saved_true_ip(31 downto 24) <= PS_DATA_IN(7 downto 0);
+          
+          
+        when 239 =>
+          saved_dhcp_type(7 downto 0) <= PS_DATA_IN(7 downto 0);
+          
+        when 240 =>
+          saved_dhcp_type(15 downto 8) <= PS_DATA_IN(7 downto 0);
+          
+        when 241 =>
+          saved_dhcp_type(23 downto 16) <= PS_DATA_IN(7 downto 0);
+          
+        when others => null;
+          
+      end case;    
+    else
+      saved_transaction_id <= saved_transaction_id;
+      saved_proposed_ip    <= saved_proposed_ip;
+      saved_true_ip        <= saved_true_ip;
+      saved_dhcp_type      <= saved_dhcp_type;    
+    end if;
+  end if;
+end process SAVE_VALUES_PROC;
+
+
+-- **** MESSAGES CONSTRUCTING PART
+
+CONSTRUCT_MACHINE_PROC : process(RESET, CLK)
+begin
+  if RESET = '1' then
+      construct_current_state <= IDLE;
+  elsif rising_edge(CLK) then
+    if (main_current_state = BOOTING) then
+      construct_current_state <= IDLE;
+    else
+      construct_current_state <= construct_next_state;
+    end if;
+  end if;
+end process CONSTRUCT_MACHINE_PROC;
+
+CONSTRUCT_MACHINE : process(construct_current_state, main_current_state, load_ctr, PS_SELECTED_IN)
+begin
+  state <= x"0";
+  
+  case construct_current_state is
+  
+    when IDLE =>
+      state <= x"1";
+      if (main_current_state = SENDING_DISCOVER) or (main_current_state = SENDING_REQUEST) then
+        construct_next_state <= WAIT_FOR_LOAD;
+      else
+        construct_next_state <= IDLE;
+      end if;
+      
+    when WAIT_FOR_LOAD =>
+      state <= x"2";
+      if (PS_SELECTED_IN = '1') then
+        construct_next_state <= BOOTP_HEADERS;
+      else
+        construct_next_state <= WAIT_FOR_LOAD;
+      end if;
+    
+      
+    when BOOTP_HEADERS =>
+      state <= x"3";
+      if (load_ctr = 11) then
+        construct_next_state <= CLIENT_IP;
+      else
+        construct_next_state <= BOOTP_HEADERS;
+      end if;
+      
+    when CLIENT_IP =>
+      state <= x"4";
+      if (load_ctr = 15) then
+        construct_next_state <= YOUR_IP;
+      else
+        construct_next_state <= CLIENT_IP;
+      end if;
+      
+    when YOUR_IP => 
+      state <= x"5";
+      if (load_ctr = 19) then
+        construct_next_state <= ZEROS1;
+      else
+        construct_next_state <= YOUR_IP;
+      end if;
+      
+    when ZEROS1 =>
+      state <= x"6";
+      if (load_ctr = 27) then
+        construct_next_state <= MY_MAC;
+      else
+        construct_next_state <= ZEROS1;
+      end if;
+    
+    when MY_MAC =>
+      state <= x"7";
+      if (load_ctr = 33) then
+        construct_next_state <= ZEROS2;
+      else
+        construct_next_state <= MY_MAC;
+      end if;
+    
+    when ZEROS2 =>
+      state <= x"8";
+      if (load_ctr = 235) then
+        construct_next_state <= VENDOR_VALS;
+      else
+        construct_next_state <= ZEROS2;
+      end if;
+      
+    when VENDOR_VALS =>
+      state <= x"9";
+      if (load_ctr = 257) then
+        -- for discover it's enough of values
+        if (main_current_state = SENDING_DISCOVER) then
+          construct_next_state <= TERMINATION;
+        -- for request there is some more values needed
+        else
+          construct_next_state <= VENDOR_VALS2;
+        end if;
+      else
+        construct_next_state <= VENDOR_VALS;
+      end if;
+      
+    when VENDOR_VALS2 =>
+      state <= x"a";
+      if (load_ctr = 263) then
+        construct_next_state <= TERMINATION;
+      else
+        construct_next_state <= VENDOR_VALS2;
+      end if;
+      
+    when TERMINATION =>
+      state <= x"b";
+      construct_next_state <= CLEANUP;
+    
+    when CLEANUP =>
+      state <= x"c";
+      construct_next_state <= IDLE;
+      
+    when others => construct_next_state <= IDLE;
+  
+  end case;
+end process CONSTRUCT_MACHINE;
+
+LOAD_CTR_PROC : process(CLK)
+begin
+  if rising_edge(CLK) then
+    if (construct_current_state = IDLE) then
+      load_ctr <= 0;
+    elsif (TC_RD_EN_IN = '1') and (PS_SELECTED_IN = '1') then
+      load_ctr <= load_ctr + 1;
+    else
+      load_ctr <= load_ctr;
+    end if;
+  end if;
+end process LOAD_CTR_PROC;
+
+TC_DATA_PROC : process(CLK)
+begin
+  if rising_edge(CLK) then
+    case (construct_current_state) is
+  
+      when BOOTP_HEADERS =>
+        for i in 0 to 7 loop
+          tc_data(i) <= bootp_hdr(load_ctr * 8 + i);
+        end loop;
+        tc_data(8) <= '0';
+        
+      when CLIENT_IP =>
+        if (main_current_state = SENDING_DISCOVER) then
+          tc_data(7 downto 0) <= x"00";
+        elsif (main_current_state = SENDING_REQUEST) then
+          for i in 0 to 7 loop
+            tc_data(i) <= saved_proposed_ip((load_ctr - 12) * 8 + i);
+          end loop;
+        end if;
+        tc_data(8) <= '0';
+      
+      when YOUR_IP =>
+        tc_data(7 downto 0) <= x"00";
+        tc_data(8) <= '0';
+      
+      when ZEROS1 =>
+        tc_data(7 downto 0) <= x"00";
+        tc_data(8) <= '0';
+      
+      when MY_MAC =>
+        for i in 0 to 7 loop
+          tc_data(i) <= MY_MAC_IN((load_ctr - 28) * 8 + i);
+        end loop;
+        tc_data(8) <= '0';
+      
+      when ZEROS2 =>
+        tc_data(7 downto 0) <= x"00";
+        tc_data(8) <= '0';
+        
+      when VENDOR_VALS =>
+        for i in 0 to 7 loop
+          tc_data(i) <= vendor_values((load_ctr - 236) * 8 + i);
+        end loop;
+        tc_data(8) <= '0';
+        
+      -- needed only for DHCP Request message
+      when VENDOR_VALS2 =>
+        for i in 0 to 7 loop
+          tc_data(i) <= vendor_values2((load_ctr - 258) * 8 + i);
+        end loop;
+        tc_data(8) <= '0';
+        
+      when TERMINATION =>
+        tc_data(7 downto 0) <= x"ff";
+        tc_data(8)          <= '1';
+      
+      when others => 
+        tc_data(7 downto 0) <= x"00";
+        tc_data(8) <= '0';
+    
+    end case;
+
+    TC_DATA_OUT  <= tc_data;
+        
+  end if;
+end process;
+
+PS_RESPONSE_SYNC : process( CLK )
+begin
+  if rising_edge(CLK) then
+    if (construct_current_state = IDLE or construct_current_state = CLEANUP) then
+      PS_RESPONSE_READY_OUT <= '0';
+    else
+      PS_RESPONSE_READY_OUT <= '1';
+    end if;
+    
+    if (construct_current_state = IDLE) then
+      PS_BUSY_OUT <= '0';
+    else
+      PS_BUSY_OUT <= '1';
+    end if;
+  end if;  
+end process PS_RESPONSE_SYNC;
+
+-- fixed sizes for discover and request messages
+TC_FRAME_SIZE_OUT   <= x"0103" when (main_current_state = SENDING_DISCOVER) else x"0109";
+
+TC_FRAME_TYPE_OUT   <= x"0008";  -- frame type: ip
+
+TC_IDENT_OUT        <= x"1" & sent_frames(11 downto 0);
+
+SENT_FRAMES_PROC : process( CLK )
+begin
+  if rising_edge(CLK) then
+    if (RESET = '1') then
+      sent_frames <= (others => '0');
+    elsif (construct_current_state = CLEANUP) then
+      sent_frames <= sent_frames + x"1";
+    end if;
+  end if;
+end process SENT_FRAMES_PROC;
+
+-- **** debug
+process( CLK )
+begin
+  if rising_edge(CLK) then
+    DEBUG_OUT(3 downto 0)   <= state;
+    DEBUG_OUT(7 downto 4)   <= state2;
+    DEBUG_OUT(11 downto 8)  <= state3;
+  end if;
+end process;
+
+-- ****
+
+end gbe_response_constructor_DHCP_arch;
+
+
diff --git a/gbe_trb/protocols/gbe_response_constructor_Forward.vhd b/gbe_trb/protocols/gbe_response_constructor_Forward.vhd
new file mode 100644 (file)
index 0000000..75cf84f
--- /dev/null
@@ -0,0 +1,254 @@
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+
+-- WARNING: data latency was wrong by one cycle (first byte not sent, last byte duplicated), and
+--          size was calculated wrong (one off). Works now FOR ME. To be tested carefully!
+
+-- BUG: If a frame written triggers FIFOFULL, it must be discarded. Maximum frame payload is 4096bytes.
+
+entity gbe_response_constructor_Forward is
+  port (
+    CLK                     : in  std_logic;  -- system clock
+    RESET                   : in  std_logic;
+    -- INTERFACE       
+    MY_MAC_IN               : in  std_logic_vector(47 downto 0);
+    MY_IP_IN                : in  std_logic_vector(31 downto 0);
+    PS_DATA_IN              : in  std_logic_vector(8 downto 0);
+    PS_WR_EN_IN             : in  std_logic;
+    PS_ACTIVATE_IN          : in  std_logic;
+    PS_RESPONSE_READY_OUT   : out std_logic;
+    PS_BUSY_OUT             : out std_logic;
+    PS_SELECTED_IN          : in  std_logic;
+    PS_SRC_MAC_ADDRESS_IN   : in  std_logic_vector(47 downto 0);
+    PS_DEST_MAC_ADDRESS_IN  : in  std_logic_vector(47 downto 0);
+    PS_SRC_IP_ADDRESS_IN    : in  std_logic_vector(31 downto 0);
+    PS_DEST_IP_ADDRESS_IN   : in  std_logic_vector(31 downto 0);
+    PS_SRC_UDP_PORT_IN      : in  std_logic_vector(15 downto 0);
+    PS_DEST_UDP_PORT_IN     : in  std_logic_vector(15 downto 0);
+    --
+    TC_RD_EN_IN             : in  std_logic;
+    TC_DATA_OUT             : out std_logic_vector(8 downto 0);
+    TC_FRAME_SIZE_OUT       : out std_logic_vector(15 downto 0);
+    TC_FRAME_TYPE_OUT       : out std_logic_vector(15 downto 0);
+    TC_IP_PROTOCOL_OUT      : out std_logic_vector(7 downto 0);
+    TC_IDENT_OUT            : out std_logic_vector(15 downto 0);
+    TC_DEST_MAC_OUT         : out std_logic_vector(47 downto 0);
+    TC_DEST_IP_OUT          : out std_logic_vector(31 downto 0);
+    TC_DEST_UDP_OUT         : out std_logic_vector(15 downto 0);
+    TC_SRC_MAC_OUT          : out std_logic_vector(47 downto 0);
+    TC_SRC_IP_OUT           : out std_logic_vector(31 downto 0);
+    TC_SRC_UDP_OUT          : out std_logic_vector(15 downto 0);
+    --
+    RECEIVED_FRAMES_OUT     : out std_logic_vector(15 downto 0);
+    SENT_FRAMES_OUT         : out std_logic_vector(15 downto 0);
+    -- END OF INTERFACE
+    FWD_DST_MAC_IN          : in  std_logic_vector(47 downto 0);
+    FWD_DST_IP_IN           : in  std_logic_vector(31 downto 0);
+    FWD_DST_UDP_IN          : in  std_logic_vector(15 downto 0);
+    FWD_DATA_IN             : in  std_logic_vector(7 downto 0);
+    FWD_DATA_VALID_IN       : in  std_logic;
+    FWD_SOP_IN              : in  std_logic;
+    FWD_EOP_IN              : in  std_logic;
+    FWD_READY_OUT           : out std_logic;
+    FWD_FULL_OUT            : out std_logic;
+    -- debug
+    DEBUG_OUT               : out std_logic_vector(31 downto 0)
+  );
+end gbe_response_constructor_Forward;
+
+architecture gbe_response_constructor_Forward_arch of gbe_response_constructor_Forward is
+
+attribute syn_encoding : string;
+
+type dissect_states is (IDLE, SAVE, WAIT_FOR_LOAD, LOAD, CLEANUP);
+signal dissect_current_state, dissect_next_state : dissect_states;
+attribute syn_encoding of dissect_current_state: signal is "safe,gray";
+
+signal ff_wr_en                 : std_logic;
+signal ff_rd_en                 : std_logic;
+signal resp_bytes_ctr           : std_logic_vector(15 downto 0);
+signal ff_empty                 : std_logic;
+signal ff_full                  : std_logic;
+signal ff_q                     : std_logic_vector(8 downto 0);
+signal ff_rd_lock               : std_logic;
+
+signal state                    : std_logic_vector(3 downto 0);
+signal rec_frames               : std_logic_vector(15 downto 0);
+signal sent_frames              : std_logic_vector(15 downto 0);
+
+signal local_eop : std_logic;
+
+begin
+
+DISSECT_MACHINE_PROC: process( CLK, RESET )
+begin
+  if( RESET = '1' ) then
+    dissect_current_state <= IDLE;
+  elsif( rising_edge(CLK) ) then
+    dissect_current_state <= dissect_next_state;
+  end if;
+end process DISSECT_MACHINE_PROC;
+
+DISSECT_MACHINE: process(dissect_current_state, FWD_SOP_IN, FWD_EOP_IN, ff_q, ff_rd_lock, PS_SELECTED_IN)
+begin
+  case dissect_current_state is
+  
+    when IDLE =>
+      state <= x"1";
+      if (FWD_SOP_IN = '1') then
+        dissect_next_state <= SAVE;
+      else
+        dissect_next_state <= IDLE;
+      end if;
+    
+    when SAVE =>
+      state <= x"2";
+      if (FWD_EOP_IN = '1') then
+        dissect_next_state <= WAIT_FOR_LOAD;
+      else
+        dissect_next_state <= SAVE;
+      end if;
+      
+    when WAIT_FOR_LOAD =>
+      state <= x"3";
+      if (PS_SELECTED_IN = '0') then
+        dissect_next_state <= LOAD;
+      else
+        dissect_next_state <= WAIT_FOR_LOAD;
+      end if;
+    
+    when LOAD =>
+      state <= x"4";
+      if (ff_q(8) = '1') and (ff_rd_lock = '0') then
+        dissect_next_state <= CLEANUP;
+      else
+        dissect_next_state <= LOAD;
+      end if;
+    
+    when CLEANUP =>
+      state <= x"5";
+      dissect_next_state <= IDLE;
+  
+  end case;
+end process DISSECT_MACHINE;
+
+PS_BUSY_OUT <= '0' when dissect_current_state = IDLE else '1';
+
+ff_wr_en <= '1' when (FWD_DATA_VALID_IN = '1') else '0';
+
+local_eop <= '1' when (dissect_current_state = SAVE and FWD_EOP_IN = '1' and FWD_DATA_VALID_IN = '1') else '0';
+
+FF_RD_LOCK_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    ff_rd_lock <= '1';
+  elsif( rising_edge(CLK) ) then
+    if( dissect_current_state = LOAD and ff_rd_en = '1' ) then
+      ff_rd_lock <= '0';
+    else 
+      ff_rd_lock <= '1';
+    end if;
+  end if;
+end process FF_RD_LOCK_PROC;
+
+FRAME_FIFO: entity fifo_4096x9
+port map( 
+  Data(7 downto 0)    => FWD_DATA_IN,
+  Data(8)             => local_eop,
+  WrClock             => CLK,
+  RdClock             => CLK,
+  WrEn                => ff_wr_en,
+  RdEn                => ff_rd_en,
+  Reset               => RESET,
+  RPReset             => RESET,
+  Q                   => ff_q,
+  Empty               => ff_empty,
+  Full                => ff_full
+);
+
+ff_rd_en <= '1' when (TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1') else '0';
+
+--TC_DATA_OUT <= ff_q; -- BUG?!?
+TC_DATA_OUT <= ff_q when rising_edge(CLK);
+
+PS_RESPONSE_READY_OUT <= '1' when (dissect_current_state = LOAD) else '0';
+
+--TC_FRAME_SIZE_OUT <= resp_bytes_ctr + x"1"; -- BUG?!?
+TC_FRAME_SIZE_OUT <= resp_bytes_ctr;
+
+TC_FRAME_TYPE_OUT  <= x"0008";
+TC_DEST_MAC_OUT    <= FWD_DST_MAC_IN;
+TC_DEST_IP_OUT     <= FWD_DST_IP_IN;
+TC_DEST_UDP_OUT    <= FWD_DST_UDP_IN;
+TC_SRC_MAC_OUT     <= MY_MAC_IN;
+TC_SRC_IP_OUT      <= MY_IP_IN;
+TC_SRC_UDP_OUT     <= FWD_DST_UDP_IN;
+TC_IP_PROTOCOL_OUT <= x"11";
+TC_IDENT_OUT       <= x"6" & sent_frames(11 downto 0);
+
+RESP_BYTES_CTR_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    resp_bytes_ctr <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if   ( dissect_current_state = IDLE ) then
+      resp_bytes_ctr <= (others => '0');
+    elsif( dissect_current_state = SAVE and FWD_DATA_VALID_IN = '1' ) then
+      resp_bytes_ctr <= resp_bytes_ctr + x"1";
+    end if;
+
+    FWD_FULL_OUT <= ff_full;
+
+    if( dissect_current_state = IDLE ) then
+      FWD_READY_OUT <= '1';
+    else
+      FWD_READY_OUT <= '0';
+    end if;
+
+  end if;
+end process RESP_BYTES_CTR_PROC;
+
+REC_FRAMES_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    rec_frames <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if( dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then
+      rec_frames <= rec_frames + x"1";
+    end if;
+  end if;
+end process REC_FRAMES_PROC;
+
+SENT_FRAMES_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    sent_frames <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if( dissect_current_state = WAIT_FOR_LOAD and PS_SELECTED_IN = '0' ) then
+      sent_frames <= sent_frames + x"1";
+    end if;
+  end if;
+end process SENT_FRAMES_PROC;
+
+RECEIVED_FRAMES_OUT <= rec_frames;
+SENT_FRAMES_OUT     <= sent_frames;
+
+-- **** debug
+DEBUG_OUT(3 downto 0)   <= state;
+DEBUG_OUT(4)            <= ff_empty;
+DEBUG_OUT(5)            <= ff_full;
+DEBUG_OUT(6)            <= ff_wr_en;
+DEBUG_OUT(7)            <= ff_rd_en;
+DEBUG_OUT(15 downto 8)  <= ff_q(7 downto 0);
+DEBUG_OUT(16)           <= ff_q(8);
+DEBUG_OUT(17)           <= local_eop;
+DEBUG_OUT(31 downto 18) <= (others => '0');
+-- ****
+
+end gbe_response_constructor_Forward_arch;
diff --git a/gbe_trb/protocols/gbe_response_constructor_Ping.vhd b/gbe_trb/protocols/gbe_response_constructor_Ping.vhd
new file mode 100644 (file)
index 0000000..0b79ad6
--- /dev/null
@@ -0,0 +1,304 @@
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.gbe_protocols.all;
+
+entity gbe_response_constructor_Ping is
+port(
+  CLK                    : in  std_logic;  -- system clock
+  RESET                  : in  std_logic;
+-- INTERFACE  
+  MY_MAC_IN              : in  std_logic_vector(47 downto 0);
+  MY_IP_IN               : in  std_logic_vector(31 downto 0);
+  PS_DATA_IN             : in  std_logic_vector(8 downto 0);
+  PS_WR_EN_IN            : in  std_logic;
+  PS_ACTIVATE_IN         : in  std_logic;
+  PS_RESPONSE_READY_OUT  : out std_logic;
+  PS_BUSY_OUT            : out std_logic;
+  PS_SELECTED_IN         : in  std_logic;
+  PS_SRC_MAC_ADDRESS_IN  : in  std_logic_vector(47 downto 0);
+  PS_DEST_MAC_ADDRESS_IN : in  std_logic_vector(47 downto 0);
+  PS_SRC_IP_ADDRESS_IN   : in  std_logic_vector(31 downto 0);
+  PS_DEST_IP_ADDRESS_IN  : in  std_logic_vector(31 downto 0);
+  PS_SRC_UDP_PORT_IN     : in  std_logic_vector(15 downto 0);
+  PS_DEST_UDP_PORT_IN    : in  std_logic_vector(15 downto 0);
+--
+  TC_RD_EN_IN            : in  std_logic;
+  TC_DATA_OUT            : out std_logic_vector(8 downto 0);
+  TC_FRAME_SIZE_OUT      : out std_logic_vector(15 downto 0);
+  TC_FRAME_TYPE_OUT      : out std_logic_vector(15 downto 0);
+  TC_IP_PROTOCOL_OUT     : out std_logic_vector(7 downto 0);  
+  TC_IDENT_OUT           : out std_logic_vector(15 downto 0);  
+  TC_DEST_MAC_OUT        : out std_logic_vector(47 downto 0);
+  TC_DEST_IP_OUT         : out std_logic_vector(31 downto 0);
+  TC_DEST_UDP_OUT        : out std_logic_vector(15 downto 0);
+  TC_SRC_MAC_OUT         : out std_logic_vector(47 downto 0);
+  TC_SRC_IP_OUT          : out std_logic_vector(31 downto 0);
+  TC_SRC_UDP_OUT         : out std_logic_vector(15 downto 0);
+-- END OF INTERFACE
+-- debug
+  DEBUG_OUT    : out  std_logic_vector(63 downto 0)
+);
+end gbe_response_constructor_Ping;
+
+architecture gbe_response_constructor_Ping_arch of gbe_response_constructor_Ping is
+
+attribute syn_encoding  : string;
+
+type dissect_states is (IDLE, READ_FRAME, WAIT_FOR_LOAD, LOAD_FRAME, CLEANUP);
+signal dissect_current_state, dissect_next_state : dissect_states;
+attribute syn_encoding of dissect_current_state: signal is "onehot";
+
+type stats_states is (IDLE, LOAD_SENT, LOAD_RECEIVED, CLEANUP);
+signal stats_current_state, stats_next_state : stats_states;
+attribute syn_encoding of stats_current_state : signal is "onehot";
+
+signal sent_frames        : std_logic_vector(15 downto 0);
+
+signal saved_data         : std_logic_vector(447 downto 0);
+signal saved_headers      : std_logic_vector(63 downto 0);
+
+signal data_ctr           : integer range 1 to 1500;
+signal data_length        : integer range 1 to 1500;
+signal tc_data            : std_logic_vector(8 downto 0);
+
+signal checksum           : std_logic_vector(15 downto 0);
+
+signal checksum_l         : std_logic_vector(19 downto 0);
+signal checksum_r         : std_logic_vector(19 downto 0);
+signal checksum_ll        : std_logic_vector(15 downto 0);
+signal checksum_rr        : std_logic_vector(15 downto 0);
+signal checksum_lll       : std_logic_vector(15 downto 0);
+signal checksum_rrr       : std_logic_vector(15 downto 0);
+
+begin
+
+DISSECT_MACHINE_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    dissect_current_state <= IDLE;
+  elsif( rising_edge(CLK) ) then
+    dissect_current_state <= dissect_next_state;
+  end if;
+end process DISSECT_MACHINE_PROC;
+
+DISSECT_MACHINE: process(dissect_current_state, PS_WR_EN_IN, PS_SELECTED_IN, PS_ACTIVATE_IN, PS_DATA_IN, data_ctr, data_length)
+begin
+  case dissect_current_state is
+  
+    when IDLE =>
+      if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then
+        dissect_next_state <= READ_FRAME;
+      else
+        dissect_next_state <= IDLE;
+      end if;
+    
+    when READ_FRAME =>
+      if (PS_DATA_IN(8) = '1') then
+        dissect_next_state <= WAIT_FOR_LOAD;
+      else
+        dissect_next_state <= READ_FRAME;
+      end if;
+      
+    when WAIT_FOR_LOAD =>
+      if (PS_SELECTED_IN = '1') then
+        dissect_next_state <= LOAD_FRAME;
+      else
+        dissect_next_state <= WAIT_FOR_LOAD;
+      end if;
+    
+    when LOAD_FRAME =>
+      if (data_ctr = data_length + 1) then
+        dissect_next_state <= CLEANUP;
+      else
+        dissect_next_state <= LOAD_FRAME;
+      end if;
+    
+    when CLEANUP =>
+      dissect_next_state <= IDLE;
+  
+  end case;
+end process DISSECT_MACHINE;
+
+DATA_CTR_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    data_ctr <= 2;
+  elsif( rising_edge(CLK) ) then
+    if   ( (dissect_current_state = IDLE) or (dissect_current_state = WAIT_FOR_LOAD) ) then
+      data_ctr <= 2;
+    elsif( dissect_current_state = READ_FRAME and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then  -- in case of saving data from incoming frame
+      data_ctr <= data_ctr + 1;
+    elsif( dissect_current_state = LOAD_FRAME and PS_SELECTED_IN = '1' and TC_RD_EN_IN = '1' ) then  -- in case of constructing response
+      data_ctr <= data_ctr + 1;
+    end if;
+  end if;
+end process DATA_CTR_PROC;
+
+DATA_LENGTH_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    data_length <= 1;
+  elsif( rising_edge(CLK) ) then
+    if (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1') then
+      data_length <= data_ctr;
+    end if;
+  end if;
+end process DATA_LENGTH_PROC;
+
+SAVE_VALUES_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    saved_headers <= (others => '0');
+    saved_data    <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if   ( dissect_current_state = IDLE ) then
+      saved_headers <= (others => '0');
+      saved_data    <= (others => '0');
+    elsif( dissect_current_state = IDLE and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then
+      saved_headers(7 downto 0) <= PS_DATA_IN(7 downto 0);
+    elsif( dissect_current_state = READ_FRAME ) then
+      if (data_ctr < 9) then  -- headers
+        saved_headers(data_ctr * 8 - 1 downto (data_ctr - 1) * 8) <= PS_DATA_IN(7 downto 0);
+      elsif (data_ctr > 8) then -- data
+        saved_data((data_ctr - 8) * 8 - 1 downto (data_ctr - 8 - 1) * 8) <= PS_DATA_IN(7 downto 0);
+      end if;
+    elsif( dissect_current_state = LOAD_FRAME ) then
+      saved_headers(7 downto 0)   <= x"00";
+      saved_headers(23 downto 16) <= checksum(7 downto 0);
+      saved_headers(31 downto 24) <= checksum(15 downto 8);
+    end if;
+  end if;
+end process SAVE_VALUES_PROC;
+
+CS_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    checksum_l(19 downto 0)    <= (others => '0');
+    checksum_r(19 downto 0)    <= (others => '0');
+    checksum_ll(15 downto 0)   <= (others => '0');
+    checksum_rr(15 downto 0)   <= (others => '0');
+    checksum_lll(15 downto 0)  <= (others => '0');
+    checksum_rrr(15 downto 0)  <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if( dissect_current_state = IDLE ) then
+      checksum_l(19 downto 0)    <= (others => '0');
+      checksum_r(19 downto 0)    <= (others => '0');
+      checksum_ll(15 downto 0)   <= (others => '0');
+      checksum_rr(15 downto 0)   <= (others => '0');
+      checksum_lll(15 downto 0)  <= (others => '0');
+      checksum_rrr(15 downto 0)  <= (others => '0');
+    elsif( dissect_current_state = READ_FRAME and data_ctr > 4 ) then
+      if (std_logic_vector(to_unsigned(data_ctr, 1)) = "0") then
+        checksum_l <= checksum_l + PS_DATA_IN(7 downto 0);
+      else
+        checksum_r <= checksum_r + PS_DATA_IN(7 downto 0);
+      end if;
+      checksum_ll  <= checksum_ll;
+      checksum_lll <= checksum_lll;
+      checksum_rr  <= checksum_rr;
+      checksum_rrr <= checksum_rrr;
+    elsif( dissect_current_state = WAIT_FOR_LOAD ) then
+      checksum_ll <= x"0000" + checksum_l(7 downto 0) + checksum_r(19 downto 8);
+      checksum_rr <= x"0000" + checksum_r(7 downto 0) + checksum_l(19 downto 8);
+      checksum_l   <= checksum_l;
+      checksum_lll <= checksum_lll;
+      checksum_r   <= checksum_r;
+      checksum_rrr <= checksum_rrr;
+    elsif( dissect_current_state = LOAD_FRAME and data_ctr = 2 ) then
+      checksum_lll <= x"0000" + checksum_ll(7 downto 0) + checksum_rr(15 downto 8);
+      checksum_rrr <= x"0000" + checksum_rr(7 downto 0) + checksum_ll(15 downto 8);
+      checksum_l  <= checksum_l;
+      checksum_ll <= checksum_ll;
+      checksum_r  <= checksum_r;
+      checksum_rr <= checksum_rr;
+    end if;
+  end if;
+end process CS_PROC;
+checksum(7 downto 0)  <= not (checksum_rrr(7 downto 0) + checksum_lll(15 downto 8));
+checksum(15 downto 8) <= not (checksum_lll(7 downto 0) + checksum_rrr(15 downto 8));
+
+TC_DATA_PROC : process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    tc_data(8) <= '0';
+    
+    if( dissect_current_state = LOAD_FRAME ) then
+      if (data_ctr < 10) then  -- headers
+        for i in 0 to 7 loop
+          tc_data(i) <= saved_headers((data_ctr - 2) * 8 + i);
+        end loop;
+      else  -- data
+        for i in 0 to 7 loop
+          tc_data(i) <= saved_data((data_ctr - 8 - 2) * 8 + i);
+        end loop;
+      
+        -- mark the last byte
+        if (data_ctr = data_length + 1) then
+          tc_data(8) <= '1';
+        end if;
+      end if;
+    else
+      tc_data(7 downto 0) <= (others => '0');  
+    end if;
+    
+    TC_DATA_OUT <= tc_data;
+    
+  end if;
+end process TC_DATA_PROC;
+
+PS_RESPONSE_SYNC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( dissect_current_state = WAIT_FOR_LOAD or dissect_current_state = LOAD_FRAME or dissect_current_state = CLEANUP ) then
+      PS_RESPONSE_READY_OUT <= '1';
+    else
+      PS_RESPONSE_READY_OUT <= '0';
+    end if;
+    
+    if( dissect_current_state = IDLE ) then
+      PS_BUSY_OUT <= '0';
+    else
+      PS_BUSY_OUT <= '1';
+    end if;
+  end if;  
+end process PS_RESPONSE_SYNC;
+
+TC_FRAME_SIZE_OUT   <= std_logic_vector(to_unsigned(data_length, 16));
+TC_FRAME_TYPE_OUT   <= x"0008";
+TC_DEST_UDP_OUT     <= x"0000";  -- not used
+TC_SRC_MAC_OUT      <= MY_MAC_IN;
+TC_SRC_IP_OUT       <= MY_IP_IN;
+TC_SRC_UDP_OUT      <= x"0000";  -- not used
+TC_IP_PROTOCOL_OUT  <= X"01"; -- ICMP
+TC_IDENT_OUT        <= x"2" & sent_frames(11 downto 0);
+
+ADDR_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( dissect_current_state = READ_FRAME ) then
+      TC_DEST_MAC_OUT <= PS_SRC_MAC_ADDRESS_IN;
+      TC_DEST_IP_OUT  <= PS_SRC_IP_ADDRESS_IN;
+    end if;
+  end if;
+end process ADDR_PROC;
+
+SENT_FRAMES_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    sent_frames <= (others => '0');
+  elsif( rising_edge(CLK) ) then
+    if( dissect_current_state = CLEANUP ) then
+      sent_frames <= sent_frames + x"1";
+    end if;
+  end if;
+end process SENT_FRAMES_PROC;
+
+end gbe_response_constructor_Ping_arch;
+
+
diff --git a/gbe_trb/protocols/gbe_response_constructor_SCTRL.vhd b/gbe_trb/protocols/gbe_response_constructor_SCTRL.vhd
new file mode 100644 (file)
index 0000000..2a47e3f
--- /dev/null
@@ -0,0 +1,635 @@
+LIBRARY IEEE;
+USE IEEE.std_logic_1164.ALL;
+USE IEEE.numeric_std.ALL;
+USE IEEE.std_logic_UNSIGNED.ALL;
+
+library work;
+use work.trb_net_std.all;
+use work.trb_net_components.all;
+use work.gbe_protocols.all;
+
+
+entity gbe_response_constructor_SCTRL is
+  generic( 
+    SLOWCTRL_BUFFER_SIZE : integer range 1 to 4 := 1
+  );
+  port(
+    CLK                           : in  std_logic;  -- system clock
+    RESET                         : in  std_logic;
+  -- INTERFACE                    
+    MY_MAC_IN                     : in  std_logic_vector(47 downto 0);
+    MY_IP_IN                      : in  std_logic_vector(31 downto 0);
+    PS_DATA_IN                    : in  std_logic_vector(8 downto 0);
+    PS_WR_EN_IN                   : in  std_logic;
+    PS_ACTIVATE_IN                : in  std_logic;
+    PS_RESPONSE_READY_OUT         : out std_logic;
+    PS_BUSY_OUT                   : out std_logic;
+    PS_SELECTED_IN                : in  std_logic;
+    PS_SRC_MAC_ADDRESS_IN         : in  std_logic_vector(47 downto 0);
+    PS_DEST_MAC_ADDRESS_IN        : in  std_logic_vector(47 downto 0);
+    PS_SRC_IP_ADDRESS_IN          : in  std_logic_vector(31 downto 0);
+    PS_DEST_IP_ADDRESS_IN         : in  std_logic_vector(31 downto 0);
+    PS_SRC_UDP_PORT_IN            : in  std_logic_vector(15 downto 0);
+    PS_DEST_UDP_PORT_IN           : in  std_logic_vector(15 downto 0);
+--                                  
+    TC_RD_EN_IN                   : in  std_logic;
+    TC_DATA_OUT                   : out std_logic_vector(8 downto 0);
+    TC_FRAME_SIZE_OUT             : out std_logic_vector(15 downto 0);
+    TC_FRAME_TYPE_OUT             : out std_logic_vector(15 downto 0);
+    TC_IP_PROTOCOL_OUT            : out std_logic_vector(7 downto 0);  
+    TC_IDENT_OUT                  : out std_logic_vector(15 downto 0); 
+    TC_DEST_MAC_OUT               : out std_logic_vector(47 downto 0);
+    TC_DEST_IP_OUT                : out std_logic_vector(31 downto 0);
+    TC_DEST_UDP_OUT               : out std_logic_vector(15 downto 0);
+    TC_SRC_MAC_OUT                : out std_logic_vector(47 downto 0);
+    TC_SRC_IP_OUT                 : out std_logic_vector(31 downto 0);
+    TC_SRC_UDP_OUT                : out std_logic_vector(15 downto 0);
+--
+    DEBUG_OUT                     : out std_logic_vector(63 downto 0);
+  -- END OF INTERFACE
+  -- protocol specific ports
+    GSC_CLK_IN                    : in  std_logic;
+    GSC_INIT_DATAREADY_OUT        : out std_logic;
+    GSC_INIT_DATA_OUT             : out std_logic_vector(15 downto 0);
+    GSC_INIT_PACKET_NUM_OUT       : out std_logic_vector(2 downto 0);
+    GSC_INIT_READ_IN              : in  std_logic;
+    GSC_REPLY_DATAREADY_IN        : in  std_logic;
+    GSC_REPLY_DATA_IN             : in  std_logic_vector(15 downto 0);
+    GSC_REPLY_PACKET_NUM_IN       : in  std_logic_vector(2 downto 0);
+    GSC_REPLY_READ_OUT            : out std_logic;
+    GSC_BUSY_IN                   : in  std_logic;
+    MAKE_RESET_OUT                : out std_logic;
+    CFG_MAX_REPLY_SIZE_IN         : in  std_logic_vector(31 downto 0);
+  -- end of protocol specific ports
+    MONITOR_SELECT_REC_OUT           : out     std_logic_vector(31 downto 0);
+    MONITOR_SELECT_REC_BYTES_OUT  : out        std_logic_vector(31 downto 0);
+    MONITOR_SELECT_SENT_BYTES_OUT : out        std_logic_vector(31 downto 0);
+    MONITOR_SELECT_SENT_OUT          : out     std_logic_vector(31 downto 0);
+    DATA_HIST_OUT                 : out hist_array
+  );
+end entity gbe_response_constructor_SCTRL;
+
+architecture gbe_response_constructor_SCTRL_arch of gbe_response_constructor_SCTRL is
+
+attribute syn_encoding : string;
+
+type dissect_states is (IDLE, READ_FRAME, WAIT_FOR_HUB, LOAD_TO_HUB, WAIT_FOR_RESPONSE, SAVE_RESPONSE, LOAD_FRAME, WAIT_FOR_LOAD, CLEANUP);
+signal dissect_current_state, dissect_next_state : dissect_states;
+attribute syn_encoding of dissect_current_state: signal is "onehot";
+
+type stats_states is (IDLE, LOAD_RECEIVED, LOAD_REPLY, CLEANUP);
+signal stats_current_state, stats_next_state : stats_states;
+attribute syn_encoding of stats_current_state : signal is "onehot";
+
+signal saved_target_ip          : std_logic_vector(31 downto 0);
+signal data_ctr                 : integer range 0 to 30;
+
+signal rec_frames               : std_logic_vector(15 downto 0);
+
+signal rx_fifo_q                : std_logic_vector(17 downto 0);
+signal rx_fifo_qq               : std_logic_vector(17 downto 0);
+signal rx_fifo_wr, rx_fifo_rd   : std_logic;
+signal tx_eod, rx_eod           : std_logic;
+
+signal tx_fifo_q                : std_logic_vector(8 downto 0);
+signal tx_fifo_wr, tx_fifo_rd   : std_logic;
+signal tx_fifo_reset            : std_logic;
+signal gsc_reply_read           : std_logic;
+signal gsc_init_dataready       : std_logic;
+signal gsc_init_dataready_q     : std_logic;
+
+signal tx_data_ctr              : std_logic_vector(15 downto 0);
+signal tx_loaded_ctr            : std_logic_vector(15 downto 0);
+signal tx_frame_loaded          : std_logic_vector(15 downto 0);
+
+signal packet_num               : std_logic_vector(2 downto 0);
+       
+signal init_ctr, reply_ctr      : std_logic_vector(15 downto 0);
+signal rx_empty, tx_empty       : std_logic;
+
+signal rx_full, tx_full         : std_logic;
+
+signal size_left                : std_logic_vector(15 downto 0);
+
+signal reset_detected           : std_logic := '0';
+signal make_reset               : std_logic := '0';
+
+signal fifo_rd_q                : std_logic;
+
+signal too_much_data            : std_logic;
+
+signal rx_fifo_data             : std_logic_vector(8 downto 0);
+signal tx_fifo_data             : std_logic_vector(17 downto 0);
+
+signal tc_wr                    : std_logic;
+signal state                    : std_logic_vector(3 downto 0);
+signal saved_hdr_1              : std_logic_vector(7 downto 0) := x"ab";
+signal saved_hdr_2              : std_logic_vector(7 downto 0) := x"cd";
+signal saved_hdr_ctr            : std_logic_vector(3 downto 0);
+
+signal mon_rec_frames, mon_rec_bytes, mon_sent_frames, mon_sent_bytes : std_logic_vector(31 downto 0);
+
+attribute syn_preserve : boolean;
+attribute syn_keep : boolean;
+attribute syn_keep of rx_fifo_wr, rx_fifo_rd, gsc_init_dataready, tx_fifo_wr, tx_fifo_rd, gsc_reply_read, state : signal is true;
+attribute syn_preserve of rx_fifo_wr, rx_fifo_rd, gsc_init_dataready, tx_fifo_wr, tx_fifo_rd, gsc_reply_read, state : signal is true;
+
+signal hist_inst : hist_array;
+signal reset_all_hist : std_logic_vector(31 downto 0);
+
+signal rx_cnt, tx_cnt : std_logic_vector(15 downto 0);
+
+begin
+
+MAKE_RESET_OUT <= make_reset;
+
+receive_fifo: entity work.fifo_2kx9x18_wcnt
+  PORT map(
+    Reset    => RESET,
+    RPReset  => RESET,
+    WrClock  => CLK,
+    RdClock  => CLK,
+    Data     => rx_fifo_data,
+    WrEn     => rx_fifo_wr,
+    RdEn     => rx_fifo_rd,
+    Q        => rx_fifo_q,
+    Full     => rx_full,
+    Empty    => rx_empty,
+    WCNT     => rx_cnt(11 downto 0)
+  );
+
+--TODO: change to synchronous
+rx_fifo_rd <= '1' when (gsc_init_dataready = '1' and dissect_current_state = LOAD_TO_HUB) or 
+                       (gsc_init_dataready = '1' and dissect_current_state = WAIT_FOR_HUB and GSC_INIT_READ_IN = '1') or
+                       (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1')
+              else '0';  -- preload first word
+              
+RX_FIFO_WR_SYNC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+
+    if( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and (saved_hdr_ctr = "0100" or saved_hdr_ctr = "1000") ) then
+      rx_fifo_wr <= '1';
+    else
+      rx_fifo_wr <= '0';
+    end if;
+  
+    rx_fifo_data <= PS_DATA_IN;
+  end if;
+end process RX_FIFO_WR_SYNC;
+
+SAVED_HDR_CTR_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( dissect_current_state = IDLE and PS_WR_EN_IN = '0' and PS_ACTIVATE_IN = '0' ) then
+      saved_hdr_ctr <= "0001";
+    elsif( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and saved_hdr_ctr /= "1000" ) then
+      saved_hdr_ctr(3 downto 0) <= saved_hdr_ctr(2 downto 0) & '0';
+    end if;
+  end if;
+end process SAVED_HDR_CTR_PROC;
+
+SAVED_HDR_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' ) then
+      if( saved_hdr_ctr = "0001" ) then
+        saved_hdr_1 <= PS_DATA_IN(7 downto 0);
+        saved_hdr_2 <= saved_hdr_2;
+      elsif( saved_hdr_ctr = "0010" ) then
+        saved_hdr_2 <= PS_DATA_IN(7 downto 0);
+        saved_hdr_1 <= saved_hdr_1;
+      end if;
+    end if;
+  end if;
+end process SAVED_HDR_PROC;
+
+----TODO: add a register
+GSC_INIT_DATA_OUT(7 downto 0)  <= rx_fifo_q(16 downto 9);
+GSC_INIT_DATA_OUT(15 downto 8) <= rx_fifo_q(7 downto 0);
+
+------ TODO: change it to synchronous
+GSC_INIT_PACKET_NUM_OUT <= packet_num;
+GSC_INIT_DATAREADY_OUT  <= gsc_init_dataready;
+gsc_init_dataready <= '1' when (GSC_INIT_READ_IN = '1' and dissect_current_state = LOAD_TO_HUB) or  --TODO Ob das so richtig ist, ohne auf fifo_rd zu schauen?
+                               (dissect_current_state = WAIT_FOR_HUB) 
+                      else '0';
+
+PACKET_NUM_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( dissect_current_state = IDLE ) then
+      packet_num <= "100";
+    elsif( GSC_INIT_READ_IN = '1' and rx_fifo_rd = '1' and packet_num = "100" and dissect_current_state /= READ_FRAME ) then  --BUG zählt schon hoch beim fifo_rd weil read schon 1 ist. read geht aber nur auf 1 wenn dataready auf 1 ist
+      packet_num <= "000";
+    elsif( rx_fifo_rd = '1' and packet_num /= "100" ) then
+      packet_num <= packet_num + "1";
+    end if;
+  end if;
+end process PACKET_NUM_PROC;
+
+tf_4k_gen: if SLOWCTRL_BUFFER_SIZE = 1 generate
+  transmit_fifo: entity work.fifo_4kx18x9_wcnt
+  port map(
+    Reset    => tx_fifo_reset,
+    RPReset  => tx_fifo_reset,
+    WrClock  => CLK,
+    RdClock  => CLK,
+    Data     => tx_fifo_data,
+    WrEn     => tx_fifo_wr,
+    RdEn     => tx_fifo_rd,
+    Q        => tx_fifo_q,
+    Full     => tx_full,
+    Empty    => tx_empty,
+    WCNT     => tx_cnt(11 downto 0)
+  );
+end generate tf_4k_gen;
+
+tf_65k_gen: if SLOWCTRL_BUFFER_SIZE = 2 generate
+  transmit_fifo: entity work.fifo_64kx18x9_wcnt
+  port map(
+    Reset    => tx_fifo_reset,
+    RPReset  => tx_fifo_reset,
+    WrClock  => CLK,
+    RdClock  => CLK,
+    Data     => tx_fifo_data,
+    WrEn     => tx_fifo_wr,
+    RdEn     => tx_fifo_rd,
+    Q        => tx_fifo_q,
+    Full     => tx_full,
+    Empty    => tx_empty,
+    WCNT     => tx_cnt
+  );
+end generate tf_65k_gen;
+
+TX_FIFO_WR_SYNC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( GSC_REPLY_DATAREADY_IN = '1' and gsc_reply_read = '1' ) then
+      tx_fifo_wr <= '1';
+    elsif( saved_hdr_ctr = "0010" ) then
+      tx_fifo_wr <= '1';
+    else
+      tx_fifo_wr <= '0';
+    end if;
+  
+    if( saved_hdr_ctr = "010" ) then
+      tx_fifo_data <= '0' & PS_DATA_IN(7 downto 0) & '0' & x"02";
+    else
+      tx_fifo_data(7 downto 0)  <= GSC_REPLY_DATA_IN(15 downto 8);
+      tx_fifo_data(8)           <= '0';
+      tx_fifo_data(16 downto 9) <= GSC_REPLY_DATA_IN(7 downto 0);
+      tx_fifo_data(17)          <= '0';
+    end if;
+  end if;
+end process TX_FIFO_WR_SYNC;
+
+tx_fifo_rd <= '1' when TC_RD_EN_IN = '1' and PS_SELECTED_IN = '1' else '0';
+
+TX_FIFO_SYNC_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    tx_fifo_reset <= '1';
+  elsif( rising_edge(CLK) ) then
+    if( too_much_data = '1' and dissect_current_state = CLEANUP ) then
+      tx_fifo_reset <= '1';
+    else
+      tx_fifo_reset <= '0';
+    end if;
+  end if;
+end process TX_FIFO_SYNC_PROC;
+
+TC_DATA_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+
+    TC_DATA_OUT(7 downto 0) <= tx_fifo_q(7 downto 0);
+  
+    if( tx_loaded_ctr = tx_data_ctr ) then
+      TC_DATA_OUT(8) <= '1';
+    else
+      TC_DATA_OUT(8) <= '0';
+    end if;
+  end if;
+end process TC_DATA_PROC;
+
+GSC_REPLY_READ_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( dissect_current_state = WAIT_FOR_RESPONSE or dissect_current_state = SAVE_RESPONSE ) then
+      gsc_reply_read <= '1';
+    else
+      gsc_reply_read <= '0';
+    end if;
+  end if;
+end process GSC_REPLY_READ_PROC;
+GSC_REPLY_READ_OUT      <= gsc_reply_read;
+
+-- counter of data received from TRBNet hub
+TX_DATA_CTR_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if (dissect_current_state = IDLE) then
+      tx_data_ctr <= (others => '0');
+    elsif( tx_fifo_wr = '1' ) then
+      tx_data_ctr <= tx_data_ctr + x"2";
+    end if;
+  end if;
+end process TX_DATA_CTR_PROC;
+
+TOO_MUCH_DATA_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( dissect_current_state = IDLE ) then
+      too_much_data <= '0';
+    elsif( (dissect_current_state = SAVE_RESPONSE) and (tx_data_ctr = CFG_MAX_REPLY_SIZE_IN(15 downto 0)) ) then
+      too_much_data <= '1';
+    end if;
+  end if;
+end process TOO_MUCH_DATA_PROC;
+
+-- total counter of data transported to frame constructor
+TX_LOADED_CTR_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( dissect_current_state = IDLE ) then
+      tx_loaded_ctr <= x"0000";
+    elsif( dissect_current_state = LOAD_FRAME and PS_SELECTED_IN = '1' and TC_RD_EN_IN = '1' ) then
+      tx_loaded_ctr <= tx_loaded_ctr + x"1";
+    end if;
+  end if;
+end process TX_LOADED_CTR_PROC;
+
+PS_RESPONSE_SYNC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if( too_much_data = '0' ) then
+      if( dissect_current_state = WAIT_FOR_LOAD or dissect_current_state = LOAD_FRAME or dissect_current_state = CLEANUP ) then
+        PS_RESPONSE_READY_OUT <= '1';
+      else
+        PS_RESPONSE_READY_OUT <= '0';
+      end if;
+    end if;
+  
+    if( dissect_current_state = IDLE or dissect_current_state = WAIT_FOR_RESPONSE ) then
+      PS_BUSY_OUT <= '0';
+    else
+      PS_BUSY_OUT <= '1';
+    end if;
+  end if;      
+end process PS_RESPONSE_SYNC;
+
+TC_FRAME_TYPE_OUT            <= x"0008";
+TC_DEST_MAC_OUT              <= PS_SRC_MAC_ADDRESS_IN;
+TC_DEST_IP_OUT               <= PS_SRC_IP_ADDRESS_IN;
+TC_DEST_UDP_OUT(7 downto 0)  <= PS_SRC_UDP_PORT_IN(15 downto 8);
+TC_DEST_UDP_OUT(15 downto 8) <= PS_SRC_UDP_PORT_IN(7 downto 0);
+TC_SRC_MAC_OUT               <= MY_MAC_IN;
+TC_SRC_IP_OUT                <= MY_IP_IN;
+TC_SRC_UDP_OUT               <= x"9065"; --x"a861";
+TC_IP_PROTOCOL_OUT           <= x"11";
+TC_IDENT_OUT                 <= x"3" & reply_ctr(11 downto 0);
+
+TC_FRAME_SIZE_OUT   <= tx_data_ctr;
+
+DISSECT_MACHINE_PROC: process( CLK, RESET )
+begin
+  if   ( RESET = '1' ) then
+    dissect_current_state <= IDLE;
+  elsif( rising_edge(CLK) ) then
+    dissect_current_state <= dissect_next_state;
+  end if;
+end process DISSECT_MACHINE_PROC;
+
+DISSECT_MACHINE: process(dissect_current_state, reset_detected, too_much_data, PS_WR_EN_IN, PS_ACTIVATE_IN, 
+                         PS_DATA_IN, PS_SELECTED_IN, GSC_INIT_READ_IN, GSC_REPLY_DATAREADY_IN, tx_loaded_ctr, 
+                         tx_data_ctr, rx_fifo_q, GSC_BUSY_IN)
+begin
+  state <= x"0";
+
+  case dissect_current_state is
+
+    when IDLE =>
+      state <= x"1";
+      if (PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1') then
+        dissect_next_state <= READ_FRAME;
+      else
+        dissect_next_state <= IDLE;
+      end if;
+  
+    when READ_FRAME =>
+      state <= x"2";
+      if (PS_DATA_IN(8) = '1' and (GSC_INIT_READ_IN = '0')) then
+        dissect_next_state <= WAIT_FOR_HUB;
+      elsif (PS_DATA_IN(8) = '1' and (GSC_INIT_READ_IN = '1')) then
+        dissect_next_state <= LOAD_TO_HUB;
+      else
+        dissect_next_state <= READ_FRAME;
+      end if;
+    
+    when WAIT_FOR_HUB =>
+      state <= x"3";
+      if (GSC_INIT_READ_IN = '1') then
+        dissect_next_state <= LOAD_TO_HUB;
+      else
+        dissect_next_state <= WAIT_FOR_HUB;
+      end if;                                          
+  
+    when LOAD_TO_HUB =>
+      state <= x"4";
+      if ((rx_fifo_q(17) = '1') and (GSC_INIT_READ_IN = '1')) then
+        if (reset_detected = '1') then
+          dissect_next_state <= CLEANUP;
+        else
+          dissect_next_state <= WAIT_FOR_RESPONSE;
+        end if;
+      else
+        dissect_next_state <= LOAD_TO_HUB;
+      end if;  
+     
+    when WAIT_FOR_RESPONSE =>
+      state <= x"5";
+      if (GSC_REPLY_DATAREADY_IN = '1') then
+        dissect_next_state <= SAVE_RESPONSE;
+      else
+        dissect_next_state <= WAIT_FOR_RESPONSE;
+      end if;
+    
+    when SAVE_RESPONSE =>
+      state <= x"6";
+      if (GSC_REPLY_DATAREADY_IN = '0' and GSC_BUSY_IN = '0') then
+        if (too_much_data = '0') then
+          dissect_next_state <= WAIT_FOR_LOAD;
+        else
+          dissect_next_state <= CLEANUP;
+        end if;
+      else
+        dissect_next_state <= SAVE_RESPONSE;
+      end if;                  
+
+    when WAIT_FOR_LOAD =>
+      state <= x"7";
+      if (PS_SELECTED_IN = '1') then
+        dissect_next_state <= LOAD_FRAME;
+      else
+        dissect_next_state <= WAIT_FOR_LOAD;
+      end if;
+
+    when LOAD_FRAME =>
+      state <= x"8";
+      if (tx_loaded_ctr = tx_data_ctr) then
+        dissect_next_state <= CLEANUP;
+      else
+        dissect_next_state <= LOAD_FRAME;
+      end if;
+
+    when CLEANUP =>
+      state <= x"9";
+      dissect_next_state <= IDLE;
+
+    when others => dissect_next_state <= IDLE;
+
+  end case;
+end process DISSECT_MACHINE;
+
+-- reset request packet detection
+RESET_DETECTED_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( dissect_current_state = IDLE ) then
+      reset_detected <= '0';
+    elsif( PS_DATA_IN(7 downto 0) = x"80" and PS_WR_EN_IN = '1' and PS_ACTIVATE_IN = '1' and saved_hdr_ctr = "0100" ) then
+      reset_detected <= '1';
+    end if;
+  end if;
+end process RESET_DETECTED_PROC;
+MAKE_RESET_PROC: process( CLK )
+begin
+  if( rising_edge(CLK) ) then
+    if   ( dissect_current_state = IDLE ) then
+      make_reset <= '0';
+    elsif( dissect_current_state = CLEANUP and reset_detected = '1' ) then
+      make_reset <= '1';
+    end if;
+  end if;
+end process MAKE_RESET_PROC;
+
+
+-- monitoring
+
+hist_ctrs_gen : for i in 0 to 31 generate
+
+  process( CLK )
+  begin
+    if rising_edge(CLK) then
+      if (RESET = '1') then
+        reset_all_hist(i) <= '1';
+      elsif (hist_inst(i) = x"ffff_ffff") then
+        reset_all_hist(i) <= '1';
+      else
+        reset_all_hist(i) <= '0';
+      end if;                          
+    end if;
+  end process;
+
+  process(CLK)
+  begin
+    if rising_edge(CLK) then
+      if (reset_all_hist /= x"0000_0000") then
+        hist_inst(i) <= (others => '0');
+      elsif (dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr and i = to_integer(unsigned(tx_data_ctr(15 downto 11)))) then
+        hist_inst(i) <= hist_inst(i) + x"1"; 
+      else
+        hist_inst(i) <= hist_inst(i);
+      end if;
+    end if;
+  end process;
+
+end generate hist_ctrs_gen;
+
+DATA_HIST_OUT <= hist_inst;
+
+process( CLK )
+begin
+  if rising_edge(CLK) then
+    DEBUG_OUT(0) <= rx_full;
+    DEBUG_OUT(1) <= rx_empty;
+    DEBUG_OUT(2) <= tx_full;
+    DEBUG_OUT(3) <= tx_empty;
+    DEBUG_OUT(7 downto 4) <= state;
+    DEBUG_OUT(23 downto 8) <= rx_cnt;
+    DEBUG_OUT(39 downto 24) <= tx_cnt;
+    DEBUG_OUT(63 downto 40) <= (others => '0');
+  end if;
+end process;
+
+process( CLK )
+begin
+  if rising_edge(CLK) then
+    if (RESET = '1') then
+      mon_rec_frames <= (others => '0');
+    elsif (dissect_current_state = READ_FRAME and PS_DATA_IN(8) = '1') then
+      mon_rec_frames <= mon_rec_frames + x"1";
+    else
+      mon_rec_frames <= mon_rec_frames;
+    end if;
+  end if;
+end process;
+MONITOR_SELECT_REC_OUT <= mon_rec_frames;
+
+process( CLK )
+begin
+  if rising_edge(CLK) then
+    if (RESET = '1') then
+      mon_rec_bytes <= (others => '0');
+    elsif (rx_fifo_wr = '1') then
+      mon_rec_bytes <= mon_rec_bytes + x"1";
+    else
+      mon_rec_bytes <= mon_rec_bytes;
+    end if;
+  end if;
+end process;
+MONITOR_SELECT_REC_BYTES_OUT <= mon_rec_bytes;
+
+process( CLK )
+begin
+  if rising_edge(CLK) then
+    if (RESET = '1') then
+      mon_sent_frames <= (others => '0');
+    elsif (dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr) then
+      mon_sent_frames <= mon_sent_frames + x"1";
+    else
+      mon_sent_frames <= mon_sent_frames;
+    end if;
+  end if;
+end process;
+MONITOR_SELECT_SENT_OUT <= mon_sent_frames;
+
+process( CLK )
+begin
+  if rising_edge(CLK) then
+    if (RESET = '1') then
+      mon_sent_bytes <= (others => '0');
+    elsif (tx_fifo_rd = '1') then
+      mon_sent_bytes <= mon_sent_bytes + x"1";
+    else
+      mon_sent_bytes <= mon_sent_bytes;
+    end if;
+  end if;
+end process;
+MONITOR_SELECT_SENT_BYTES_OUT <= mon_sent_bytes;
+
+-- needed for identification
+REPLY_CTR_PROC : process( CLK )
+begin
+  if rising_edge(CLK) then
+    if (RESET = '1') then
+      reply_ctr <= (others => '0');
+    elsif (dissect_current_state = LOAD_FRAME and tx_loaded_ctr = tx_data_ctr) then
+      reply_ctr <= reply_ctr + x"1";
+    end if;
+  end if;
+end process REPLY_CTR_PROC;
+
+end architecture gbe_response_constructor_SCTRL_arch;
index 07ee55d3b29120c7055395c23d6188baa473fd51..4054fb4f7fc46f9c32108e2008f64e9bc59705e9 100644 (file)
@@ -1,13 +1,10 @@
-LIBRARY IEEE;
-USE IEEE.std_logic_1164.ALL;
-USE IEEE.std_logic_ARITH.ALL;
-USE IEEE.std_logic_UNSIGNED.ALL;
+library ieee;
+  use ieee.std_logic_1164.all;
+  use ieee.numeric_std.all;
 
 library work;
-use work.trb_net_std.all;
-use work.trb_net_components.all;
-use work.trb_net_gbe_components.all;
-use work.med_sync_define_RS.all;
+  use work.trb_net_std.all;
+  use work.med_sync_define_RS.all;
 
 -- short documentation:
 -- LINK_MODE:     set to c_IS_SLAVE for uplink port, c_IS_MASTER for downlink port, 
@@ -807,7 +804,7 @@ begin
       );
       
       -- RX ringbuffer
-      THE_FW_RB: entity rx_rb 
+      THE_FW_RB: entity work.gbe_rx_rb 
       port map(
         CLK                 => MASTER_CLK_IN,
         RESET               => CLEAR, --RESET, -- CHECKIFWORKS
diff --git a/media_interfaces/sync/gbe_tx_reset.vhd b/media_interfaces/sync/gbe_tx_reset.vhd
new file mode 100644 (file)
index 0000000..2b30c89
--- /dev/null
@@ -0,0 +1,181 @@
+--Media interface TX state machine\r
+\r
+LIBRARY IEEE;\r
+USE IEEE.std_logic_1164.ALL;\r
+USE IEEE.numeric_std.all;\r
+\r
+entity gbe_tx_reset is\r
+  port(\r
+    CLEAR                : in  std_logic; -- async reset, active high, should not be used!\r
+    CLK_REF              : in  std_logic; -- usually local oscillator sourced   \r
+    TX_PLL_LOL_IN        : in  std_logic; -- externally or'ed\r
+    TX_CLOCK_AVAIL_IN    : in  std_logic; -- suitable TX clock available \r
+    TX_PCS_RST_CH_C_OUT  : out std_logic; -- PCS reset\r
+    SYNC_TX_QUAD_OUT     : out std_logic; -- sync all QUADs to TX bit 0\r
+    LINK_TX_READY_OUT    : out std_logic; -- TX lane can use used now\r
+    STATE_OUT            : out std_logic_vector(3 downto 0)\r
+  );\r
+end entity gbe_tx_reset;\r
+\r
+architecture gbe_tx_reset_arch of gbe_tx_reset is\r
+\r
+  constant count_index : integer := 18; -- end of timer\r
+\r
+  type statetype is ( IDLE, WAIT_FOR_TIMER, SYNC_ALL, SYNC_DONE, NORMAL );\r
+\r
+  signal CURRENT_STATE : statetype;  -- current state of lsm\r
+  signal NEXT_STATE    : statetype;  -- next state of lsm\r
+  \r
+  signal tx_pcs_rst_ch_c_int  : std_logic;\r
+  signal sync_tx_quad_int     : std_logic;\r
+  signal link_tx_ready_int    : std_logic;\r
+  signal sync_tx_quad_trans   : std_logic;\r
+  \r
+  signal tx_pll_lol_all_q     : std_logic; -- synced\r
+  signal tx_clock_avail_q     : std_logic; -- synced\r
+  \r
+  signal counter              : unsigned(count_index downto 0);\r
+  signal timer                : std_logic;\r
+  signal reset_timer          : std_logic;\r
+\r
+begin\r
+\r
+-- This reset handler takes care of enabling all TX SerDes blocks in parallel,\r
+-- independently of RX SerDes blocks. The only difference between master and slave\r
+-- ports is the TX_CLOCK_AVAIL_IN input signal.\r
+-- This will delay the TX SerDes startup until the slave RX port is fully active.\r
+\r
+-- synchronize, just to be on the safe side\r
+  SYNC_SFP_SIGS : entity work.signal_sync\r
+    generic map(\r
+      WIDTH => 2,\r
+      DEPTH => 3\r
+    )\r
+    port map(\r
+      RESET    => '0',\r
+      CLK0     => CLK_REF, \r
+      CLK1     => CLK_REF,\r
+      D_IN(0)  => TX_PLL_LOL_IN, \r
+      D_IN(1)  => TX_CLOCK_AVAIL_IN,\r
+      D_OUT(0) => tx_pll_lol_all_q,\r
+      D_OUT(1) => tx_clock_avail_q\r
+    );\r
+\r
+-- Timer\r
+  THE_TIMER_PROC: process( CLK_REF )\r
+  begin\r
+    if( rising_edge(CLK_REF) ) then\r
+      if( reset_timer = '1' ) then\r
+        counter <= (others => '0');\r
+      else\r
+        if( counter(count_index) = '0' ) then\r
+          counter <= counter + 1 ;\r
+        end if;\r
+      end if;\r
+    end if;\r
+  end process THE_TIMER_PROC;\r
+\r
+  timer <= counter(count_index);\r
+\r
+-- State machine clocked process\r
+  THE_FSM_PROC: process( CLK_REF, CLEAR )\r
+  begin\r
+    if( CLEAR = '1' ) then\r
+      CURRENT_STATE        <= IDLE;\r
+      TX_PCS_RST_CH_C_OUT  <= '1';\r
+      LINK_TX_READY_OUT    <= '0';\r
+    else \r
+      if( rising_edge(CLK_REF) ) then\r
+        CURRENT_STATE        <= NEXT_STATE;\r
+        TX_PCS_RST_CH_C_OUT  <= tx_pcs_rst_ch_c_int;\r
+        LINK_TX_READY_OUT    <= link_tx_ready_int;\r
+      end if;\r
+    end if;\r
+  end process THE_FSM_PROC;\r
+\r
+  THE_FSM_DECODE_PROC: process( CURRENT_STATE, timer, tx_pll_lol_all_q, tx_clock_avail_q )\r
+  begin\r
+    reset_timer <= '0';\r
+    tx_pcs_rst_ch_c_int <= '0';\r
+    sync_tx_quad_int <= '0';\r
+    link_tx_ready_int <= '0';\r
+    STATE_OUT <= x"F";\r
+\r
+    case CURRENT_STATE is\r
+\r
+      when IDLE =>\r
+        STATE_OUT <= x"1";\r
+        tx_pcs_rst_ch_c_int <= '1';\r
+        reset_timer <= '1';\r
+        if( tx_clock_avail_q = '1' ) then\r
+          NEXT_STATE <= WAIT_FOR_TIMER;\r
+        else\r
+          NEXT_STATE <= IDLE;\r
+        end if;\r
+\r
+      when WAIT_FOR_TIMER =>\r
+        STATE_OUT <= x"2";\r
+        tx_pcs_rst_ch_c_int <= '1';\r
+        if( timer = '1' ) then\r
+          if( tx_pll_lol_all_q = '0' ) then\r
+            NEXT_STATE <= SYNC_ALL;\r
+          else\r
+            NEXT_STATE <= IDLE; -- restart timer\r
+          end if;\r
+        else\r
+          NEXT_STATE <= WAIT_FOR_TIMER;\r
+        end if;\r
+\r
+      when SYNC_ALL =>\r
+        STATE_OUT <= x"3";\r
+        tx_pcs_rst_ch_c_int <= '1';\r
+        reset_timer <= '1';\r
+        sync_tx_quad_int <= '1';\r
+        NEXT_STATE <= SYNC_DONE;\r
+\r
+      when SYNC_DONE =>\r
+        STATE_OUT <= x"4";\r
+        if( timer = '1' ) then\r
+          NEXT_STATE <= NORMAL;\r
+        else\r
+          NEXT_STATE <= SYNC_DONE;\r
+        end if;\r
+\r
+      when NORMAL =>\r
+        STATE_OUT <= x"5";\r
+        tx_pcs_rst_ch_c_int <= '0';\r
+        link_tx_ready_int <= '1';\r
+        reset_timer <= '1';\r
+        if( (tx_pll_lol_all_q = '1') or (tx_clock_avail_q = '0') ) then\r
+          NEXT_STATE <= IDLE;\r
+        else\r
+          NEXT_STATE <= NORMAL;\r
+        end if;\r
+\r
+      when others =>\r
+        STATE_OUT <= x"f";\r
+        NEXT_STATE <= IDLE;\r
+\r
+    end case;\r
+\r
+  end process THE_FSM_DECODE_PROC;\r
+\r
+  -- TX serializer is operational "at level" of this signal, \r
+  -- and gets reset by a transition (according to SerDes Usage Guide).\r
+  -- Timer1 is used to delay the TX link ready signal by some cycles.\r
+  THE_QUAD_SYNC_PROC: process( CLK_REF, CLEAR )\r
+  begin\r
+    if( CLEAR = '1' ) then\r
+      sync_tx_quad_trans <= '0';\r
+    else \r
+      if( rising_edge(CLK_REF) ) then\r
+        if( sync_tx_quad_int = '1' ) then\r
+          sync_tx_quad_trans <= not sync_tx_quad_trans;\r
+        end if;\r
+      end if;\r
+    end if;\r
+  end process THE_QUAD_SYNC_PROC;\r
+\r
+  SYNC_TX_QUAD_OUT <= sync_tx_quad_trans;\r
+\r
+end architecture gbe_tx_reset_arch;\r
index 4445656eb32f2e477442a8e6d11a279b88b64cc3..dd863f99544c27d73fc01c9b00fe2aba5596561d 100644 (file)
@@ -71,36 +71,6 @@ architecture trb_net_i2cwire_arch of trb_net_i2cwire is
 \r
   signal sda_drv             : std_logic;\r
   signal scl_drv             : std_logic;\r
-  \r
-  -- Components\r
-  component i2c_slim is\r
-    port(\r
-      CLOCK          : in  std_logic;\r
-      RESET          : in  std_logic;\r
-      -- I2C command / setup\r
-      I2C_GO_IN      : in  std_logic; -- startbit to trigger I2C actions\r
-      ACTION_IN      : in  std_logic; -- '0' -> write, '1' -> read\r
-      WORD_IN        : in  std_logic; -- '0' -> byte, '1' -> word\r
-      I2C_SPEED_IN   : in  std_logic_vector(5 downto 0); -- speed adjustment (to be defined)\r
-      I2C_ADDR_IN    : in  std_logic_vector(7 downto 0); -- I2C address byte (R/W bit is ignored)\r
-      I2C_CMD_IN     : in  std_logic_vector(7 downto 0); -- I2C command byte (sent after address byte)\r
-      I2C_DW_IN      : in  std_logic_vector(15 downto 0); -- data word for write command\r
-      I2C_DR_OUT     : out std_logic_vector(15 downto 0); -- data word from read command\r
-      STATUS_OUT     : out std_logic_vector(7 downto 0); -- status and error bits\r
-      VALID_OUT      : out std_logic;\r
-      I2C_BUSY_OUT   : out std_logic;\r
-      I2C_DONE_OUT   : out std_logic;\r
-      -- I2C connections\r
-      SDA_IN         : in  std_logic;\r
-      SDA_OUT        : out std_logic;\r
-      SCL_IN         : in  std_logic;\r
-      SCL_OUT        : out std_logic;\r
-      -- Debug\r
-      BSM_OUT        : out std_logic_vector(4 downto 0)\r
-    );\r
-  end component i2c_slim;\r
-\r
-\r
 \r
 begin\r
 \r
@@ -316,7 +286,7 @@ begin
   end if;\r
 end process THE_TIME_COUNTER_PROC;\r
 \r
-THE_I2C_SLIM: i2c_slim \r
+THE_I2C_SLIM: entity i2c_slim \r
 port map(\r
   CLOCK            => CLK,\r
   RESET            => RESET,\r
index b3b2090262543514585f90752c86ccd2f30c1b4c..b59c2d7e7010151928da5b308c065ff8098a3d1e 100644 (file)
@@ -72,35 +72,6 @@ architecture trb_net_i2cwire2_arch of trb_net_i2cwire2 is
 \r
   signal sda_drv             : std_logic;\r
   signal scl_drv             : std_logic;\r
-  \r
-  -- Components\r
-  component i2c_slim2 is\r
-    port(\r
-      CLOCK           : in  std_logic;\r
-      RESET           : in  std_logic;\r
-      -- I2C command / setup\r
-      I2C_GO_IN       : in  std_logic; -- startbit to trigger I2C actions\r
-      ACTION_IN       : in  std_logic; -- '0' -> write, '1' -> read\r
-      WORD_IN         : in  std_logic; -- '0' -> byte, '1' -> word\r
-      DIRECT_IN       : in  std_logic; -- '0' -> normal access, '1' -> direct read\r
-      I2C_SPEED_IN    : in  std_logic_vector(5 downto 0); -- speed adjustment (to be defined)\r
-      I2C_ADDR_IN     : in  std_logic_vector(7 downto 0); -- I2C address byte (R/W bit is ignored)\r
-      I2C_CMD_IN      : in  std_logic_vector(7 downto 0); -- I2C command byte (sent after address byte)\r
-      I2C_DW_IN       : in  std_logic_vector(15 downto 0); -- data word for write command\r
-      I2C_DR_OUT      : out std_logic_vector(15 downto 0); -- data word from read command\r
-      STATUS_OUT      : out std_logic_vector(7 downto 0); -- status and error bits\r
-      VALID_OUT       : out std_logic;\r
-      I2C_BUSY_OUT    : out std_logic;\r
-      I2C_DONE_OUT    : out std_logic;\r
-      -- I2C connections\r
-      SDA_IN          : in  std_logic;\r
-      SDA_OUT         : out std_logic;\r
-      SCL_IN          : in  std_logic;\r
-      SCL_OUT         : out std_logic;\r
-      -- Debug\r
-      BSM_OUT         : out std_logic_vector(3 downto 0)\r
-    );\r
-  end component i2c_slim2;\r
 \r
 begin\r
 \r
@@ -331,7 +302,7 @@ begin
   end if;\r
 end process THE_TIME_COUNTER_PROC;\r
 \r
-THE_I2C_SLIM: i2c_slim2 \r
+THE_I2C_SLIM: entity i2c_slim2 \r
 port map(\r
   CLOCK            => CLK,\r
   RESET            => RESET,\r
index f4565facddaa53cb4111cfed4a6e7666e85b6ea7..991b11ad4e40a9066735185fa1c78b3f05b02f16 100644 (file)
@@ -225,111 +225,90 @@ begin
 ---------------------------------------
 -- a sbuf (to_int direction)
 ---------------------------------------
---  gen_int_sbuf : if SECURE_MODE_TO_INT = 1 generate
-    SBUF: trb_net16_sbuf
-      generic map (
-        VERSION    => SBUF_VERSION)
-      port map (
-        CLK    => CLK,
-        RESET  => RESET,
-        CLK_EN => CLK_EN,
-        COMB_DATAREADY_IN  => next_INT_MASTER_DATAREADY_OUT,
-        COMB_next_READ_OUT => sbuf_next_READ,
-        COMB_READ_IN       => '1',
-        COMB_DATA_IN       => next_INT_MASTER_DATA_OUT,
-        COMB_PACKET_NUM_IN => next_INT_MASTER_PACKET_NUM_OUT,
-        SYN_DATAREADY_OUT  => buf_INT_MASTER_DATAREADY_OUT,
-        SYN_DATA_OUT       => INT_MASTER_DATA_OUT,
-        SYN_PACKET_NUM_OUT => buf_INT_MASTER_PACKET_NUM_OUT,
-        SYN_READ_IN        => INT_MASTER_READ_IN,
-        STAT_BUFFER        => sbuf_status(0)
-        );
+  SBUF: trb_net16_sbuf
+    generic map (
+      VERSION    => SBUF_VERSION)
+    port map (
+      CLK    => CLK,
+      RESET  => RESET,
+      CLK_EN => CLK_EN,
+      COMB_DATAREADY_IN  => next_INT_MASTER_DATAREADY_OUT,
+      COMB_next_READ_OUT => sbuf_next_READ,
+      COMB_READ_IN       => '1',
+      COMB_DATA_IN       => next_INT_MASTER_DATA_OUT,
+      COMB_PACKET_NUM_IN => next_INT_MASTER_PACKET_NUM_OUT,
+      SYN_DATAREADY_OUT  => buf_INT_MASTER_DATAREADY_OUT,
+      SYN_DATA_OUT       => INT_MASTER_DATA_OUT,
+      SYN_PACKET_NUM_OUT => buf_INT_MASTER_PACKET_NUM_OUT,
+      SYN_READ_IN        => INT_MASTER_READ_IN,
+      STAT_BUFFER        => sbuf_status(0)
+    );
 
-    process(CLK)
-      begin
-        if rising_edge(CLK) then
-          if RESET = '1' then
-            sbuf_free <= '0';
-          elsif CLK_EN = '1' then
-            sbuf_free <= sbuf_next_READ or INT_MASTER_READ_IN;
-          end if;
+  process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          sbuf_free <= '0';
+        elsif CLK_EN = '1' then
+          sbuf_free <= sbuf_next_READ or INT_MASTER_READ_IN;
         end if;
-      end process;
---  end generate;
-
---   gen_int_nonsbuf : if SECURE_MODE_TO_INT = 0 generate
---     buf_INT_MASTER_DATAREADY_OUT <= next_INT_MASTER_DATAREADY_OUT;
---     INT_MASTER_DATA_OUT <= next_INT_MASTER_DATA_OUT;
---     buf_INT_MASTER_PACKET_NUM_OUT <= next_INT_MASTER_PACKET_NUM_OUT;
---     sbuf_free <= INT_MASTER_READ_IN;
---   end generate;
+      end if;
+    end process;
 
 INT_MASTER_PACKET_NUM_OUT <= buf_INT_MASTER_PACKET_NUM_OUT;
 INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
 
-
 ---------------------------------------
 -- a sbuf (to_apl direction)
 ---------------------------------------
---   gen_apl_sbuf : if SECURE_MODE_TO_APL = 1 generate
-    SBUF_TO_APL: trb_net16_sbuf
-      generic map (
-        VERSION    => SBUF_VERSION)
-      port map (
-        CLK    => CLK,
-        RESET  => RESET,
-        CLK_EN => CLK_EN,
-        COMB_DATAREADY_IN  => next_APL_DATAREADY_OUT,
-        COMB_next_READ_OUT => sbuf_to_apl_next_READ,
-        COMB_READ_IN       => '1',
-        COMB_DATA_IN       => next_APL_DATA_OUT,
-        COMB_PACKET_NUM_IN => next_APL_PACKET_NUM_OUT,
-        SYN_DATAREADY_OUT  => reg_APL_DATAREADY_OUT,
-        SYN_DATA_OUT       => reg_APL_DATA_OUT,
-        SYN_PACKET_NUM_OUT => reg_APL_PACKET_NUM_OUT,
-        SYN_READ_IN        => APL_READ_IN,
-        STAT_BUFFER        => sbuf_status(1)
-        );
-
+  SBUF_TO_APL: trb_net16_sbuf
+    generic map (
+      VERSION    => SBUF_VERSION)
+    port map (
+      CLK    => CLK,
+      RESET  => RESET,
+      CLK_EN => CLK_EN,
+      COMB_DATAREADY_IN  => next_APL_DATAREADY_OUT,
+      COMB_next_READ_OUT => sbuf_to_apl_next_READ,
+      COMB_READ_IN       => '1',
+      COMB_DATA_IN       => next_APL_DATA_OUT,
+      COMB_PACKET_NUM_IN => next_APL_PACKET_NUM_OUT,
+      SYN_DATAREADY_OUT  => reg_APL_DATAREADY_OUT,
+      SYN_DATA_OUT       => reg_APL_DATA_OUT,
+      SYN_PACKET_NUM_OUT => reg_APL_PACKET_NUM_OUT,
+      SYN_READ_IN        => APL_READ_IN,
+      STAT_BUFFER        => sbuf_status(1)
+    );
 
-    SBUF_TO_APL2: trb_net_sbuf
-      generic map (
-        VERSION    => SBUF_VERSION,
-        DATA_WIDTH => 3)
-      port map (
-        CLK    => CLK,
-        RESET  => RESET,
-        CLK_EN => CLK_EN,
-        COMB_DATAREADY_IN  => next_APL_DATAREADY_OUT,
-        COMB_next_READ_OUT => open,
-        COMB_READ_IN       => '1',
-        COMB_DATA_IN       => next_APL_TYP_OUT,
-        SYN_DATAREADY_OUT  => sbuf_apl_type_dataready,
-        SYN_DATA_OUT       => buf_APL_TYP_OUT,
-        SYN_READ_IN        => APL_READ_IN,
-        STAT_BUFFER        => sbuf_status(2)
-        );
+  SBUF_TO_APL2: trb_net_sbuf
+    generic map (
+      VERSION    => SBUF_VERSION,
+      DATA_WIDTH => 3)
+    port map (
+      CLK    => CLK,
+      RESET  => RESET,
+      CLK_EN => CLK_EN,
+      COMB_DATAREADY_IN  => next_APL_DATAREADY_OUT,
+      COMB_next_READ_OUT => open,
+      COMB_READ_IN       => '1',
+      COMB_DATA_IN       => next_APL_TYP_OUT,
+      SYN_DATAREADY_OUT  => sbuf_apl_type_dataready,
+      SYN_DATA_OUT       => buf_APL_TYP_OUT,
+      SYN_READ_IN        => APL_READ_IN,
+      STAT_BUFFER        => sbuf_status(2)
+    );
 
-    reg_APL_TYP_OUT <= TYPE_ILLEGAL when reg_APL_DATAREADY_OUT = '0' else buf_APL_TYP_OUT;
-    process(CLK)
-      begin
-        if rising_edge(CLK) then
-          if RESET = '1' then
-            sbuf_to_apl_free <= '0';
-          elsif CLK_EN = '1' then
-            sbuf_to_apl_free <= sbuf_to_apl_next_READ;
-          end if;
+  reg_APL_TYP_OUT <= TYPE_ILLEGAL when reg_APL_DATAREADY_OUT = '0' else buf_APL_TYP_OUT;
+  process(CLK)
+    begin
+      if rising_edge(CLK) then
+        if RESET = '1' then
+          sbuf_to_apl_free <= '0';
+        elsif CLK_EN = '1' then
+          sbuf_to_apl_free <= sbuf_to_apl_next_READ;
         end if;
-      end process;
---   end generate;
-
---   gen_apl_nonsbuf : if SECURE_MODE_TO_APL = 0 generate
---     reg_APL_DATAREADY_OUT  <= next_APL_DATAREADY_OUT;
---     reg_APL_DATA_OUT       <= next_APL_DATA_OUT;
---     reg_APL_PACKET_NUM_OUT <= next_APL_PACKET_NUM_OUT;
---     reg_APL_TYP_OUT        <= next_APL_TYP_OUT;
---     sbuf_to_apl_free       <= APL_READ_IN;
---   end generate;
+      end if;
+    end process;
 
   next_APL_DATA_OUT       <= fifo_to_apl_data_out;
   next_APL_PACKET_NUM_OUT <= fifo_to_apl_long_packet_num_out;
@@ -344,7 +323,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
 -- save packet type
 ---------------------------------------
 
-  process(CLK)
+  process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -361,8 +340,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
 -- select data for int direction
 ---------------------------------------
 
-
-  process(current_combined_header, current_registered_trailer, current_data, out_select)
+  process( current_combined_header, current_registered_trailer, current_data, out_select )
     begin
       case out_select is
         when HDR      => next_INT_MASTER_DATA_OUT <= current_combined_header;
@@ -372,8 +350,6 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
       end case;
     end process;
 
-
-
   process(master_counter, fifo_to_int_data_out, registered_trailer_F1,
           registered_trailer_F2, registered_trailer_F3, registered_trailer_F0,
           registered_header_F0, registered_header_F1, registered_header_F2,
@@ -424,48 +400,29 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
 -- fifo to apl
 ---------------------------------------
 
---   GEN_FIFO_TO_APL:   if FIFO_TO_APL_DEPTH >0 generate
-    FIFO_TO_APL: trb_net16_fifo
-      generic map (
-        DEPTH => FIFO_TO_APL_DEPTH,
-        USE_VENDOR_CORES => USE_VENDOR_CORES)
-      port map (
-        CLK       => CLK,
-        RESET     => RESET,
-        CLK_EN    => CLK_EN,
-        DATA_IN         => fifo_to_apl_data_in,
-        PACKET_NUM_IN   => fifo_to_apl_packet_num_in,
-        WRITE_ENABLE_IN => fifo_to_apl_write,
-        DATA_OUT        => next_fifo_to_apl_data_out,
-        PACKET_NUM_OUT  => next_fifo_to_apl_packet_num_out,
-        READ_ENABLE_IN  => fifo_to_apl_read,
-        DATA_COUNT_OUT  => fifo_to_apl_data_count,
-        FULL_OUT        => fifo_to_apl_full,
-        EMPTY_OUT       => next_fifo_to_apl_empty
-        );
---   end generate;
-
---   GEN_DUMMY_FIFO_TO_APL: if FIFO_TO_APL_DEPTH = 0 generate
---     FIFO_TO_APL: trb_net16_dummy_fifo
---       port map (
---         CLK       => CLK,
---         RESET     => RESET,
---         CLK_EN    => CLK_EN,
---         DATA_IN         => fifo_to_apl_data_in,
---         PACKET_NUM_IN   => fifo_to_apl_packet_num_in,
---         WRITE_ENABLE_IN => fifo_to_apl_write,
---         DATA_OUT        => next_fifo_to_apl_data_out,
---         PACKET_NUM_OUT  => next_fifo_to_apl_packet_num_out,
---         READ_ENABLE_IN  => fifo_to_apl_read,
---         FULL_OUT        => fifo_to_apl_full,
---         EMPTY_OUT       => next_fifo_to_apl_empty
---         );
---   end generate;
+  FIFO_TO_APL: trb_net16_fifo
+    generic map (
+      DEPTH => FIFO_TO_APL_DEPTH,
+      USE_VENDOR_CORES => USE_VENDOR_CORES)
+    port map (
+      CLK       => CLK,
+      RESET     => RESET,
+      CLK_EN    => CLK_EN,
+      DATA_IN         => fifo_to_apl_data_in,
+      PACKET_NUM_IN   => fifo_to_apl_packet_num_in,
+      WRITE_ENABLE_IN => fifo_to_apl_write,
+      DATA_OUT        => next_fifo_to_apl_data_out,
+      PACKET_NUM_OUT  => next_fifo_to_apl_packet_num_out,
+      READ_ENABLE_IN  => fifo_to_apl_read,
+      DATA_COUNT_OUT  => fifo_to_apl_data_count,
+      FULL_OUT        => fifo_to_apl_full,
+      EMPTY_OUT       => next_fifo_to_apl_empty
+    );
 
 ---------------------------------------
 -- keep track of fifo to apl read operations
 ---------------------------------------
-   process(CLK)
+   process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -561,7 +518,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
 -- keep track of fifo to int read operations
 ---------------------------------------
 
-   process(CLK)
+   process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -578,7 +535,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
       end if;
     end process;
 
-  process(CLK)
+  process( CLK )
     begin
       if rising_edge(CLK) then
         if APL_SEND_IN = '1' then
@@ -597,7 +554,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
   fifo_to_int_long_packet_num_out(0) <= fifo_to_int_packet_num_out(0);
   fifo_to_int_long_packet_num_out(1) <= not saved_fifo_to_int_long_packet_num_out(1) when last_fifo_to_int_read = '1' and not saved_fifo_to_int_long_packet_num_out(2) = '1' and saved_fifo_to_int_long_packet_num_out(0) = '1' else saved_fifo_to_int_long_packet_num_out(1);
 
-  process(CLK)
+  process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -613,7 +570,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
   fifo_to_apl_long_packet_num_out(0) <= fifo_to_apl_packet_num_out(0);
   fifo_to_apl_long_packet_num_out(1) <= not saved_fifo_to_apl_long_packet_num_out(1) when last_fifo_to_apl_read = '1' and not saved_fifo_to_apl_long_packet_num_out(2) = '1' and saved_fifo_to_apl_long_packet_num_out(0) = '1' else saved_fifo_to_apl_long_packet_num_out(1);
 
-  process(CLK)
+  process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -624,8 +581,6 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
       end if;
     end process;
 
-
-
 ---------------------------------------
 --state machine for direction to APL
 ---------------------------------------
@@ -792,7 +747,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
       end process;
 
 
-  PROC_FSM_REG : process(CLK)
+  PROC_FSM_REG: process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -815,7 +770,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
       end if;
     end process;
 
-  PROC_SEQ_CNT : process(CLK)
+  PROC_SEQ_CNT: process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' or CTRL_SEQNR_RESET = '1' then
@@ -826,8 +781,6 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
       end if;
     end process;
 
-
-
   PROC_ENDP_REACHED : process(CLK)
     begin
       if rising_edge(CLK) then
@@ -841,14 +794,10 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
       end if;
     end process;
 
-
-
-
 ---------------------------------------------------------------------
 --Connection to FIFOs
 ---------------------------------------------------------------------
 
-
   -- connect Transmitter port
   fifo_to_int_data_in       <= APL_DATA_IN;
   fifo_to_int_packet_num_in <= APL_PACKET_NUM_IN(2) & APL_PACKET_NUM_IN(0);
@@ -865,7 +814,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
 --Running Signals
 ---------------------------------------------------------------------
 
-  RUN_OUT_gen : process(CLK)
+  RUN_OUT_gen: process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -889,7 +838,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
     end process;
   APL_RUN_OUT <= buf_APL_RUN_OUT;
 
-  RUNNING_gen : process(CLK)
+  RUNNING_gen: process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -914,7 +863,6 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
 --Header & Trailer Words
 ---------------------------------------------------------------------
 
-
   --get target address from active APL
   gentarget1: if API_TYPE = 1 generate
     combined_header_F1 <= APL_TARGET_ADDRESS_IN;
@@ -922,7 +870,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
 
   --save target address for passive api
   gentarget0: if API_TYPE = 0 generate
-    reg_hdr_f1: process(CLK)
+    reg_hdr_f1: process( CLK )
       begin
         if rising_edge(CLK) then
           if RESET = '1' then
@@ -950,7 +898,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
   combined_trailer_F3(11 downto 4)  <= sequence_counter;  -- SEQNR
   combined_trailer_F3(3 downto 0)   <= APL_DTYPE_IN;
 
-  PROC_REG3 : process(CLK)
+  PROC_REG3: process( CLK )
     begin
       if rising_edge(CLK) then
         if update_registered_trailer = '1' then
@@ -967,7 +915,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
       end if;
     end process;
 
-  PROC_REG_HDR : process(CLK)
+  PROC_REG_HDR: process( CLK )
     begin
       if rising_edge(CLK) then
         if update_registered_header = '1' then
@@ -983,7 +931,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
 --Decode FSM states
 ---------------------------------------------------------------------
 
-  process(state_to_apl)
+  process( state_to_apl )
     begin
       case state_to_apl is
         when sa_IDLE         => state_bits_to_apl <= "000";
@@ -994,7 +942,7 @@ INT_MASTER_DATAREADY_OUT  <= buf_INT_MASTER_DATAREADY_OUT;
       end case;
     end process;
 
-  process(state_to_int)
+  process( state_to_int )
     begin
       case state_to_int is
         when IDLE         => state_bits_to_int <= "000";
index 39404ca62eede0c3db816e35a2078d0dd3a6b36e..e186f7cc0ee5cc0d79de3b3bea752fd924b38be3 100644 (file)
@@ -9,7 +9,6 @@ use work.trb_net_std.all;
 use work.trb_net_components.all;
 use work.config.all;
 
-
 entity trb_net16_endpoint_standalone_sctrl is
   generic (
     FIFO_TO_INT_DEPTH            : integer := 6;
index 23e3d6e03ea1bfd154d2cbc640885a990fbd78e1..27d1870e946609412c39e6e9c423ac760052ca03 100644 (file)
@@ -8,9 +8,6 @@ use work.trb_net_components.all;
 use work.version.all;
 use work.config.all;
 
-
-
-
 entity trb_net16_regIO is
   generic (
     NUM_STAT_REGS      : integer range 0 to 6 := 3; --log2 of number of status registers
@@ -197,7 +194,7 @@ begin
 ---------------------------------------------------------------------
 --5bit address decoder for registers
 ---------------------------------------------------------------------
-  pattern_gen_inst : trb_net_pattern_gen
+  pattern_gen_inst: trb_net_pattern_gen
     generic map(
       WIDTH => 5
       )
@@ -211,7 +208,7 @@ begin
 -- trbnet addresses
 ---------------------------------------------------------------------
 
-  the_addresses : trb_net16_addresses
+  the_addresses: trb_net16_addresses
     generic map(
       INIT_ADDRESS     => INIT_ADDRESS,
       INIT_UNIQUE_ID   => INIT_UNIQUE_ID,
@@ -241,12 +238,11 @@ begin
       STAT_DEBUG        => buf_STAT_ADDR_DEBUG
       );
 
-
 ---------------------------------------------------------------------
 -- Main State Machine
 ---------------------------------------------------------------------
 
-  fsm : process(API_DATA_IN, API_PACKET_NUM_IN, API_TYP_IN, API_DATAREADY_IN, API_READ_IN,
+  fsm: process(API_DATA_IN, API_PACKET_NUM_IN, API_TYP_IN, API_DATAREADY_IN, API_READ_IN,
                 address, saved_Reg_high, saved_Reg_low, saved_operation, current_state,
                 buf_API_SEND_OUT, next_packet_counter, buf_API_DATA_OUT, buf_API_SHORT_TRANSFER_OUT,
                 REGISTERS_IN, buf_REGISTERS_OUT, reg_enable_pattern, DAT_NO_MORE_DATA_IN,
@@ -664,7 +660,7 @@ begin
    end process;
 
 
-  reg_fsm : process(CLK)
+  reg_fsm: process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -716,7 +712,7 @@ begin
 ---------------------------------------------------------------------
 -- Packet Numbers
 ---------------------------------------------------------------------
-  reg_packet_counter : process(CLK)
+  reg_packet_counter: process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -727,7 +723,7 @@ begin
       end if;
     end process;
 
-  next_packet_counter_proc : process(API_READ_IN, buf_API_DATAREADY_OUT, packet_counter)
+  next_packet_counter_proc: process( API_READ_IN, buf_API_DATAREADY_OUT, packet_counter )
     begin
       if buf_API_DATAREADY_OUT = '1' and API_READ_IN = '1' then
         if packet_counter =  "011" then
@@ -743,7 +739,7 @@ begin
 ---------------------------------------------------------------------
 -- Generate output to API
 ---------------------------------------------------------------------
-  process(CLK)
+  process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1' then
@@ -792,7 +788,7 @@ begin
 -- Read from DAT port
 ---------------------------------------------------------------------
 --save Dataready_in in case API can not read immediately
-  process(CLK)
+  process( CLK )
     begin
       if rising_edge(CLK) then
         if RESET = '1'  or current_state = IDLE then
@@ -805,7 +801,7 @@ begin
       end if;
     end process;
 
-  process(CLK)
+  process( CLK )
     begin
       if rising_edge(CLK) then
         if DAT_DATAREADY_IN = '1' then
@@ -974,7 +970,7 @@ begin
   COMMON_CTRL_REG_OUT    <= buf_COMMON_CTRL_REG_OUT;
 
 
-  PROC_STROBES : process(CLK)
+  PROC_STROBES: process( CLK )
     begin
       if rising_edge(CLK) then
         COMMON_STAT_REG_STROBE <= next_COMMON_STAT_REG_STROBE;
@@ -1009,7 +1005,7 @@ begin
   STAT(30) <= API_READ_IN;
   STAT(31) <= '0';
 
-  process(current_state)
+  process( current_state )
     begin
       case current_state is
         when IDLE         => state_bits <= "0000";
@@ -1031,7 +1027,6 @@ begin
       end case;
     end process;
 
-
   STAT_ADDR_DEBUG(2 downto 0)  <= state_bits(2 downto 0);
   STAT_ADDR_DEBUG(3)  <= ADR_DONT_UNDERSTAND;
   STAT_ADDR_DEBUG(4)  <= API_DATAREADY_IN;
@@ -1043,7 +1038,4 @@ begin
   STAT_ADDR_DEBUG(14) <= ADR_SEND_OUT;
   STAT_ADDR_DEBUG(15) <= ADR_DATAREADY_OUT;
 
-
-
 end architecture;
-