3
\$\begingroup\$

In my digital electronics class we are currently dealing with Finite-State-Machines and VHDL.

I have written a VHDL-code for finite state machine and I've run into trouble. I want to attach the output to my state, but I don't know how to do it.

For example, I have a state \$S_0\$ where the outputs are \$z_0 =0\$, \$z_1=0\$, \$z_3=0\$.

How do I "attach" that output to \$S_0\$ in terms of VHDL-coding?

Something like: \$S_0: z_0 <=0; z_1<=0; z_2<=0;\$

just gives me: "\$S_0\$ is already defined in this region".

Here is my VHDL-code. I have no idea if what I've written make sense, but hopefully, you can help me?

use IEEE.STD_LOGIC_1164.ALL;

entity Thunderbird is
    port(   B        :  in  std_logic;
            L         :    in    std_logic;
            R         :    in    std_logic;
            H         :    in    std_logic;
            Reset     :    in    std_logic;
            Clock     :    in    std_logic;
            L0,L1,L2 :    out    std_logic;
            R0,R1,R2 :    out    std_logic);
end Thunderbird;

architecture Behavioral of Thunderbird is

type state_type is (s00, sH, sB, sR1, sRB1, sR2, sRB2, sR3, sL1, sLB1, sL2, sLB2, sL3, sTB, sRB0, sLB0);
signal current_state, next_state: state_type;
begin

process(all)
begin
    if rising_edge(Clock) then
        if Reset = '1'
            then current_state <= s00;
            else
            current_state <= next_state;
        end if;
    end if;


    case current_state is
    when s00 => 
         if H ='1' then next_state <= sH;
           elsif 
            H = '0' and L = '0' and R = '0' and B = '1' then next_state <= sB;
           elsif 
              H = '0' and L = '1' and R = '0' and B = '0' then next_state <= sL1;
            elsif 
              H = '0' and L = '1' and R = '0' and B = '1' then next_state <= sLB1;
            elsif
             H = '0' and L = '0' and R = '1' and B = '0'  then next_state <= sR1; 
            elsif
             H = '0' and L = '0' and R = '1' and B = '1'  then next_state <= sRB1;
        end if;

    when sH => 
        next_state <= s00;

    when sB =>
        if H = '0' and L = '0' and R = '0' and B = '0' then next_state <= s00;
        elsif
           H = '1' then next_state <= sH;
        elsif
        H = '0' and L = '0' and R = '1' and B = '1' then next_state <=sRB1;
        elsif
        H = '0' and L = '1' and R = '0' and B = '1' then next_state <=sLB1;
        elsif
        H = '0' and L = '1' and R = '0' and B = '0' then next_state <=sL1;
        elsif
        H = '0' and L = '0' and R = '1' and B = '0' then next_state <= sR1;
       end if;

    when sR1 =>
        if H = '0' and B = '0' then next_state <=sR2;
        elsif
        H = '0' and B = '1' then next_state <= sRB2;
        elsif
        H = '1' then next_state <= sH;
       end if;

    when sR2 =>
        if H = '0' and B = '0' then next_state <= sR3;
        elsif
        H = '0' and B = '1' then next_state <= sTB;
        elsif
        H = '1' then next_state <= sH;
       end if;

    when sR3 =>
        if H = '0' and B = '0' then next_state <= s00;
        elsif
        H = '0' and B = '1' then next_state <= sRB0;
        elsif
        H = '1' then next_state <= sH;
        end if;

    when sRB1 =>
        if H = '0' and B = '0' then next_state <= sR2;
        elsif
        H = '0' and B = '1' then next_state <= sRB2;
        elsif
        H = '1' then next_state <= sH;
        end if;

   when sRB2 =>
    if H = '0' and B = '0' then next_state <= sR3;
    elsif 
    H = '0' and B = '1' then next_state <= sTB;
    elsif
    H = '1' then next_state <= sH;
       end if;

   when sL1 =>
   if H = '0' and B = '0' then next_state <=sL2;
   elsif
   H = '0' and B = '1' then next_state <= sLB2;
   elsif
   H = '1' then next_state <= sH;
       end if;

   when sL2 =>
   if H = '0' and B = '0' then next_state <= sL3;
   elsif
   H = '0' and L = '0' and R = '0' and B = '1' then next_state <= sTB;
   elsif
   H = '1' then next_state <= sH;
   end if;

    when sL3 =>
        if H = '0' and B = '0' then next_state <= s00;
        elsif
        H = '0' and B = '1' then next_state <= sLB0;
        elsif
        H = '1' then next_state <= sH;
       end if;

    when sRB0 =>
      if H = '1' then next_state <= sH;
      elsif 
      H = '0' and L = '0' and R = '0' and B = '1' then next_state <= sB;
      elsif 
      H = '0' and L = '1' and R = '0' and B = '0' then next_state <= sL1;
      elsif 
      H = '0' and L = '1' and R = '0' and B = '1' then next_state <= sLB1;
      elsif
      H = '0' and L = '0' and R = '1' and B = '0' then next_state <= sR1; 
      elsif
      H = '0' and L = '0' and R = '1' and B = '1' then next_state <= sRB1;
      end if;

     when sLB0 =>
     if H = '1' then next_state <= sH;
     elsif 
     H = '0' and L = '0' and R = '0' and B = '1' then next_state <= sB;
     elsif 
     H = '0' and L = '1' and R = '0' and B = '0' then next_state <= sL1;
     elsif 
     H = '0' and L = '1' and R = '0' and B = '1' then next_state <= sLB1;
     elsif
     H = '0' and L = '0' and R = '1' and B = '0' then next_state <= sR1; 
     elsif
     H = '0' and L = '0' and R = '1'and B = '1' then next_state <= sRB1;
     end if;  

      when sLB1 =>
         if H = '0' and B = '0' then next_state <= sL2;
           elsif
           H = '0' and B = '1' then next_state <= sLB2;
           elsif
           H = '1' then next_state <= sH;
           end if;

      when sLB2 =>
       if H = '0' and B = '0' then next_state <= sL3;
       elsif 
       H = '0' and B = '1' then next_state <= sTB;
       elsif
       H = '1' then next_state <= sH;
          end if;

     when sTB =>
        if H = '0' and B = '0' then next_state <= s00;
        elsif
        H = '0' and B = '1' then next_state <= sB;
        elsif
        H = '1' then next_state <= sH;
        end if;

        end case;
