Forum Discussion

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

Vending Machine

Hi there.

I have a school project which consists in a vending machine that has 3 products ( diferent prices) and i can only use 4 type of coins.

My idea is to make a FSM ( where each state equals to the sum of coins that i put in the machine).

Am i thinkg right? Can you guys help me?

8 Replies

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

    This is my code so far:

    (coins : 0.10; 0.20; 0.50 ans 1.00)

    library IEEE;

    use IEEE.STD_LOGIC_1164.all;

    use IEEE.NUMERIC_STD.all;

    entity VendingMachine is

    port(sel: in std_logic_vector(1 downto 0);

    reset,clk,u,d,c,t: in std_logic;

    opn: out std_logic;

    total: out std_logic);

    end VendingMachine;

    architecture Behav of VendingMachine is

    type estados is(s0, s10,s20,s30,s40,s50,s60,s70,s80,s90,s100,s110,s120,s130,s140,s150,s160,s170,s180,s190,s200,s210,opnd);

    signal ps, ns : estados;

    begin

    sync_proc: process(clk, reset)

    begin

    if(reset = '1') then

    ps <= s0;

    elsif(rising_edge(clk)) then

    ps <= ns;

    end if;

    end process;

    comb_proc: process(ps,u,d,c,t,ns)

    begin

    ns <= ps;

    case ps is

    when s0 => --0.00€

    if u = '1' then ns <= s10;

    elsif d = '1' then ns <= s20;

    elsif c = '1' then ns <= s50;

    elsif t = '1' then ns <= s100;

    end if;

    when s10 =>

    if u = '1' then ns <= s20;

    elsif d = '1' then ns <= s30;

    elsif c = '1' then ns <= s60;

    elsif t = '1' then ns <= s110;

    end if;

    when s20 =>

    if u = '1' then ns <= s30;

    elsif d = '1' then ns <= s40;

    elsif c = '1' then ns <= s70;

    elsif t = '1' then ns <= s120;

    end if;

    when s30 =>

    if u = '1' then ns <= s40;

    elsif d = '1' then ns <= s50;

    elsif c = '1' then ns <= s80;

    elsif t = '1' then ns <= s130;

    end if;

    when s40 =>

    if u = '1' then ns <= s50;

    elsif d = '1' then ns <= s60;

    elsif c = '1' then ns <= s90;

    elsif t = '1' then ns <= s140;

    end if;

    when s50 =>

    if u = '1' then ns <= s60;

    elsif d = '1' then ns <= s70;

    elsif c = '1' then ns <= s100;

    elsif t = '1' then ns <= s150;

    end if;

    when s60 =>

    if u = '1' then ns <= s70;

    elsif d = '1' then ns <= s80;

    elsif c = '1' then ns <= s110;

    elsif t = '1' then ns <= s160;

    end if;

    when s70 =>

    if u = '1' then ns <= s80;

    elsif d = '1' then ns <= s90;

    elsif c = '1' then ns <= s120;

    elsif t = '1' then ns <= s170;

    end if;

    when s80 =>

    if u = '1' then ns <= s90;

    elsif d = '1' then ns <= s100;

    elsif c = '1' then ns <= s130;

    elsif t = '1' then ns <= s180;

    end if;

    if(sel = "01") then

    ns <= opnd;

    end if;

    when s90 =>

    if u = '1' then ns <= s100;

    elsif d = '1' then ns <= s110;

    elsif c = '1' then ns <= s140;

    elsif t = '1' then ns <= s190;

    end if;

    if(sel = "01") then

    ns <= opnd;

    end if;

    when s100 =>

    if u = '1' then ns <= s110;

    elsif d = '1' then ns <= s120;

    elsif c = '1' then ns <= s150;

    elsif t = '1' then ns <= s200;

    end if;

    if( sel = "10") then

    ns <= opnd;

    elsif(sel = "01") then

    ns <= opnd;

    end if;

    when s110 =>

    if u = '1' then ns <= s120;

    elsif d = '1' then ns <= s130;

    elsif c = '1' then ns <= s160;

    elsif t = '1' then ns <= s210;

    end if;

    if( sel = "10") then

    ns <= opnd;

    elsif(sel = "01") then

    ns <= opnd;

    end if;

    when s120 =>

    if u = '1' then ns <= s130;

    elsif d = '1' then ns <= s150;

    elsif c = '1' then ns <= s170;

    end if;

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when s130 =>

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when s140 =>

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when s150 =>

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when s160 =>

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when s170 =>

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when s180 =>

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when s190 =>

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when s200 =>

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when s210 =>

    if(sel = "01") then

    ns <= opnd;

    elsif( sel = "10") then

    ns <= opnd;

    elsif(sel <= "11") then

    ns <= opnd;

    end if;

    when opnd =>

    opn <= '1';

    when others =>

    ns <= ps;

    end case;

    end process;

    end Behav;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It's probably better keep a total, say a 16 bit number of cents. What you have will use up quite a few resources. Fewer resources = cheaper chip. What happens in your design when someone puts $2.25 or $5.00 in the machine?

    Edit: Fewer resources is relative. Your code as it is now will fit in any modern CPLD. It's better to learn to be frugal with resources at all times. It is always easier to design for fewer resources in the first place than it is to trim down a design that is using too many.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Similarly to the above remark, seems like wanted to create 1 state for each possible value, which is a real waste if compared to store the sum within 3 unsigned variables, 1 variable per product. In addition, it also would be better you drew a short draft of your design.

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

    I agree with andre_teprom making a drawing of your design helps in understanding what you are doing. Once you have drawn your state machine you can look at states that are identical and have paths to the same destination under the same conditions. These can be simplified into one state. If you have your drawing, then write the code. It also helps in spotting dead ends or unwanted loops.

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

    This is a school project, i can't use $5.00 ( five dollars ? we use euros) because we have some restrictions, like, i can only use 4 coins (and i chose 0.10€, 0.20€, 0.50€ and 1.00€) and I can only have 3 products, with random prices, so i thougt that the max price that someone can put in the machine was 2.10€, since the the product with the highest price is 1.20€.

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

    --- Quote Start ---

    It's probably better keep a total, say a 16 bit number of cents. What you have will use up quite a few resources. Fewer resources = cheaper chip. What happens in your design when someone puts $2.25 or $5.00 in the machine?

    Edit: Fewer resources is relative. Your code as it is now will fit in any modern CPLD. It's better to learn to be frugal with resources at all times. It is always easier to design for fewer resources in the first place than it is to trim down a design that is using too many.

    --- Quote End ---

    This is a school project, i can't use $5.00 ( five dollars ? we use euros) because we have some restrictions, like, i can only use 4 coins (and i chose 0.10€, 0.20€, 0.50€ and 1.00€) and I can only have 3 products, with random prices, so i thougt that the max price that someone can put in the machine was 2.10€, since the the product with the highest price is 1.20€.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Similarly to the above remark, seems like wanted to create 1 state for each possible value, which is a real waste if compared to store the sum within 3 unsigned variables, 1 variable per product. In addition, it also would be better you drew a short draft of your design.

    --- Quote End ---

    --- Quote Start ---

    I agree with andre_teprom making a drawing of your design helps in understanding what you are doing. Once you have drawn your state machine you can look at states that are identical and have paths to the same destination under the same conditions. These can be simplified into one state. If you have your drawing, then write the code. It also helps in spotting dead ends or unwanted loops.

    --- Quote End ---

    I thought this was the best way... Can u guys help me using a more efficient way?