Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

Problem with "WHILE...loop"

Hello,

I am trying to write an FSM module using VHDL.I have to make a "while...loop" that doesn't concern all the states but only a pre-determined number of them.Here is the FSM diagram schematic:

file:///C:/Users/CHAKCH%7E1/AppData/Local/Temp/moz-screenshot.jpg https://www.alteraforum.com/forum/attachment.php?attachmentid=1281

After the syntax check,I got the following error message:"error (10552): vhdl expression error at fsm.vhd(122): illegal state in expression".

Here is the part of the code related to this issue:


 process (etat_suivant,Idle , Start_recep,Reception , Depart_trans , Tran_addr , Ack_1 , Trans_data_1 , Ack_2 ,
        Trans_data_2, Ack_3, Stop_cond_1 , Stop_cond_2 , Stop_cond_3) --data transmission process
        begin
        case state is 
        
        when idle => 
        SCLK<= '1';
        SDIN<= '1';
        if SDIN = '0' then etat_suivant<= Start_recep;
        end if;
        
        when Start_recep => 
        SCLK<= '1';
        SDIN<= '0';
        if SDIN = '1' then etat_suivant<= Reception;
        end if;
        
        when Reception => 
        while (m <= 47) loop
        while (s <= 7) loop
        SDIN<= ADCDAT(s);
        s:= s+1;
        end loop ;         
        m:= m+1;
        end loop ;         
        if (m = 48) then etat_suivant<= Depart_trans;
        end if;
        end case;
        
       while (n <= 15) loop
        case state is
        when Depart_trans => 
        SCLK<= '0';
        SDIN<= '0';
        if (SDIN = '1') then etat_suivant<= Tran_addr;
        end if;
        
        when Tran_addr => 
        while (i < 7 ) loop
        SDIN<= ADDR(i);
        i:= i+1;
        end loop ; 
        DATA_0<= ADDR&'0'; 
    
        if (i = 7) then etat_suivant<= Ack_1 ;
        end if;
        
        when Ack_1  => 
        SDIN<= '0';
        ACK<='1';
        etat_suivant<= Trans_data_1 ;
        
        
        when Trans_data_1 => 
        ACK<='0';
        while (j < 8 ) loop
        SDIN<= DATA_1(j);
        j:= j+1;
        end loop ; 
        if (j = 8) then etat_suivant<= Ack_2;
        end if;
        
        when Ack_2  => 
        SDIN<= '0';
        ACK<='1';
        etat_suivant<= Trans_data_2 ;
        
        
        when Trans_data_2 => 
        ACK<='0';
        while (k < 8 ) loop
        SDIN<= DATA_2(k);
        k:= k+1;
        end loop ; 
        if (k = 8) then etat_suivant<= Ack_3;
        end if;    
        
        when Ack_3  => 
        SDIN<= '0';
        ACK<='1';
        etat_suivant<= Stop_cond_1 ;
        
        when Stop_cond_1  => 
        ACK <= '0';
        SDIN<= '0';
        SCLK<='0';
        etat_suivant<= Stop_cond_2 ;
        
        
        when Stop_cond_2  => 
        SDIN<= '0';
        SCLK<='1';
        etat_suivant<= Stop_cond_3 ;
        
        when Stop_cond_3  => 
        SDIN<= '1';
        SCLK<='1';
         etat_suivant<= Depart_trans ;  
         
          when others=> 
         etat_suivant<=Idle;
        
        if ( n > 15) then
        fin<='1';
        etat_suivant<= Idle ;
        end if;
        end case;
        end loop;

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I do not see any place where your VHDL code is synchronized by a clock event.

    For such a finite state-machine you should define a synchronous system clocked with an external clock.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Actually there is no problem with the clock since it is written in a separate process:

    
    process(reset,BCLK)
            begin
            if reset = '1' then 
            adr_reg <= adr_reg_1E;
            val_reg_byte_1 <= val_reg_1E(8 downto 1);
            val_reg_byte_2<= "00000000";
            
            elsif (BCLK'event and BCLK = '1') then 
            etat_courant <= etat_suivant;
            end if;
            end process;
    

    I am very sure the problem lies in the loop.Please take a look at the FSM schematic.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    The synthesis for the "while" loops is rather complicated as the amount of terms the loop will be taken is not known at compile time. This would mean that separate hardware would be generated for every individual value of the signals to be tested in your while loop.

    So the code:

    while (n <= 15) loop

    would have to be expanded in hardware for every individual case where n = 0, n = 1, n = 2 ... n = 15.

    I have the impression that there are a number of states in which you would like to stay for a number of turns (indicated by the end conditions of your while expression).

    In the case that your state transitions (also the loops from a state to itself) are taking place synchronized by the clock, you can implement the statemachine by using "if" expressions instead of the "while" loops.

    In the "if" expression as long as the end condition is not met, your etat_suivant next state should remain the same as the previous value. Only when the end condition is met, you should update the next state etat_suivant.