![]() |
|
|
|||||||
![]() |
VHDL - My FSM is jumping to an unreachable state |
|
|
Thread Tools | Search this Thread |
|
|
#1 |
|
I am having a problem whereby my FSM is jumping back and forth between
two states, one of which is unreachable from that current state ie. in the code below, it is jumping out of "check_da" state into "check_protocol" state okay, but once it is in this state, it jumps into "check_da" state which should be unreachable, then back to "check_protocol" and so forth. For nibble_counter values not equal to 39->41,47->51 it should stay in "check_protocol" as indicated by "when others=>next_state<=check_protocol;" declaration. Any ideas why this occuring ? library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.board_addresses.all; entity Receiver is Port ( rxd : in std_logic_vector (3 downto 0); rst :in std_logic; rxclk : in std_logic; rxdv : in STD_LOGIC; frame_bad : out std_logic; frame_good : out std_logic; frame_mrk : out std_logic; crcgen_en: out std_logic:='0'; crcgen_rst crc:in std_logic_vector (31 downto 0)); end Receiver; architecture RTL of Receiver is type receiver_state is (idle,wait_till_one_nibble_before_sfd,start_crcgen ,check_da,check_protocol,read_data_till_one_nibble _before_fcs,stop_crcgen,check_fcs,wait_end,frm_goo d,frm_bad); signal current_state,next_state:receiver_state; signal frame_mrk_i:std_logic:='0'; signal frame_good_i:std_logic:='0'; signal frame_bad_i:std_logic:='0'; signal crcgen_en_i:std_logic:='0'; signal crcgen_rst_i:std_logic:='0'; signal nibble_counter:integer range 0 to 4096; signal ip_length:std_logic_vector (15 downto 0):="0000000000000000"; signal fcs_position:integer range 0 to 4096:=0; signal err_flag:std_logic:='0'; signal nibble_counter_rst:std_logic:='0'; signal fcs:std_logic_vector (31 downto 0); signal test:integer range 0 to 4096; begin state_flops: process (rxclk,rst,nibble_counter_rst) begin if (rising_edge(rxclk))then if (rst = '1') then current_state <= idle; nibble_counter<=0; elsif (nibble_counter_rst='1') then current_state <= next_state; nibble_counter<=0; else current_state <= next_state; nibble_counter<=nibble_counter+1; end if; end if; end process state_flops; output_flops: process (rxclk,rst) begin if (rising_edge(rxclk))then if (rst = '1') then frame_mrk<='0'; frame_good<='0'; frame_bad<='0'; crcgen_en<='0'; crcgen_rst<='0'; else frame_mrk<=frame_mrk_i; frame_good<=frame_good_i; frame_bad<=frame_bad_i; crcgen_en<=crcgen_en_i; crcgen_rst<=crcgen_rst_i; end if; end if; end process output_flops; output_comb: process (next_state) begin case next_state is when idle=> frame_mrk_i<='0'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='0'; crcgen_rst_i<='1'; when wait_till_one_nibble_before_sfd=> frame_mrk_i<='0'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='0'; crcgen_rst_i<='0'; when start_crcgen=> frame_mrk_i<='0'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='1'; crcgen_rst_i<='0'; when check_da=> frame_mrk_i<='1'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='1'; crcgen_rst_i<='0'; when check_protocol=> frame_mrk_i<='1'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='1'; crcgen_rst_i<='0'; when read_data_till_one_nibble_before_fcs=> frame_mrk_i<='1'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='1'; crcgen_rst_i<='0'; when stop_crcgen=> frame_mrk_i<='0'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='0'; crcgen_rst_i<='0'; when check_fcs=> frame_mrk_i<='0'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='0'; crcgen_rst_i<='0'; when wait_end=> frame_mrk_i<='0'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='0'; crcgen_rst_i<='0'; when frm_good=> frame_mrk_i<='0'; frame_good_i<='1'; frame_bad_i<='0'; crcgen_en_i<='0'; crcgen_rst_i<='0'; when frm_bad=> frame_mrk_i<='0'; frame_good_i<='0'; frame_bad_i<='1'; crcgen_en_i<='0'; crcgen_rst_i<='0'; when others=> frame_mrk_i<='0'; frame_good_i<='0'; frame_bad_i<='0'; crcgen_en_i<='0'; crcgen_rst_i<='1'; end case; end process output_comb; next_state_comb: process(current_state,rxclk,rxdv,nibble_counter,ip _length,rxd,crc,rst) begin if (rst='1') then fcs<=(others=>'0'); ip_length<=(others=>'0'); fcs_position<=0; err_flag<='0'; nibble_counter_rst<='0'; elsif rising_edge(rxclk) then case current_state is when idle => if rxdv='1' and rxd="0101" then next_state <= wait_till_one_nibble_before_sfd; nibble_counter_rst<='0'; else nibble_counter_rst<='1'; end if; when wait_till_one_nibble_before_sfd=> if nibble_counter=13 then next_state<=start_crcgen; end if; when start_crcgen=> next_state<=check_da; when check_da=> case nibble_counter is when 15=> if rxd=board_mac_address(43 downto 40) or rxd=x"F" then err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 16=> if rxd=board_mac_address(47 downto 44) or rxd=x"F" then err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 17=> if rxd=board_mac_address(35 downto 32) or rxd=x"F" then err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 18=> if rxd=board_mac_address(39 downto 36) or rxd=x"F" then err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 19=> if rxd=board_mac_address(27 downto 24) or rxd=x"F" then err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 20=> if rxd=board_mac_address(31 downto 2 err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 21=> if rxd=board_mac_address(19 downto 16) or rxd=x"F" then err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 22=> if rxd=board_mac_address(23 downto 20) or rxd=x"F" then err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 23=> if rxd=board_mac_address(11 downto err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 24=> if rxd=board_mac_address(15 downto 12) or rxd=x"F" then err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 25=> if rxd=board_mac_address(3 downto 0)or rxd=x"F" then err_flag<='0'; next_state <= check_da; else err_flag<='1'; next_state <= wait_end; end if; when 26=> if rxd=board_mac_address(7 downto 4) or rxd=x"F" then err_flag<='0'; next_state <= check_protocol; else err_flag<='1'; next_state <= wait_end; end if; when others=> next_state <=check_da; err_flag<='0'; end case; when check_protocol=> case nibble_counter is --only valid protocols are IP and ARP when 39=> if rxd="1000" then next_state <= check_protocol; err_flag<='0'; else next_state <= wait_end; err_flag<='1'; end if; when 40=> if rxd="0000" then next_state <= check_protocol; err_flag<='0'; else next_state <= wait_end; err_flag<='1'; end if; when 41=> if rxd="0110" then --Frame type is ARP, hence frame size is 60 bytes (data of 92 nibbles, type of 4 nibbles, 24 nibbles for dest and source addresses) fcs_position<=135; --fcs position will be a (frame size of 120 nibbles+32 nibbles for preample and sfd)-1 next_state <= read_data_till_one_nibble_before_fcs; err_flag<='0'; elsif rxd="0000" then fcs_position<=0; next_state <= check_protocol; err_flag<='0'; else next_state <= wait_end; err_flag<='1'; end if; when 47=> ip_length(11 downto next_state <= check_protocol; when 48=> ip_length(15 downto 12)<=rxd; next_state <= check_protocol; when 49=> ip_length(3 downto 0)<=rxd; next_state <= check_protocol; when 50=> ip_length(7 downto 4)<=rxd; next_state <= check_protocol; when 51=> if ip_length<"0000000000101110" then --payload length under minimum 46 bytes, frame size will be padded to 60 bytes fcs_position<=135; next_state<=read_data_till_one_nibble_before_fcs; else fcs_position<=conv_integer((ip_length+14)+(ip_leng th +14)+16-1);--frame size will be 2* (ip_length+14) where 14 is for preample in nibbles next_state<=read_data_till_one_nibble_before_fcs; end if; when others=> next_state <= check_protocol; err_flag<='0'; end case; when read_data_till_one_nibble_before_fcs=> if nibble_counter=fcs_position-1 then next_state<=stop_crcgen; else next_state<=read_data_till_one_nibble_before_fcs; end if; when stop_crcgen=> if nibble_counter=fcs_position+7 then next_state<=check_fcs; else next_state<=stop_crcgen; end if; fcs(31 downto 2 fcs(27 downto 24)<=fcs(31 downto 2 fcs(23 downto 20)<=fcs(27 downto 24); fcs(19 downto 16)<=fcs(23 downto 20); fcs(15 downto 12)<=fcs(19 downto 16); fcs(11 downto fcs(7 downto 4)<=fcs(11 downto fcs(3 downto 0)<=fcs(7 downto 4); when check_fcs=> if crc(31 downto 0)=fcs(31 downto 0) then next_state<=frm_good; else next_state<=frm_bad; end if; when wait_end=> if rxdv='0' then if err_flag='1' then next_state<=frm_bad; else next_state<=frm_good; end if; end if; when frm_bad=> next_state<=idle; when frm_good=> next_state<=idle; when others => next_state <= idle; end case; end if; end process next_state_comb; end RTL; Regards Mario Gencarelli Defence Science&Technology Organisation Salisbury Australia maurizio.gencarelli@dsto.defence.gov.au |
|
|
|
|
#2 |
|
Posts: n/a
|
<> wrote in message news: ups.com... >I am having a problem whereby my FSM is jumping back and forth between > two states, one of which is unreachable from that current state ie. in > the code below, it is jumping out of "check_da" state into > "check_protocol" state okay, but once it is in this state, it jumps > into "check_da" state which should be unreachable, then back to > "check_protocol" and so forth. For nibble_counter values not equal to > 39->41,47->51 it should stay in "check_protocol" as indicated by > "when others=>next_state<=check_protocol;" declaration. > > Any ideas why this occuring ? If this is happening on a real board but not in simulation, then it is most likely a timing problem, you need to perform static timing analysis. Somewhat related would be if any of the inputs to the state machine are not synchronized to the clock. This will eventually cause a timing problem when that async input ends up violating the required setup time (as determined by static timing analysis) and the design fails. KJ KJ |
|
|
|
#3 |
|
Posts: n/a
|
Hi Mario,
wrote: > I am having a problem whereby my FSM is jumping back and forth between > two states, one of which is unreachable from that current state ie. in > the code below, it is jumping out of "check_da" state into > "check_protocol" state okay, but once it is in this state, it jumps > into "check_da" state which should be unreachable, then back to > "check_protocol" and so forth. For nibble_counter values not equal to > 39->41,47->51 it should stay in "check_protocol" as indicated by > "when others=>next_state<=check_protocol;" declaration. > > Any ideas why this occuring ? You're using separate synchronous processes to handle the current state and compute the next state. This leads to a 2 clock cycles delay between next state computation and current state update, instead of a single clock cycle like you probably intended. Let's assume current_state and next_state are both check_da. When nibble_counter reaches 26 (clock cycle N) your next_state_comb process will change next_state to check_protocol. At clock cycle N+1, current_state will be updated to check_protocol by the state_flops process, but the next_state_comb process will still see a current state equal to check_da. nibble_counter will then be equal to 27, and thus next_state will be set to check_da by the "when others" case. You should either remove the next_state signal completely and move your next state computation logic to the state_flops process, or make the next_state_comb process asynchronous. Best regards, Laurent Pinchart Laurent Pinchart |
|
|
|
#4 |
|
Posts: n/a
|
On Jun 26, 6:58 pm, Laurent Pinchart <laurent.pinch...@skynet.be>
wrote: > Hi Mario, > > maurizio.gencare...@dsto.defence.gov.au wrote: > > I am having a problem whereby my FSM is jumping back and forth between > > two states, one of which is unreachable from that current state ie. in > > the code below, it is jumping out of "check_da" state into > > "check_protocol" state okay, but once it is in this state, it jumps > > into "check_da" state which should be unreachable, then back to > > "check_protocol" and so forth. For nibble_counter values not equal to > > 39->41,47->51 it should stay in "check_protocol" as indicated by > > "when others=>next_state<=check_protocol;" declaration. > > > Any ideas why this occuring ? > > You're using separate synchronous processes to handle the current state and > compute the next state. This leads to a 2 clock cycles delay between next > state computation and current state update, instead of a single clock cycle > like you probably intended. > > Let's assume current_state and next_state are both check_da. When > nibble_counter reaches 26 (clock cycle N) your next_state_comb process will > change next_state to check_protocol. At clock cycle N+1, current_state will > be updated to check_protocol by the state_flops process, but the > next_state_comb process will still see a current state equal to check_da. > nibble_counter will then be equal to 27, and thus next_state will be set to > check_da by the "when others" case. > > You should either remove the next_state signal completely and move your next > state computation logic to the state_flops process, or make the > next_state_comb process asynchronous. > > Best regards, > > Laurent Pinchart Thanks for your comments. I started with a next_state_comb process asynchronous but this caused BIG problems ie. structure of my FSM was the text book standard registered outputs with next_state look up to eliminate 1 clock cycle delay due to registering, which seems to work okay if values ae not temporary stored, ie. for given input conditions, outputs are immediately set in each state, not stored and processed to set some output condition. However, in my case signals such as ip_length which built up from four rxd nibble values over 4 clock cycles and fcs which is built up from 8 rxd nibbles over 8 clock cycles=> are stored. If I make next_comb_process asynchronous, I get unpredicted results with ip_length having rubbish values appear, resulting from changing values between clock ?. I also get bit latch errors which I can not seem to get rid of. By making the next_state_comb register based, I can guarantee that ip_length and fcs etc update only on the clock edge and eliminate all latch warnings. Has anyone had this problem and can suggest a better way, other than put all my code into one clocked process and live with the clock delays between inputs and ouputs, it would be appreciated. Cheers Mario Gencarelli Defence Science & Technology Organisation Salisbury Australia maurizio.gencarelli@dsto.defence.gov.au |
|
|
|
#5 |
|
Posts: n/a
|
wrote:
> Has anyone had this problem and can suggest a better way, other than > put all my code into one clocked process and live with the clock > delays between inputs and ouputs, it would be appreciated. 1. Right now you have two ticks of delay. With a single process, there would only be one. It is also much simpler to read. 2. Jumping to an illegal state is a sure sign of an unsynchronized input. -- Mike Treseler Mike Treseler |
|
|
|
#6 |
|
Posts: n/a
|
On 26 Jun, 07:40, maurizio.gencare...@dsto.defence.gov.au wrote:
> I am having a problem whereby my FSM is jumping back and forth between > two states, one of which is unreachable from that current state ie. in > the code below, it is jumping out of "check_da" state into > "check_protocol" state okay, but once it is in this state, it jumps > into "check_da" state which should be unreachable, then back to > "check_protocol" and so forth. For nibble_counter values not equal to > 39->41,47->51 it should stay in "check_protocol" as indicated by > "when others=>next_state<=check_protocol;" declaration. > > Any ideas why this occuring ? > > library IEEE; > use IEEE.STD_LOGIC_1164.ALL; > use IEEE.STD_LOGIC_ARITH.ALL; > use IEEE.STD_LOGIC_UNSIGNED.ALL; > use work.board_addresses.all; > > entity Receiver is > Port ( rxd : in std_logic_vector (3 downto 0); > rst :in std_logic; > rxclk : in std_logic; > rxdv : in STD_LOGIC; > frame_bad : out std_logic; > frame_good : out std_logic; > frame_mrk : out std_logic; > crcgen_en: out std_logic:='0'; > crcgen_rst > crc:in std_logic_vector (31 downto 0)); > end Receiver; > > architecture RTL of Receiver is > > type receiver_state is > (idle,wait_till_one_nibble_before_sfd,start_crcgen ,check_da,check_protocol,*read_data_till_one_nibbl e_before_fcs,stop_crcgen,check_fcs,wait_end,frm_go o*d,frm_bad); > signal current_state,next_state:receiver_state; > signal frame_mrk_i:std_logic:='0'; > signal frame_good_i:std_logic:='0'; > signal frame_bad_i:std_logic:='0'; > signal crcgen_en_i:std_logic:='0'; > signal crcgen_rst_i:std_logic:='0'; > signal nibble_counter:integer range 0 to 4096; > signal ip_length:std_logic_vector (15 downto 0):="0000000000000000"; > signal fcs_position:integer range 0 to 4096:=0; > signal err_flag:std_logic:='0'; > signal nibble_counter_rst:std_logic:='0'; > signal fcs:std_logic_vector (31 downto 0); > signal test:integer range 0 to 4096; > > begin > > state_flops: process (rxclk,rst,nibble_counter_rst) > begin > if (rising_edge(rxclk))then > if (rst = '1') then > current_state <= idle; > nibble_counter<=0; > elsif (nibble_counter_rst='1') then > current_state <= next_state; > nibble_counter<=0; > else > current_state <= next_state; > nibble_counter<=nibble_counter+1; > end if; > end if; > end process state_flops; > > output_flops: process (rxclk,rst) > begin > if (rising_edge(rxclk))then > if (rst = '1') then > frame_mrk<='0'; > frame_good<='0'; > frame_bad<='0'; > crcgen_en<='0'; > crcgen_rst<='0'; > else > frame_mrk<=frame_mrk_i; > frame_good<=frame_good_i; > frame_bad<=frame_bad_i; > crcgen_en<=crcgen_en_i; > crcgen_rst<=crcgen_rst_i; > end if; > end if; > end process output_flops; > > output_comb: process (next_state) > begin > case next_state is > when idle=> > frame_mrk_i<='0'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='0'; > crcgen_rst_i<='1'; > > when wait_till_one_nibble_before_sfd=> > frame_mrk_i<='0'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='0'; > crcgen_rst_i<='0'; > > when start_crcgen=> > frame_mrk_i<='0'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='1'; > crcgen_rst_i<='0'; > > when check_da=> > frame_mrk_i<='1'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='1'; > crcgen_rst_i<='0'; > > when check_protocol=> > frame_mrk_i<='1'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='1'; > crcgen_rst_i<='0'; > > when read_data_till_one_nibble_before_fcs=> > frame_mrk_i<='1'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='1'; > crcgen_rst_i<='0'; > > when stop_crcgen=> > frame_mrk_i<='0'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='0'; > crcgen_rst_i<='0'; > > when check_fcs=> > frame_mrk_i<='0'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='0'; > crcgen_rst_i<='0'; > > when wait_end=> > frame_mrk_i<='0'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='0'; > crcgen_rst_i<='0'; > > when frm_good=> > frame_mrk_i<='0'; > frame_good_i<='1'; > frame_bad_i<='0'; > crcgen_en_i<='0'; > crcgen_rst_i<='0'; > > when frm_bad=> > frame_mrk_i<='0'; > frame_good_i<='0'; > frame_bad_i<='1'; > crcgen_en_i<='0'; > crcgen_rst_i<='0'; > > when others=> > frame_mrk_i<='0'; > frame_good_i<='0'; > frame_bad_i<='0'; > crcgen_en_i<='0'; > crcgen_rst_i<='1'; > > end case; > end process output_comb; > > next_state_comb: > process(current_state,rxclk,rxdv,nibble_counter,ip _length,rxd,crc,rst) > > begin > > if (rst='1') then > > fcs<=(others=>'0'); > ip_length<=(others=>'0'); > fcs_position<=0; > err_flag<='0'; > nibble_counter_rst<='0'; > > elsif rising_edge(rxclk) then > > case current_state is > when idle => > if rxdv='1' and rxd="0101" then > next_state <= wait_till_one_nibble_before_sfd; > nibble_counter_rst<='0'; > else > nibble_counter_rst<='1'; > end if; > > when wait_till_one_nibble_before_sfd=> > if nibble_counter=13 then > next_state<=start_crcgen; > end if; > > when start_crcgen=> > next_state<=check_da; > > when check_da=> > > case nibble_counter is > > when 15=> > if rxd=board_mac_address(43 downto 40) or rxd=x"F" then > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; next_state <= wait_end; > end if; > when 16=> > if rxd=board_mac_address(47 downto 44) or rxd=x"F" then > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 17=> > if rxd=board_mac_address(35 downto 32) or rxd=x"F" then > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 18=> > if rxd=board_mac_address(39 downto 36) or rxd=x"F" then > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 19=> > if rxd=board_mac_address(27 downto 24) or rxd=x"F" then > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 20=> > if rxd=board_mac_address(31 downto 2 > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 21=> > if rxd=board_mac_address(19 downto 16) or rxd=x"F" > then > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 22=> > if rxd=board_mac_address(23 downto 20) or rxd=x"F" > then > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 23=> > if rxd=board_mac_address(11 downto > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 24=> > if rxd=board_mac_address(15 downto 12) or rxd=x"F" then > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 25=> > if rxd=board_mac_address(3 downto 0)or rxd=x"F" then > err_flag<='0'; > next_state <= check_da; > else > err_flag<='1'; > next_state <= wait_end; > end if; > when 26=> > if rxd=board_mac_address(7 downto 4) or rxd=x"F" then > err_flag<='0'; > next_state <= check_protocol; > else > err_flag<='1'; > next_state <= wait_end; > end if; > > when others=> > next_state <=check_da; > err_flag<='0'; > end case; > > when check_protocol=> > > case nibble_counter is > --only valid protocols are IP and ARP > when 39=> > if rxd="1000" then > next_state <= check_protocol; > err_flag<='0'; > else > next_state <= wait_end; > err_flag<='1'; > end if; > > when 40=> > if rxd="0000" then > next_state <= check_protocol; > err_flag<='0'; > else > next_state <= wait_end; > err_flag<='1'; > end if; > > when 41=> > if rxd="0110" then --Frame type is ARP, hence frame size is 60 > bytes (data of 92 nibbles, type of 4 nibbles, 24 nibbles for dest and > source addresses) > fcs_position<=135; --fcs position will be a (frame size of > 120 nibbles+32 nibbles for preample and sfd)-1 > next_state <= read_data_till_one_nibble_before_fcs; > err_flag<='0'; > elsif rxd="0000" then > fcs_position<=0; > next_state <= check_protocol; > err_flag<='0'; > else > next_state <= wait_end; > err_flag<='1'; > end if; > > when 47=> > ip_length(11 downto > next_state <= check_protocol; > > when 48=> > ip_length(15 downto 12)<=rxd; > next_state <= check_protocol; > > when 49=> > ip_length(3 downto 0)<=rxd; > next_state <= check_protocol; > > when 50=> > ip_length(7 downto 4)<=rxd; > next_state <= check_protocol; > > when 51=> > if ip_length<"0000000000101110" then --payload length under > minimum 46 bytes, frame size will be padded to 60 bytes > fcs_position<=135; > next_state<=read_data_till_one_nibble_before_fcs; > else > fcs_position<=conv_integer((ip_length+14)+(ip_leng th > +14)+16-1);--frame size will be 2* (ip_length+14) where 14 is for > preample in nibbles > next_state<=read_data_till_one_nibble_before_fcs; > end if; > > when others=> > next_state <= check_protocol; > err_flag<='0'; > end case; > > when read_data_till_one_nibble_before_fcs=> > if nibble_counter=fcs_position-1 then > next_state<=stop_crcgen; > else > next_state<=read_data_till_one_nibble_before_fcs; > end if; > > when stop_crcgen=> > > if nibble_counter=fcs_position+7 then > next_state<=check_fcs; > else > next_state<=stop_crcgen; > end if; > > fcs(31 downto 2 > fcs(27 downto 24)<=fcs(31 downto 2 > fcs(23 downto 20)<=fcs(27 downto 24); > fcs(19 downto 16)<=fcs(23 downto 20); > fcs(15 downto 12)<=fcs(19 downto 16); > fcs(11 downto > fcs(7 downto 4)<=fcs(11 downto > fcs(3 downto 0)<=fcs(7 downto 4); > > when check_fcs=> > > if crc(31 downto 0)=fcs(31 downto 0) then > next_state<=frm_good; > else > next_state<=frm_bad; > end if; > > when > > read more »... A minor point is that the state_flops process only needs rxclock in the sensitivity list as the resets, as coded, are both synchronous. The other clocked process has async resets; did you mean that? I tend to use a 3 process FSM; P1: state <= next_state on rising_edge(clk) P2: combinatorial state assignments: CASE state IS WHEN idle => IF condition_1 THEN next_state <= state2; ELSE next_state <= idle; END IF; etc etc. P3: assign o/ps depending on state, the o/ps can be registerd. (Helps to avoid glitches as state changes via various inputs, can be critical in gate level sims & real h/w, but often not seen in RTL). Kev P Niv |
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Using BRAM in state machines | zoki111 | Hardware | 0 | 09-18-2007 09:38 AM |
| Judge: File-swapping tools are legal | Citizen Bob | DVD Video | 140 | 11-08-2006 06:42 PM |
| DVD Verdict reviews: THE PACIFIER, STATE PROPERTY 2, and more! | DVD Verdict | DVD Video | 0 | 07-22-2005 09:11 AM |
| BUSH WILL LIKELY INSTALL A DRAFT | Jas | DVD Video | 165 | 10-20-2004 09:39 PM |
| DVD copy company killed by Hollywood studios | Modemac | DVD Video | 24 | 08-07-2004 02:46 AM |