Go Back   Velocity Reviews > Newsgroups > VHDL
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

Reply

VHDL - My FSM is jumping to an unreachable state

 
Thread Tools Search this Thread
Old 06-26-2007, 07:40 AM   #1
Default My FSM is jumping to an unreachable state


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_rstut std_logic:='0';
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 or rxd=x"F" then
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 or rxd=x"F" then
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 <=rxd;
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<=rxd;
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(15 downto 12);
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
  Reply With Quote
Old 06-26-2007, 10:53 AM   #2
KJ
 
Posts: n/a
Default Re: My FSM is jumping to an unreachable state

<> 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
  Reply With Quote
Old 06-26-2007, 10:58 AM   #3
Laurent Pinchart
 
Posts: n/a
Default Re: My FSM is jumping to an unreachable state
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
  Reply With Quote
Old 06-26-2007, 01:50 PM   #4
maurizio.gencarelli@dsto.defence.gov.au
 
Posts: n/a
Default Re: My FSM is jumping to an unreachable state
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
  Reply With Quote
Old 06-26-2007, 05:34 PM   #5
Mike Treseler
 
Posts: n/a
Default Re: My FSM is jumping to an unreachable state
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
  Reply With Quote
Old 06-27-2007, 08:53 AM   #6
Niv
 
Posts: n/a
Default Re: My FSM is jumping to an unreachable state
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_rstut std_logic:='0';
> 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 or rxd=x"F" then
> 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 or rxd=x"F" then
> 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 <=rxd;
> 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<=rxd;
> 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(15 downto 12);
> 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
  Reply With Quote
Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off

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




SEO by vBSEO 3.3.2 ©2009, Crawlability, Inc.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46