end process;


end Behavioral;

\$\endgroup\$
3
  • \$\begingroup\$ Can you share more of your code, so that we can see how you defined S0 and what structure you used for your FSM? \$\endgroup\$
    – The Photon
    Commented Nov 30, 2019 at 15:59
  • \$\begingroup\$ I have added some additional information. \$\endgroup\$
    – Carl
    Commented Nov 30, 2019 at 16:37
  • 1
    \$\begingroup\$ OK, sorry I am a Verilog guy so can't give you VHDL syntax. But basically for each output you will write a decoder that has the state variable as inputs and outputs the correct value depending on the state. \$\endgroup\$
    – The Photon
    Commented Nov 30, 2019 at 16:39

1 Answer 1

4
\$\begingroup\$

For writing concurrent code (outside of a clocked process), try this:

z0 <= '0' when (current_state = s00) else
      '1' when (current_state = sh) else
      '0'; --when others

z1 <= '0' when (current_state = s00) else
      '0' when (current_state = sh) else
      '1'; --when others

make sure that the last selection doesn't have a "when (...)" or else you will produce inferred latches (bad). Another way to do this would be to assign z0,z1, etc directly at the same location you are assigning next_state to current state:

if (next_state = s00) then
   z0 <= '0';
   z1 <= '0';
elsif (next_state = sh) then
   z0 <= '1';
   z1 <= '0';
else
   z0 <= '0';
   z1 <= '1';
end if;

Either make a signal named "z0" and "z1" in your architecture declaration section (and then drive the appropriate output), or add "z0" and "z1" as an output port to your module.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.