From 5be96dc4e6f0d9d0ef19f415de2082fbcae1e2fa Mon Sep 17 00:00:00 2001 From: Michael Boehmer Date: Tue, 8 Nov 2022 11:28:43 +0100 Subject: [PATCH] ARP and Ping working, Ping to be reviewed. SCTRL still dead. --- gbe_trb/base/gbe_frame_receiver.vhd | 54 +++--- .../gbe_response_constructor_ARP.vhd | 172 +++++++++--------- .../gbe_response_constructor_DHCP.vhd | 37 ++-- 3 files changed, 139 insertions(+), 124 deletions(-) diff --git a/gbe_trb/base/gbe_frame_receiver.vhd b/gbe_trb/base/gbe_frame_receiver.vhd index a805030..3b86ac8 100644 --- a/gbe_trb/base/gbe_frame_receiver.vhd +++ b/gbe_trb/base/gbe_frame_receiver.vhd @@ -117,8 +117,6 @@ architecture gbe_frame_receiver_arch of gbe_frame_receiver is signal drop_frame_x : std_logic; signal drop_frame : std_logic; - signal fifo_wr_en : std_logic; - begin -- buffer incoming signals @@ -301,36 +299,36 @@ begin -- end if; -- end process PROC_DECODE_CTR; - -- counter for decoding the byte stream - PROC_DECODE_CTR: process( CLK, RESET ) - begin - if ( RESET = '1' ) then - decode_ctr <= (others => '0'); + -- counter for decoding the byte stream + PROC_DECODE_CTR: process( CLK, RESET ) + begin + if ( RESET = '1' ) then + decode_ctr <= (others => '0'); elsif( rising_edge(CLK) ) then if ( (DECODE_CS /= STORE_HEADER) and (DECODE_CS /= STORE_FRAME) ) then - decode_ctr <= (others => '0'); - elsif( ((DECODE_CS = STORE_HEADER) or (DECODE_CS = STORE_FRAME)) and (MAC_RX_EN_IN = '1') ) then - decode_ctr <= decode_ctr + 1; - end if; - end if; - end process PROC_DECODE_CTR; + decode_ctr <= (others => '0'); + elsif( ((DECODE_CS = STORE_HEADER) or (DECODE_CS = STORE_FRAME)) and (MAC_RX_EN_IN = '1') ) then + decode_ctr <= decode_ctr + 1; + end if; + end if; + end process PROC_DECODE_CTR; -- write only if data stream is available! - PROC_RX_FIFO_SYNC: process( CLK ) - begin - if( rising_edge(CLK) ) then - if( MAC_RX_EN_IN = '1' ) then - if ( DECODE_NS = STORE_FRAME ) then - fifo_pl_wr <= '1'; - elsif( (DECODE_CS = STORE_FRAME) and (DECODE_NS = LAST_BYTE) ) then - fifo_pl_wr <= '1'; - else - fifo_pl_wr <= '0'; - end if; - else - fifo_pl_wr <= '0'; - end if; - end if; + PROC_RX_FIFO_SYNC: process( CLK ) + begin + if( rising_edge(CLK) ) then + if( MAC_RX_EN_IN = '1' ) then + if ( DECODE_NS = STORE_FRAME ) then + fifo_pl_wr <= '1'; + elsif( (DECODE_CS = STORE_FRAME) and (DECODE_NS = LAST_BYTE) ) then + fifo_pl_wr <= '1'; + else + fifo_pl_wr <= '0'; + end if; + else + fifo_pl_wr <= '0'; + end if; + end if; end process PROC_RX_FIFO_SYNC; -- storing the relevant parts of headers for decision and further usage diff --git a/gbe_trb/protocols/gbe_response_constructor_ARP.vhd b/gbe_trb/protocols/gbe_response_constructor_ARP.vhd index 5533b64..6372d4e 100644 --- a/gbe_trb/protocols/gbe_response_constructor_ARP.vhd +++ b/gbe_trb/protocols/gbe_response_constructor_ARP.vhd @@ -10,7 +10,7 @@ library work; -- BUG: check (length == 28) for correct request. -- BUG: check request type at all. - + entity gbe_response_constructor_ARP is port ( CLK : in std_logic; -- system clock @@ -49,9 +49,9 @@ architecture gbe_response_constructor_ARP_arch of gbe_response_constructor_ARP i 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 DISSECT_STATES is (IDLE, READ_FRAME, DELAY, DECIDE, LOAD_FRAME, WAIT_FOR_LOAD, CLEANUP); + signal DISSECT_CS, DISSECT_NS : DISSECT_STATES; + attribute syn_encoding of DISSECT_CS: signal is "onehot"; type stats_states is (IDLE, LOAD_SENT, LOAD_RECEIVED, CLEANUP); signal stats_current_state, stats_next_state : stats_states; @@ -60,16 +60,10 @@ architecture gbe_response_constructor_ARP_arch of gbe_response_constructor_ARP i 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 dissect_ctr : unsigned(7 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; @@ -78,98 +72,90 @@ architecture gbe_response_constructor_ARP_arch of gbe_response_constructor_ARP i 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 - PROC_DISSECT_FSM: process( CLK, RESET ) begin if ( RESET = '1' ) then - dissect_current_state <= IDLE; + DISSECT_CS <= IDLE; elsif( rising_edge(CLK) ) then - dissect_current_state <= dissect_next_state; + DISSECT_CS <= DISSECT_NS; end if; end process PROC_DISSECT_FSM; - PROC_DISSECT_TRANSITIONS : 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 ) + PROC_DISSECT_TRANSITIONS : process( DISSECT_CS, MY_IP_IN, PS_WR_EN_IN, PS_ACTIVATE_IN, + PS_DATA_IN, dissect_ctr, PS_SELECTED_IN, saved_target_ip ) begin - case dissect_current_state is + case DISSECT_CS is when IDLE => state <= x"1"; if( (PS_WR_EN_IN = '1') and (PS_ACTIVATE_IN = '1') ) then - dissect_next_state <= READ_FRAME; + DISSECT_NS <= READ_FRAME; else - dissect_next_state <= IDLE; + DISSECT_NS <= IDLE; end if; when READ_FRAME => state <= x"2"; + -- BUG: fails on empty payload if( PS_DATA_IN(8) = '1' ) then - dissect_next_state <= DECIDE; + DISSECT_NS <= DELAY; else - dissect_next_state <= READ_FRAME; + DISSECT_NS <= READ_FRAME; end if; + + when DELAY => + DISSECT_NS <= DECIDE; when DECIDE => state <= x"3"; if( saved_target_ip = MY_IP_IN ) then - dissect_next_state <= WAIT_FOR_LOAD; + DISSECT_NS <= WAIT_FOR_LOAD; -- in case the request is not for me, drop it else - dissect_next_state <= IDLE; + DISSECT_NS <= IDLE; end if; when WAIT_FOR_LOAD => state <= x"4"; if( PS_SELECTED_IN = '1' ) then - dissect_next_state <= LOAD_FRAME; + DISSECT_NS <= LOAD_FRAME; else - dissect_next_state <= WAIT_FOR_LOAD; + DISSECT_NS <= WAIT_FOR_LOAD; end if; when LOAD_FRAME => state <= x"5"; - if( data_ctr = 28 ) then - dissect_next_state <= CLEANUP; + if( dissect_ctr = x"1c" ) then + DISSECT_NS <= CLEANUP; else - dissect_next_state <= LOAD_FRAME; + DISSECT_NS <= LOAD_FRAME; end if; when CLEANUP => state <= x"e"; - dissect_next_state <= IDLE; + DISSECT_NS <= IDLE; end case; end process PROC_DISSECT_TRANSITIONS; - PROC_DATA_CTR: process( CLK, RESET ) + PROC_DISSEC_CTR: process( CLK, RESET ) begin if ( RESET = '1' ) then - data_ctr <= 0; --- data_ctr <= 1; + dissect_ctr <= (others => '0'); elsif( rising_edge(CLK) ) then - if ( (dissect_current_state = IDLE) and (PS_WR_EN_IN = '0') ) then - data_ctr <= 0; --- 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; + if ( (DISSECT_CS = IDLE) and (PS_WR_EN_IN = '0') ) then + dissect_ctr <= (others => '0'); + elsif( (DISSECT_CS = DECIDE) ) then + dissect_ctr <= (others => '0'); + elsif( (DISSECT_CS = IDLE) and (PS_WR_EN_IN = '1') and (PS_ACTIVATE_IN = '1') ) then + dissect_ctr <= dissect_ctr + 1; + elsif( (DISSECT_CS = READ_FRAME) and (PS_WR_EN_IN = '1') and (PS_ACTIVATE_IN = '1') ) then -- in case of saving data from incoming frame + dissect_ctr <= dissect_ctr + 1; + elsif( (DISSECT_CS = LOAD_FRAME) and (PS_SELECTED_IN = '1') and (TC_RD_EN_IN = '1') ) then -- in case of constructing response + dissect_ctr <= dissect_ctr + 1; end if; end if; - end process PROC_DATA_CTR; + end process PROC_DISSEC_CTR; PROC_SAVE_VALUES: process( CLK, RESET ) begin @@ -178,28 +164,28 @@ begin 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 + if( DISSECT_CS = READ_FRAME ) then + case dissect_ctr is - when 6 => + when x"06" => saved_opcode(7 downto 0) <= PS_DATA_IN(7 downto 0); - when 7 => + when x"07" => saved_opcode(15 downto 8) <= PS_DATA_IN(7 downto 0); - when 13 => + when x"0e" => saved_sender_ip(7 downto 0) <= PS_DATA_IN(7 downto 0); - when 14 => + when x"0f" => saved_sender_ip(15 downto 8) <= PS_DATA_IN(7 downto 0); - when 15 => + when x"10" => saved_sender_ip(23 downto 16) <= PS_DATA_IN(7 downto 0); - when 16 => + when x"11" => saved_sender_ip(31 downto 24) <= PS_DATA_IN(7 downto 0); - when 23 => + when x"18" => saved_target_ip(7 downto 0) <= PS_DATA_IN(7 downto 0); - when 24 => + when x"19" => saved_target_ip(15 downto 8) <= PS_DATA_IN(7 downto 0); - when 25 => + when x"1a" => saved_target_ip(23 downto 16) <= PS_DATA_IN(7 downto 0); - when 26 => + when x"1b" => saved_target_ip(31 downto 24) <= PS_DATA_IN(7 downto 0); when others => null; @@ -210,36 +196,56 @@ begin PROC_TC_DATA: 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'); + if( rising_edge(CLK) ) then + tc_data(8) <= '0'; + tc_data(7 downto 0) <= x"00"; + if( DISSECT_CS = LOAD_FRAME ) then + case dissect_ctr is + when x"00" => tc_data(7 downto 0) <= x"00"; -- HWTYPE + when x"01" => tc_data(7 downto 0) <= x"01"; + when x"02" => tc_data(7 downto 0) <= x"08"; -- PTYPE + when x"03" => tc_data(7 downto 0) <= x"00"; + when x"04" => tc_data(7 downto 0) <= x"06"; -- HLEN + when x"05" => tc_data(7 downto 0) <= x"04"; -- PLEN + when x"06" => tc_data(7 downto 0) <= x"00"; -- OPER + when x"07" => tc_data(7 downto 0) <= x"02"; + when x"08" => tc_data(7 downto 0) <= MY_MAC_IN(7 downto 0); -- SHA + when x"09" => tc_data(7 downto 0) <= MY_MAC_IN(15 downto 8); + when x"0a" => tc_data(7 downto 0) <= MY_MAC_IN(23 downto 16); + when x"0b" => tc_data(7 downto 0) <= MY_MAC_IN(31 downto 24); + when x"0c" => tc_data(7 downto 0) <= MY_MAC_IN(39 downto 32); + when x"0d" => tc_data(7 downto 0) <= MY_MAC_IN(47 downto 40); + when x"0e" => tc_data(7 downto 0) <= MY_IP_IN(7 downto 0); -- SPA + when x"0f" => tc_data(7 downto 0) <= MY_IP_IN(15 downto 8); + when x"10" => tc_data(7 downto 0) <= MY_IP_IN(23 downto 16); + when x"11" => tc_data(7 downto 0) <= MY_IP_IN(31 downto 24); + when x"12" => tc_data(7 downto 0) <= PS_SRC_MAC_ADDRESS_IN(7 downto 0); -- THA + when x"13" => tc_data(7 downto 0) <= PS_SRC_MAC_ADDRESS_IN(15 downto 8); + when x"14" => tc_data(7 downto 0) <= PS_SRC_MAC_ADDRESS_IN(23 downto 16); + when x"15" => tc_data(7 downto 0) <= PS_SRC_MAC_ADDRESS_IN(31 downto 24); + when x"16" => tc_data(7 downto 0) <= PS_SRC_MAC_ADDRESS_IN(39 downto 32); + when x"17" => tc_data(7 downto 0) <= PS_SRC_MAC_ADDRESS_IN(47 downto 40); + when x"18" => tc_data(7 downto 0) <= saved_sender_ip(7 downto 0); -- TPA + when x"19" => tc_data(7 downto 0) <= saved_sender_ip(15 downto 8); + when x"1a" => tc_data(7 downto 0) <= saved_sender_ip(23 downto 16); + when x"1b" => tc_data(7 downto 0) <= saved_sender_ip(31 downto 24); tc_data(8) <= '1'; + when others => tc_data(7 downto 0) <= x"00"; + end case; + TC_DATA_OUT <= tc_data; -- delay once clock cycle end if; - - TC_DATA_OUT <= tc_data; - end if; end process PROC_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 + if( (DISSECT_CS = WAIT_FOR_LOAD) or (DISSECT_CS = LOAD_FRAME) or (DISSECT_CS = CLEANUP) ) then PS_RESPONSE_READY_OUT <= '1'; else PS_RESPONSE_READY_OUT <= '0'; end if; - if( dissect_current_state = IDLE ) then + if( DISSECT_CS = IDLE ) then PS_BUSY_OUT <= '0'; else PS_BUSY_OUT <= '1'; diff --git a/gbe_trb/protocols/gbe_response_constructor_DHCP.vhd b/gbe_trb/protocols/gbe_response_constructor_DHCP.vhd index 55ea20e..e0ac074 100644 --- a/gbe_trb/protocols/gbe_response_constructor_DHCP.vhd +++ b/gbe_trb/protocols/gbe_response_constructor_DHCP.vhd @@ -97,10 +97,14 @@ architecture gbe_response_constructor_DHCP_arch of gbe_response_constructor_DHCP attribute syn_keep of cons_state, main_state, recv_state : signal is true; attribute syn_preserve of cons_state, main_state, recv_state : signal is true; - signal wait_value : unsigned(31 downto 0); +-- signal wait_value : unsigned(31 downto 0); + + signal long_delay_bit : integer range 0 to 31 := 29; + signal short_delay_bit : integer range 0 to 31 := 12; begin + -- Debug lines DEBUG_OUT(31 downto 28) <= main_state; DEBUG_OUT(27 downto 24) <= recv_state; DEBUG_OUT(23 downto 20) <= cons_state; @@ -136,11 +140,9 @@ begin 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_OUT <= saved_true_ip when (MAIN_CS) = ESTABLISHED else (others => '0'); - --***************** + -- store the source IP/MAC for reply PROC_SAVE_SERVER_ADDR: process( CLK ) begin if( rising_edge(CLK) ) then @@ -154,9 +156,8 @@ begin end if; end process PROC_SAVE_SERVER_ADDR; - -- **** MAIN MACHINE PART - PROC_MAIN_FSM: process( CLK, RESET) + PROC_MAIN_FSM: process( CLK, RESET ) begin if ( RESET = '1' ) then MAIN_CS <= BOOTING; @@ -165,10 +166,12 @@ begin end if; end process PROC_MAIN_FSM; - wait_value <= x"2000_0000"; + -- wait time between link active and start of DHCP process +-- wait_value <= x"2000_0000"; -- wait_value <= x"0000_2000"; - PROC_MAIN_TRANSITIONS : process( MAIN_CS, DHCP_START_IN, CONSTRUCT_CS, wait_ctr, RECEIVE_CS, PS_DATA_IN, wait_value ) +-- PROC_MAIN_TRANSITIONS : process( MAIN_CS, DHCP_START_IN, CONSTRUCT_CS, wait_ctr, RECEIVE_CS, PS_DATA_IN, wait_value ) + PROC_MAIN_TRANSITIONS : process( MAIN_CS, DHCP_START_IN, CONSTRUCT_CS, wait_ctr, RECEIVE_CS, PS_DATA_IN ) begin main_state <= x"0"; @@ -184,7 +187,8 @@ begin when DELAY => main_state <= x"2"; - if( wait_ctr = wait_value ) then +-- if( wait_ctr = wait_value ) then + if( wait_ctr(short_delay_bit) = '1' ) then MAIN_NS <= SENDING_DISCOVER; else MAIN_NS <= DELAY; @@ -200,9 +204,11 @@ begin when WAITING_FOR_OFFER => main_state <= x"4"; - if( (RECEIVE_CS = SAVE_VALUES) and (PS_DATA_IN(8) = '1') ) then + -- BUG: fails on empty payload + if ( (RECEIVE_CS = SAVE_VALUES) and (PS_DATA_IN(8) = '1') ) then MAIN_NS <= SENDING_REQUEST; - elsif( wait_ctr = x"2000_0000" ) then +-- elsif( wait_ctr = x"2000_0000" ) then + elsif( wait_ctr(long_delay_bit) = '1' ) then MAIN_NS <= BOOTING; else MAIN_NS <= WAITING_FOR_OFFER; @@ -218,9 +224,11 @@ begin when WAITING_FOR_ACK => main_state <= x"6"; - if( (RECEIVE_CS = SAVE_VALUES) and (PS_DATA_IN(8) = '1') ) then + -- BUG: fails on empty payload + if ( (RECEIVE_CS = SAVE_VALUES) and (PS_DATA_IN(8) = '1') ) then MAIN_NS <= ESTABLISHED; - elsif( wait_ctr = x"2000_0000" ) then +-- elsif( wait_ctr = x"2000_0000" ) then + elsif( wait_ctr(long_delay_bit) = '1' ) then MAIN_NS <= BOOTING; else MAIN_NS <= WAITING_FOR_ACK; @@ -246,6 +254,7 @@ begin if( rising_edge(CLK) ) then if ( (MAIN_CS = SENDING_DISCOVER) or (MAIN_CS = SENDING_REQUEST) or (MAIN_CS = BOOTING) ) then wait_ctr <= (others => '0'); + -- BUG: fails on empty payload elsif( (MAIN_CS = WAITING_FOR_ACK) and (RECEIVE_CS = SAVE_VALUES) and (PS_DATA_IN(8) = '1') ) then wait_ctr <= (others => '0'); elsif( (MAIN_CS = WAITING_FOR_ACK) or (MAIN_CS = WAITING_FOR_OFFER) or (MAIN_CS = DELAY) or (MAIN_CS = ESTABLISHED) ) then @@ -292,6 +301,7 @@ begin when SAVE_VALUES => recv_state <= x"2"; + -- BUG: fails on empty payload if ( PS_DATA_IN(8) = '1' ) then RECEIVE_NS <= CLEANUP; -- check if the same transaction @@ -309,6 +319,7 @@ begin when DISCARD => recv_state <= x"3"; + -- BUG: fails on empty payload if( PS_DATA_IN(8) = '1' ) then RECEIVE_NS <= CLEANUP; else -- 2.43.0