VHDL: FSM с несколькими типами состояний

Мы пытаемся создать контроллер для робота, способного выполнять две разные задачи: поиск линии и отслеживание линии. (Мы используем три светорезистора для обнаружения линии, проведенной на земле.) Идея состояла в том, чтобы создать fsm машину Мура, которая, однако, использует вместо одного типа обновления состояния несколько. Причина этого в том, что каждое состояние должно переходить в состояние сброса через 20 мс, чтобы обновить другие компоненты, которые в противном случае не будут работать. Чтобы вернуться в исходное состояние, мы используем дополнительную последовательность состояний, которая используется в качестве входных данных, чтобы машина Мура знала, куда вернуться. (Возможно, полезно знать, что сокращение кода только до отслеживания строки работает отлично, что также реализовано в реальной жизни.)

Странно то, что смоделированный на ModelSim код работает без нареканий, все подключено и т.д., но при его реализации мы получаем с десяток предупреждений о наличии защелок (относительно двух других последовательностей состояний new_eureka и new_StoredValue), которые полностью портит наши операции. Тем не менее, глядя на код, мы не можем понять, почему производятся эти защелки. Как мы можем избежать появления этих защелок?

Ниже код и предупреждения, созданные с помощью программного обеспечения Quartus.

library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity LineFinder is
  port (    clk     : in    std_logic;
        reset       : in    std_logic;
        count_out   : in    std_logic_vector(19 downto 0);
      sensor_l_out  : in    std_logic;
        sensor_m_out    : in    std_logic;
        sensor_r_out    : in    std_logic;

        pwm_l_reset : out   std_logic;
        pwm_l_direction : out std_logic;
        pwm_r_reset : out   std_logic;
        pwm_r_direction : out std_logic;    

        count_reset: out std_logic  
    );
end entity LineFinder;


