Forum Discussion

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

Quartus doesnt recognize my FSM as a FSM

Hello guys i have a "problem", i can't see my FSM as a FSM inside quartus state machine view or RTL viewer or whatever, is this a problem?

I use two processes, one is combinational and the other is sequential

An example of my FSM is here :


  process (reset_n, sysclk) is
  begin
    if reset_n = '0' then
      state_core      <= WAIT_START_CALC;
      mean_reg        <= (others => '0');
      first_time_reg  <= '1';
      aux_a_reg       <= (others => '0');
      contador_ph     <= 0;
      mag_out_reg     <= (others => '0');
      finish_calc_reg <= '0';
      read_counter    <= 0;
    elsif rising_edge(sysclk) then
      state_core      <= state_core_next;
      mean_reg        <= mean_reg_next;
      aux_a_reg       <= aux_a_next;
      first_time_reg  <= first_time_next;
      contador_ph     <= contador_ph_next;
      mag_out_reg     <= mag_out_next;
      finish_calc_reg <= finish_calc_next;
      read_counter    <= read_counter_next;
    end if;
  end process;
  process (aux_a_reg, contador_ph, finish_calc_reg, first_time_reg,
           mag_out_reg, mean_reg, memory_mean, read_counter, start_calc,
           state_core)
  begin
    state_core_next   <= state_core;
    mean_reg_next     <= mean_reg;
    first_time_next   <= first_time_reg;
    contador_ph_next  <= contador_ph;
    aux_a_next        <= aux_a_reg;
    mag_out_next      <= mag_out_reg;
    finish_calc_next  <= finish_calc_reg;
    read_counter_next <= read_counter;
    case state_core is
      
      when WAIT_START_CALC =>
        if start_calc = '1' then
          first_time_next <= '1';
          if contador_ph = 31 then
            contador_ph_next <= 0;
            state_core_next  <= READY;
          else
            contador_ph_next <= contador_ph + 1;
          end if;
        end if;
        
      when READY =>
        finish_calc_next <= '0';
        if first_time_reg = '1' then
          first_time_next <= '0';
          state_core_next <= SUM_P1;
        else
          first_time_next <= '0';
          if start_calc = '1' then
            if contador_ph = 31 then
              contador_ph_next <= 0;
            else
              contador_ph_next <= contador_ph + 1;
            end if;
            state_core_next <= SUM_P1;
          end if;
        end if;
        
      when SUM_P1 =>
        mean_reg_next   <= "00000" & memory_mean(read_counter);
        state_core_next <= SUM_P2;
        
      when SUM_P2 =>
        aux_a_next <= aux_a_reg + mean_reg;
        if read_counter = 31 then
          state_core_next <= DONE;
        else
          read_counter_next <= read_counter + 1;
          state_core_next   <= SUM_P1;
        end if;
        
        
      when DONE =>
        mag_out_next      <= aux_a_reg(20 downto 5);
        read_counter_next <= 0;
        finish_calc_next  <= '1';
        aux_a_next        <= (others => '0');
        state_core_next   <= READY;
        
        
      when others =>
        state_core_next <= WAIT_START_CALC;
    end case;
    
  end process;
My design is working but could i achieve better results with other FSM implementation recognized by Quartus? (LE wise and timing wise).

9 Replies

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

    I always use one process state machines as I find they are easier to write. They are perfectly recognised as such by Quartus, even if I don't follow strictly their recommended style (http://www.altera.com/literature/hb/qts/qts_qii51007.pdf).

    Your problem could come from the fact that you register a whole bunch of signals in the first process and have all your signals retain their previous value in the second process. I hope that Quartus is smart enough not to generate latches from your second process description.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    try moving to the 1 process state machine template. Thats essntially what you're trying to do here by holding state by default.

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

    I always use the two-process approach for state machines as that allows you to generate both combinatorial and registered outputs. If you use a one -process state machine all signals are clocked and often you can 'loose' active clock cycles due to this approach.

    It however pays to generate 'enables' in the combinatorial section and use these in the clocked section to register values. It saves on LE's and makes nicer RTL diagrams as well.

    using 'hold' signals generates a lot of extra muxes, which eventually generates slower logic.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I changed to a one process FSM and i didnt got recognized also

    process (reset_n, sysclk) is
      begin
        if reset_n = '0' then
          state_core      <= WAIT_START_CALC;
          mean_reg        <= (others => '0');
          first_time_reg  <= '1';
          aux_a_reg       <= (others => '0');
          contador_ph     <= 0;
          mag_out_reg     <= (others => '0');
          finish_calc_reg <= '0';
          read_counter    <= 0;
        elsif rising_edge(sysclk) then
          
        case state_core is
          
          when WAIT_START_CALC =>
            if start_calc = '1' then
              first_time_reg <= '1';
              if contador_ph = 31 then
                contador_ph <= 0;
                state_core  <= READY;
              else
                contador_ph <= contador_ph + 1;
              end if;
            end if;
            
          when READY =>
            finish_calc_reg <= '0';
            if first_time_reg = '1' then
              first_time_reg <= '0';
              state_core <= SUM_P1;
            else
              first_time_reg <= '0';
              if start_calc = '1' then
                if contador_ph = 31 then
                  contador_ph <= 0;
                else
                  contador_ph <= contador_ph + 1;
                end if;
                state_core <= SUM_P1;
              end if;
            end if;
            
          when SUM_P1 =>
            mean_reg   <= "00000" & memory_mean(read_counter);
            state_core <= SUM_P2;
            
          when SUM_P2 =>
            aux_a_reg <= aux_a_reg + mean_reg;
            if read_counter = 31 then
              state_core <= DONE;
            else
              read_counter <= read_counter + 1;
              state_core   <= SUM_P1;
            end if;
            
            
          when DONE =>
            mag_out_reg      <= aux_a_reg(20 downto 5);
            read_counter <= 0;
            finish_calc_reg  <= '1';
            aux_a_reg        <= (others => '0');
            state_core   <= READY;
            
            
          when others =>
            state_core <= WAIT_START_CALC;
        end case;
        end if;
      end process;
    Josyb, could you please post an example of a SM in your style?

    TYVM

    i also tried to design my sm as the code guidelines suggests but without sucess
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In a short: the problem isn't in the posted code.

    I didn't understand, why Quartus won't infer a FSM from your design, so I supplemented the missing design frame, that is unfortunately stripped off from your code. It turned out, that both variants are recognized as FSM, both in Quartus 9.0 and 11.0.

    I don't know why, but I guess that there's something special with the signals you are feeding to or driving from your design, so that possibly part of design functionally is removed. Or it has to do with non-standard synthesis settings.

    In any case, the experiment clarifies, that the problem isn't located in the posted code, and previous assumptions about the problem are more or less missing the point.

    The case shows once more, that discussing code snippets involves a risk of jumping into conclusions.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    FVM thanks for your help.

    Well i will attach my code here, your coded used 1k LE opposed to mine that used 131 and infered a ram, apart from that my design doesn't infer a FSM (yours does), it may be a QSF option?

    my code is attached
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    By the way my FSM is implemented exactly like Pong P. Chu suggests in his book RTL-Hardware-Design-Using-VHDL