0
\$\begingroup\$

I have been trying to implement a Vending Machine where the user selects P(2to0) P(2) : 3.5 Currency_X P(1) : 3 Currency_X P(0) : 2.5 Currency_X C(3 to 0) as coins 5 Currency_X / 2 Currency_X / 1 Currency_X / 0.5 Currency_X. And it gives the money back (R2to0) (2,1,0.5) and the item. My code seems to not go the next state (S2) which returns the money back.

    entity Vending_Machine is
    Port ( C : in  STD_LOGIC_VECTOR (3 downto 0);
           P : in  STD_LOGIC_VECTOR (2 downto 0);
           CLK : in  STD_LOGIC;
           Reset : in  STD_LOGIC;
           R : out  STD_LOGIC_VECTOR (2 downto 0);
           Vend : out  STD_LOGIC_VECTOR (2 downto 0));
end Vending_Machine;

architecture Behavioral of Vending_Machine is
    type STATE_TYPE is (S0,S1,S2,S3);
    signal CurrentState,NextState:STATE_TYPE;



begin   
            --CLK and Reset Process
        process (CLK, Reset)
        begin 
                if (Reset = '1') then 
                        CurrentState <= S0;
                elsif (CLK 'Event and CLK = '1') then 
                        CurrentState <= NextState;
                end if;
                end process; 


                --Vending Machine Process
        process (CurrentState,P(0),P(1),P(2),C(0),C(1),C(2), C(3))
            Variable Sum , Price, Product, Change : INTEGER; 
            begin 

        case CurrentState is 
            when S0=>                           --Will check which product is selected
                    R <="000";
                    Vend<="000";
                if ( P(0)= '1' ) then 
                    Price := 5;                 --Due to Errors in REAL We changed to INT
                    Product := 1; 
                    Sum := 0;
                    NextState <= S1;
                end if;
                if ( P(1) = '1' ) then 
                    Price := 6;
                    Product := 2; 
                    Sum := 0;
                    NextState <= S1;
                end if;
                if ( P(2) = '1' ) then 
                    Price := 7;
                    Product := 3; 
                    Sum := 0;
                    NextState <= S1;
                end if;
            when S1=>
                if(C(0) = '1') then 
                    Sum := Sum + 1;
                elsif(C(1) = '1') then 
                    Sum := Sum + 2;
                elsif(C(2) = '1') then 
                    Sum := Sum + 4;
                elsif(C(3) = '1') then 
                    Sum := Sum + 10;
                end if;
                if(Price > Sum) then
                    NextState <= S1;
                elsif (Price <= Sum) then
                    Change := Sum - Price;
                    NextState <= S2;
                end if;
                                                        -- Change Possibilites, 1 / 2 / 4.
            when S2=>
                if ( Change >= 4 ) then 
                    R<="100";
                    Change:=Change -4;
                elsif( Change >= 2) then 
                    R<= "010";
                    Change:=Change-2;
                elsif(Change >= 1) then
                    R<="001";
                    Change:=Change-1;
                end if;
                if(Change > 0 ) then 
                    NextState <= S2; 
                elsif (Change = 0) then
                    NextState <=S3;
                end if;
            When S3=> 
                if ( Product = 1) then 
                    Vend <= "001";
                elsif(Product = 2) then
                    Vend <= "010"; 
                elsif (Product = 3) then
                    Vend <= "100";
                end if;
                    NextState <= S0;
            end case;end process;end Behavioral;
```
\$\endgroup\$
  • 1
    \$\begingroup\$ look at your post .... do you see how part of the code is on gray background and is easy to read? ...... select all of the code and press ctrl-k or click the {} button .... all of your code will be easy to read \$\endgroup\$ – jsotola Apr 13 '19 at 1:10
  • \$\begingroup\$ @jsotola thank you! \$\endgroup\$ – Waleed Titi Apr 13 '19 at 7:05
0
\$\begingroup\$

Your sensitivity list for the non-clocked process is incomplete: at least clock and reset should also be added. You'd need to show your testbench, but the code as shown right now cannot work: if you want to pay across multiple clock cycles with the same coin, you'll keep the C signals steady and the secondary process won't fire anymore.

Consider writing the whole module using a one-process style or switching to VHDL 2008 so you can use all in your sensitivity list.

Also: this would have been trivial to see if you had simulated your code and traced your variables. The paid sum would have stopped increasing.

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ (this answer will induce a different bug if you just update your sensitivity list: you'll have integer overflow on Sum. Again: consider using a one-process style or use a fully two-process style where everything is a signal). \$\endgroup\$ – DonFusili Apr 15 '19 at 7:23
  • \$\begingroup\$ I wouldn't say the sensitivity list is incomplete, it's just wrong. Either as mentioned include everything into one clocked process, then the current sensitivity list is obsolete or do the signalmanipulation in the clocked process the same way you manipulate the state (e.g. change <= next_change with setting next_change instead of change in the Vending Machine Process). \$\endgroup\$ – po.pe Apr 15 '19 at 8:13
-1
\$\begingroup\$

You shouldn't be using non-blocking assignments to assign the value of NextState...that is a combinational logic block.

You also use non-blocking assignments for R and Vend. If you really want those values to be in registers you need to put them in a clocked process, as you have done for CurrentState.

|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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