architecture behaviour of LineFinder is

  component input_buffer is
    port (  clk     : in    std_logic;

        sensor_l_in : in    std_logic;
        sensor_m_in : in    std_logic;
        sensor_r_in : in    std_logic;

        sensor_l_out    : out   std_logic;
        sensor_m_out    : out   std_logic;
        sensor_r_out    : out   std_logic
    );
  end component input_buffer;

  type line_state is (reset_state, 
                      FindLine_state, 
                      PassLine_state, 
                      CorrectLeft_state, 
                      CorrectRight_state, 
                      wbw_state,

                      bbb_state,
                      bbw_state, 
                      bwb_state, 
                      bww_state, 
                      wbb_state,  
                      wwb_state, 
                      www_state);                   
  signal state , new_state: line_state ;

  type eureka_state is (FindingLine, 
            PassingLine, 
            CorrectingRight, 
            CorrectingLeft,  
            TrackingLine);
  signal eureka, new_eureka: eureka_state;

  signal StoredValue, new_StoredValue: std_logic_vector(2 downto 0) := "000";

  constant period: std_logic_vector(19 downto 0) := std_logic_vector (to_unsigned(1000000, 20));

  begin


    Process1: process (clk, reset)
      begin
        if (rising_edge(clk)) then
          if (reset ='1') then
            state <= FindLine_state;
            eureka <= FindingLine;
        StoredValue <= "000";
          else
          state <= new_state;
          eureka <= new_eureka;
      StoredValue <= new_StoredValue;
        end if;
      end if;
      end process;

      --Finding Line process
      Process2: process (state, eureka, StoredValue, count_out, sensor_l_out, sensor_m_out, sensor_r_out)
        begin
          if ((not((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '0'))) and (eureka = PassingLine)) then
            new_StoredValue <= sensor_r_out & sensor_m_out & sensor_l_out;
          end if;

          case state is
          when FindLine_state =>
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= FindingLine;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '0')) then
              new_state <= FindLine_state;
              new_eureka <= FindingLine;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
              new_state <= wbw_state;
              new_eureka <= TrackingLine;
            else
              new_state <= PassLine_state;
              new_eureka <= PassingLine;
            end if;

          when PassLine_state =>
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= PassingLine;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '0')) then
              if ((StoredValue = "001") or (StoredValue = "011")) then 
                  new_state <= CorrectRight_state;
                  new_eureka <= CorrectingRight;
              else
                  new_state <= CorrectLeft_state;
                  new_eureka <= CorrectingLeft;
              end if;
            else 
              new_state <= PassLine_state;
              new_eureka <= PassingLine;
            end if;


          when CorrectRight_state =>
            pwm_l_reset <= '0'; --making sharp turn to right
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '1'; 
            count_reset <= '0';            
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= CorrectingRight;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
              new_state <= wbw_state;
              new_eureka <= TrackingLine;
            else
              new_state <= CorrectRight_state;
              new_eureka <= CorrectingRight;
            end if;

          when CorrectLeft_state => 
            pwm_l_reset <= '0'; --making sharp turn to left
            pwm_r_reset <= '0';
            pwm_l_direction <= '0';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= CorrectingLeft;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
              new_state <= wbw_state;
              new_eureka <= TrackingLine;
            else
              new_state <= CorrectLeft_state;
              new_eureka <= CorrectingLeft;
            end if;

          when wbw_state =>     --aka LineFoundState   
            -- go to LineTracker process!
            -- forward trigger
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';      
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= wbw_state;
              new_eureka <= TrackingLine;
            end if;

          when reset_state => 
            pwm_l_reset <= '1';
            pwm_r_reset <= '1';
            pwm_l_direction <= '1';
            pwm_r_direction <= '1';
            count_reset <= '1';
            if (not(eureka = TrackingLine)) then
              if (eureka = FindingLine) then
                new_state <= FindLine_state;
                new_eureka <= FindingLine;
              elsif (eureka = PassingLine) then
                new_state <= PassLine_state;
                new_eureka <= PassingLine;
              elsif (eureka = CorrectingRight) then
                new_state <= CorrectRight_state;
                new_eureka <= CorrectingRight;
              elsif (eureka = CorrectingLeft) then
                new_state <= CorrectLeft_state;
                new_eureka <= CorrectingLeft;
              else
                new_state <= FindLine_state;  --do we need this?
                new_eureka <= FindingLine;
              end if;
            else
              --The other reset process
              if ((sensor_l_out = '1') and (sensor_m_out ='1') and (sensor_r_out = '1')) then
                new_state <= bbb_state;
              elsif ((sensor_l_out = '1') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
                new_state <= bbw_state;
              elsif ((sensor_l_out = '1') and (sensor_m_out ='0') and (sensor_r_out = '1')) then
                new_state <= bwb_state;
              elsif ((sensor_l_out = '1') and (sensor_m_out ='0') and (sensor_r_out = '0')) then
                new_state <= bww_state;
              elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '1')) then
                new_state <= wbb_state;
              elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
                new_state <= wbw_state;
              elsif ((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '1')) then
                new_state <= wwb_state;
              elsif ((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '0')) then
                new_state <= www_state;             
              else
                new_state <= reset_state;
              end if;
            end if;



            when bbb_state => -- forward
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';      
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= bbb_state;
              new_eureka <= TrackingLine;
            end if;


            when bbw_state => -- right turn
            pwm_l_reset <= '0';
            pwm_r_reset <= '1';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';            
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;              
            else
              new_state <= bbw_state;
              new_eureka <= TrackingLine;
            end if;


            when bwb_state => -- forward trigger
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= bwb_state;
              new_eureka <= TrackingLine;
            end if;


            when bww_state => -- right sharp turn
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '1'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= bww_state;
              new_eureka <= TrackingLine;
            end if;


            when wbb_state => -- left turn
            pwm_l_reset <= '1';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= wbb_state;
              new_eureka <= TrackingLine;
            end if;


            when wwb_state => -- left sharp turn
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '0';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= wwb_state;
              new_eureka <= TrackingLine;
            end if;


            when www_state => -- forward search
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= FindingLine;
            else
              new_state <= www_state;
              new_eureka <= TrackingLine;
            end if;


      end case;
    end process;


  end architecture behaviour;

Предупреждения:

Warning (18236): Number of processors has not been specified which may cause overloading on shared machines.  Set the global assignment NUM_PARALLEL_PROCESSORS in your QSF to an appropriate value for best performance.
Warning (10631): VHDL Process Statement warning at LineFinder.vhdl(84): inferring latch(es) for signal or variable "new_StoredValue", which holds its previous value in one or more paths through the process
Warning (10631): VHDL Process Statement warning at LineFinder.vhdl(84): inferring latch(es) for signal or variable "new_eureka", which holds its previous value in one or more paths through the process
Warning (13012): Latch LineFinder:lbl1|new_eureka.TrackingLine_445 has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal LineFinder:lbl1|state.reset_state
Warning (13012): Latch LineFinder:lbl1|new_eureka.CorrectingRight_463 has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal LineFinder:lbl1|state.reset_state
Warning (13012): Latch LineFinder:lbl1|new_StoredValue[0] has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal input_buffer:lbl0|ThreeBitRegister:lbl1|data_out[2]
Warning (13012): Latch LineFinder:lbl1|new_StoredValue[2] has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal input_buffer:lbl0|ThreeBitRegister:lbl1|data_out[0]
Warning (13012): Latch LineFinder:lbl1|new_eureka.PassingLine_472 has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal LineFinder:lbl1|state.reset_state
Warning (13012): Latch LineFinder:lbl1|new_eureka.FindingLine_481 has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal LineFinder:lbl1|state.reset_state
Warning (13012): Latch LineFinder:lbl1|new_eureka.CorrectingLeft_454 has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal LineFinder:lbl1|state.reset_state
Warning (18236): Number of processors has not been specified which may cause overloading on shared machines.  Set the global assignment NUM_PARALLEL_PROCESSORS in your QSF to an appropriate value for best performance.
Warning (292013): Feature LogicLock is only available with a valid subscription license. You can purchase a software subscription to gain full access to this feature.
Warning (15714): Some pins have incomplete I/O assignments. Refer to the I/O Assignment Warnings report for details
Warning (335093): TimeQuest Timing Analyzer is analyzing 7 combinational loops as latches. For more details, run the Check Timing command in the TimeQuest Timing Analyzer or view the "User-Specified and Inferred Latches" table in the Analysis & Synthesis report.
Warning (18236): Number of processors has not been specified which may cause overloading on shared machines.  Set the global assignment NUM_PARALLEL_PROCESSORS in your QSF to an appropriate value for best performance.
Warning (18236): Number of processors has not been specified which may cause overloading on shared machines.  Set the global assignment NUM_PARALLEL_PROCESSORS in your QSF to an appropriate value for best performance.
Warning (335093): TimeQuest Timing Analyzer is analyzing 7 combinational loops as latches. For more details, run the Check Timing command in the TimeQuest Timing Analyzer or view the "User-Specified and Inferred Latches" table in the Analysis & Synthesis report.
Warning (18236): Number of processors has not been specified which may cause overloading on shared machines.  Set the global assignment NUM_PARALLEL_PROCESSORS in your QSF to an appropriate value for best performance.
Warning (10905): Generated the EDA functional simulation netlist because it is the only supported netlist type for this device.

person user3604362    schedule 15.12.2016    source источник
comment
Все ваши защелки вызваны комбинаторным процессом process2. Пример 1: new_StoredValue не задается оператором else в начале процесса. Пример 2: то же самое для new_eureka в состоянии reset_state. Вам необходимо указать статус всех ваших сигналов во всех возможных состояниях. В противном случае, чтобы избежать этого, вы можете использовать только синхронизированные процессы.   -  person A. Kieffer    schedule 15.12.2016
comment
Имейте в виду, что вы работаете с оборудованием, а не с программным обеспечением. Вам не обязательно переходить в состояние сброса, чтобы делать другие вещи, вы можете просто делать их параллельно. В этом все преимущество специализированного оборудования для цифровой логики.   -  person QuantumRipple    schedule 23.12.2016
comment
Правда QuantumRipple, но в данном случае моторы, которые у нас есть, работают только при условии регулярного сброса системы, если только не передавать в моторы интеллект контроллера. Но это приводит к беспорядку.   -  person user3604362    schedule 24.12.2016


Ответы (1)


Действительно, как упоминалось в разделе комментариев А. Киффера, я не указывал во всех случаях (особенно в состоянии сброса), что такое new_StoredValue или new_eureka. Затем это принятие решений было введено защелками, предлагающими нежелательное поведение.

В приведенном ниже исправленном коде удается избежать создания защелок.

library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity LineFinder is
  port (    clk     : in    std_logic;
        reset       : in    std_logic;
        count_out   : in    std_logic_vector(19 downto 0);
      sensor_l_out  : in    std_logic;
        sensor_m_out    : in    std_logic;
        sensor_r_out    : in    std_logic;

        pwm_l_reset : out   std_logic;
        pwm_l_direction : out std_logic;
        pwm_r_reset : out   std_logic;
        pwm_r_direction : out std_logic;    

        count_reset: out std_logic  
    );
end entity LineFinder;


architecture behaviour of LineFinder is

  component input_buffer is
    port (  clk     : in    std_logic;

        sensor_l_in : in    std_logic;
        sensor_m_in : in    std_logic;
        sensor_r_in : in    std_logic;

        sensor_l_out    : out   std_logic;
        sensor_m_out    : out   std_logic;
        sensor_r_out    : out   std_logic
    );
  end component input_buffer;

  type line_state is (reset_state, 
                      FindLine_state, 
                      PassLine_state, 
                      CorrectLeft_state, 
                      CorrectRight_state, 
                      wbw_state,

                      bbb_state,
                      bbw_state, 
                      bwb_state, 
                      bww_state, 
                      wbb_state,  
                      wwb_state, 
                      www_state);                   
  signal state , new_state: line_state ;

  type eureka_state is (FindingLine, 
            PassingLine, 
            CorrectingRight, 
            CorrectingLeft,  
            TrackingLine);
  signal eureka, new_eureka: eureka_state;

  signal StoredValue, new_StoredValue: std_logic_vector(2 downto 0) := "000";

  constant period: std_logic_vector(19 downto 0) := std_logic_vector (to_unsigned(1000000, 20));

  begin


    Process1: process (clk, reset)
      begin
        if (rising_edge(clk)) then
          if (reset ='1') then
            state <= FindLine_state;
            eureka <= FindingLine;
        StoredValue <= "000";
          else
          state <= new_state;
          eureka <= new_eureka;
      StoredValue <= new_StoredValue;
        end if;
      end if;
      end process;

      --Finding Line process
      Process2: process (state, eureka, StoredValue, count_out, sensor_l_out, sensor_m_out, sensor_r_out)
        begin
          if ((not((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '0'))) and (eureka = PassingLine)) then
            new_StoredValue <= sensor_r_out & sensor_m_out & sensor_l_out;
      else
        new_StoredValue <= StoredValue;
          end if;

          case state is
          when FindLine_state =>
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= FindingLine;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '0')) then
              new_state <= FindLine_state;
              new_eureka <= FindingLine;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
              new_state <= wbw_state;
              new_eureka <= TrackingLine;
            else
              new_state <= PassLine_state;
              new_eureka <= PassingLine;
            end if;

          when PassLine_state =>
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= PassingLine;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '0')) then
              if ((StoredValue = "001") or (StoredValue = "011")) then 
                  new_state <= CorrectRight_state;
                  new_eureka <= CorrectingRight;
              else
                  new_state <= CorrectLeft_state;
                  new_eureka <= CorrectingLeft;
              end if;
            else 
              new_state <= PassLine_state;
              new_eureka <= PassingLine;
            end if;


          when CorrectRight_state =>
            pwm_l_reset <= '0'; --making sharp turn to right
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '1'; 
            count_reset <= '0';            
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= CorrectingRight;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
              new_state <= wbw_state;
              new_eureka <= TrackingLine;
            else
              new_state <= CorrectRight_state;
              new_eureka <= CorrectingRight;
            end if;

          when CorrectLeft_state => 
            pwm_l_reset <= '0'; --making sharp turn to left
            pwm_r_reset <= '0';
            pwm_l_direction <= '0';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= CorrectingLeft;
            elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
              new_state <= wbw_state;
              new_eureka <= TrackingLine;
            else
              new_state <= CorrectLeft_state;
              new_eureka <= CorrectingLeft;
            end if;

          when wbw_state =>     --aka LineFoundState   
            -- go to LineTracker process!
            -- forward trigger
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';      
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= wbw_state;
              new_eureka <= TrackingLine;
            end if;

          when reset_state => 
            pwm_l_reset <= '1';
            pwm_r_reset <= '1';
            pwm_l_direction <= '1';
            pwm_r_direction <= '1';
            count_reset <= '1';
            if (not(eureka = TrackingLine)) then
              if (eureka = FindingLine) then
                new_state <= FindLine_state;
                new_eureka <= FindingLine;
              elsif (eureka = PassingLine) then
                new_state <= PassLine_state;
                new_eureka <= PassingLine;
              elsif (eureka = CorrectingRight) then
                new_state <= CorrectRight_state;
                new_eureka <= CorrectingRight;
              elsif (eureka = CorrectingLeft) then
                new_state <= CorrectLeft_state;
                new_eureka <= CorrectingLeft;
              else
                new_state <= FindLine_state;  --do we need this?
                new_eureka <= FindingLine;
              end if;
            else
              --The other reset process
              if ((sensor_l_out = '1') and (sensor_m_out ='1') and (sensor_r_out = '1')) then
                new_state <= bbb_state;
                new_eureka <= eureka;
              elsif ((sensor_l_out = '1') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
                new_state <= bbw_state;
                new_eureka <= eureka;
              elsif ((sensor_l_out = '1') and (sensor_m_out ='0') and (sensor_r_out = '1')) then
                new_state <= bwb_state;
                new_eureka <= eureka;
              elsif ((sensor_l_out = '1') and (sensor_m_out ='0') and (sensor_r_out = '0')) then
                new_state <= bww_state;
                new_eureka <= eureka;
              elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '1')) then
                new_state <= wbb_state;
                new_eureka <= eureka;
              elsif ((sensor_l_out = '0') and (sensor_m_out ='1') and (sensor_r_out = '0')) then
                new_state <= wbw_state;
                new_eureka <= eureka;
              elsif ((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '1')) then
                new_state <= wwb_state;
                new_eureka <= eureka;
              elsif ((sensor_l_out = '0') and (sensor_m_out ='0') and (sensor_r_out = '0')) then
                new_state <= www_state;  
                new_eureka <= eureka;           
              else
                new_state <= reset_state;
                new_eureka <= eureka;
              end if;
            end if;



            when bbb_state => -- forward
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';      
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= bbb_state;
              new_eureka <= TrackingLine;
            end if;


            when bbw_state => -- right turn
            pwm_l_reset <= '0';
            pwm_r_reset <= '1';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';            
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;              
            else
              new_state <= bbw_state;
              new_eureka <= TrackingLine;
            end if;


            when bwb_state => -- forward trigger
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= bwb_state;
              new_eureka <= TrackingLine;
            end if;


            when bww_state => -- right sharp turn
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '1'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= bww_state;
              new_eureka <= TrackingLine;
            end if;


            when wbb_state => -- left turn
            pwm_l_reset <= '1';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= wbb_state;
              new_eureka <= TrackingLine;
            end if;


            when wwb_state => -- left sharp turn
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '0';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= TrackingLine;
            else
              new_state <= wwb_state;
              new_eureka <= TrackingLine;
            end if;


            when www_state => -- forward search
            pwm_l_reset <= '0';
            pwm_r_reset <= '0';
            pwm_l_direction <= '1';
            pwm_r_direction <= '0'; 
            count_reset <= '0';
            if (count_out >= period) then
              new_state <= reset_state;
              new_eureka <= FindingLine;
            else
              new_state <= www_state;
              new_eureka <= TrackingLine;
            end if;

      end case;
    end process;


  end architecture behaviour;
person user3604362    schedule 15.12.2016