OpenCores
URL https://opencores.org/ocsvn/mcu8/mcu8/trunk

Subversion Repositories mcu8

[/] [mcu8/] [trunk/] [src/] [EXAMPLES/] [candy_machine.vhd] - Rev 24

Compare with Previous | Blame | View Log

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.asci_types.all;
 
entity candy_machine is
  generic( one_sec_factor : INTEGER := 1e5/2-1;  -- 1e8/2-1 for 1s; change to 5
-- for synthesis (1 ms period)
           ok_factor : INTEGER := 6000;  --change to 5000 for synthesis
           period_factor : INTEGER := 300;  --50ms
           problem_factor : INTEGER := 1000);
  port( clk : in std_logic;
-- j_left=5cent, j_up=10cent, j_right=20cent, j_down=rst
        j_down, j_up, j_left, j_right : IN std_logic;
--        money_rest : out STD_LOGIC_VECTOR (2 DOWNTO 0);
-- if '1' the machine gives all the money in the temp. save out
--        money_error : OUT std_vector;
-- if '1' gives a candy out
--        candy : out std_logic;
-- "0001"=candy, "0010"=5cent, "0100"=10cent, "1000"=20cent, "1110"=error
        led : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
        lcd_print  : OUT lcd_matrix );
end candy_machine;
 
 
architecture behavioral of candy_machine is
  TYPE state IS (s0, s5, s10, s15, s20, s25, s30, s35, s40, problem, wait_before_s5,
                 wait_before_s10, wait_before_s15, wait_before_s20);
  signal pr_state, nxt_state : state;
  signal money : STD_LOGIC_VECTOR (2 DOWNTO 0);  -- "100"=5cent "010"=10cent "001"=20cent
  signal one_sec, rst_int : STD_LOGIC := '0';
  signal counter : INTEGER RANGE 0 TO ok_factor; 
  SIGNAL rst : STD_LOGIC := '1';
begin
 
 
time_p: process(clk)  
  variable temp0 : integer RANGE 0 TO ok_factor;
  VARIABLE flag : STD_LOGIC := '0';
BEGIN
    IF clk'EVENT AND clk='1' THEN
      IF rst_int='0' THEN 
        temp0 := 0;
        flag := '1';                    -- because of the one_sec_p process
      else                
        IF one_sec='0' THEN
          flag := '0';
--this part is executed only on a
--positive transition of the one_sec signal, the counter factors multiply the
--period of the one_sec signal. If you need to speed up the execution change
--the on_sec_factor to a lower VALUE
        elsif flag='0' THEN
          flag := '1';
          IF
            temp0>=ok_factor THEN
            temp0 := 0;
          ELSE
            temp0 := temp0 + 1;
          end if;
        END if;
      END if;
    END if;
    counter <= temp0;
END process;
 
--------------------------------------------------------------------------------------
-- generates the one_sec signal. Period of the signal is 1s if one_sec_factor=1e8/2-1
-- for 100MHz oszillator
--------------------------------------------------------------------------------------
one_sec_p: process(clk)
  VARIABLE temp : integer RANGE 0 TO one_sec_factor;
  begin
    IF clk'event AND clk='1' THEN
      IF rst_int='0' THEN 
        temp := 0;
        one_sec <= '1';                 -- take a look at lcd1.vhd to see why
      else     
        iF temp>=one_sec_factor THEN
          temp := 0;
          one_sec <= NOT one_sec;
        else
          temp := temp + 1;
        END if;
      END if;
    END IF;
  END process;
 
-------------------------------------------------------------------------------
-- LCD matrix
-------------------------------------------------------------------------------
lcd_m: process(clk)
  BEGIN
    IF clk'EVENT AND clk='1' THEN
      CASE pr_state IS
        WHEN s0 =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      ' ','P','l','e','a','s','e',' ','i','n','s','e','r','t',':',' ','2','5','c',' ', 
                      ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' );
        WHEN s5 | wait_before_s5 =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      ' ','P','l','e','a','s','e',' ','i','n','s','e','r','t',':',' ','2','0','c',' ', 
                      ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' );
        WHEN s10 | wait_before_s10 =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      ' ','P','l','e','a','s','e',' ','i','n','s','e','r','t',':',' ','1','5','c',' ', 
                      ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' );
        WHEN s15 | wait_before_s15 =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      ' ','P','l','e','a','s','e',' ','i','n','s','e','r','t',':',' ','1','0','c',' ', 
                      ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' );          
        WHEN s20 | wait_before_s20 =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      ' ','P','l','e','a','s','e',' ','i','n','s','e','r','t',':',' ',' ','5','c',' ', 
                      ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' );
        WHEN s25 =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      'Y','o','u','r',' ','c','o','f','f','e',' ','i','s',' ','r','e','a','d','y','!', 
                      ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' );          
        WHEN s30 =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      'Y','o','u','r',' ','c','o','f','f','e',' ','i','s',' ','r','e','a','d','y','!', 
                      'Y','o','u',' ','h','a','v','e',':',' ','5','c',' ',' ','c','h','a','n','g','e' );          
        WHEN s35 =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      'Y','o','u','r',' ','c','o','f','f','e',' ','i','s',' ','r','e','a','d','y','!', 
                      'Y','o','u',' ','h','a','v','e',':',' ','1','0','c',' ','c','h','a','n','g','e' );          
        WHEN s40 =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      'Y','o','u','r',' ','c','o','f','f','e',' ','i','s',' ','r','e','a','d','y','!', 
                      'Y','o','u',' ','h','a','v','e',':',' ','1','5','c',' ','c','h','a','n','g','e' );          
        WHEN OTHERS =>
          lcd_print <=  ( '-','-','-','C','o','f','f','e','e',' ','A','u','t','o','m','a','t','-','-','-',
                      ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-',' ',' ',' ',' ',' ',' ',' ',' ', 
                      ' ',' ',' ',' ',' ',' ',' ','E','r','r','o','r','!',' ',' ',' ',' ',' ',' ',' ', 
                      ' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ' );          
      END CASE;
    END IF;
  END process;
 
---------------------------------------------------------------------------------
-- this is a MORE automat, in order to save some registers, you can use MAELY too
---------------------------------------------------------------------------------
main_s_p: process(clk)
  begin
    if clk'event and clk='1' then
      IF rst='0' THEN
        pr_state <= s0;
      else
        pr_state <= nxt_state;
      end if;
    END if;
  end process;
 
 
main_c_p: process(pr_state,money,counter)
begin
  case pr_state is
      WHEN s0 =>
        CASE money IS
          WHEN "000" => nxt_state <= s0;
          WHEN "100" => nxt_state <= wait_before_s5;  
          WHEN "010" => nxt_state <= wait_before_s10;  
          WHEN "001" => nxt_state <= wait_before_s20;  
          WHEN OTHERS => nxt_state <= problem;
        END CASE;
        rst_int <= '0';
        led <= "0000";
      WHEN s5 =>
        CASE money IS
          WHEN "000" => nxt_state <= s5;
          WHEN "100" => nxt_state <= wait_before_s10;  
          WHEN "010" => nxt_state <= wait_before_s15;  
          WHEN "001" => nxt_state <= s25;
          WHEN OTHERS => nxt_state <= problem;
        END CASE;
        rst_int <= '0';
        led <= "1000";
      WHEN s10 =>
        CASE money IS
          WHEN "000" => nxt_state <= s10;
          WHEN "100" => nxt_state <= wait_before_s15;
          WHEN "010" => nxt_state <= wait_before_s20;
          WHEN "001" => nxt_state <= s30;
          WHEN OTHERS => nxt_state <= problem;
        END CASE;
        rst_int <= '0';
        led <= "0100";
      WHEN s15 =>
        CASE money IS
          WHEN "000" => nxt_state <= s15;
          WHEN "100" => nxt_state <= wait_before_s20;  
          WHEN "010" => nxt_state <= s25;
          WHEN "001" => nxt_state <= s35;  
          WHEN OTHERS => nxt_state <= problem;
        END CASE;
        rst_int <= '0';
        led <= "1100";
      WHEN s20 =>
        CASE money IS
          WHEN "000" => nxt_state <= s20;
          WHEN "100" => nxt_state <= s25;
          WHEN "010" => nxt_state <= s30;  
          WHEN "001" => nxt_state <= s40;  
          WHEN OTHERS => nxt_state <= problem;
        END CASE;
        led <= "0010";
        rst_int <= '0';
      WHEN s25 =>
        IF counter>=ok_factor THEN
          nxt_state <= s0;
        ELSE
          nxt_state <= s25;
        END IF;
        led <= "0001";
        rst_int <= '1';
      WHEN s30 =>
        IF counter>=ok_factor THEN
          nxt_state <= s0;
        ELSE
          nxt_state <= s30;
        END IF;
        led <= "1001";
        rst_int <= '1';
      WHEN s35 =>
        IF counter>=ok_factor THEN
          nxt_state <= s0;
        ELSE
          nxt_state <= s35;
        END IF;
        led <= "0101";
        rst_int <= '1';
      WHEN s40 =>
        IF counter>=ok_factor THEN
          nxt_state <= s0;
        ELSE
          nxt_state <= s40;
        END IF;
        led <= "1101";
        rst_int <= '1';
--      WHEN rst_before_s5 =>
--        nxt_state <= wait_before_s5;
--        led <= "0000";
--        rst_int <= '0';
--      WHEN rst_before_s10 =>
--        nxt_state <= wait_before_s10;
--        led <= "0000";
--        rst_int <= '0';
--      WHEN rst_before_s15 =>
--        nxt_state <= wait_before_s15;
--        led <= "0000";
--        rst_int <= '0';
--      WHEN rst_before_s20 =>
--        nxt_state <= wait_before_s20;
--        led <= "0000";
--        rst_int <= '0';
      WHEN wait_before_s5 =>
        IF counter>=period_factor THEN
          nxt_state <= s5;
        ELSE
          nxt_state <= wait_before_s5;
        END IF;
        led <= "1000";
        rst_int <= '1';
      WHEN wait_before_s10 =>
        IF counter>=period_factor THEN
          nxt_state <= s10;
        ELSE
          nxt_state <= wait_before_s10;
        END IF;
        led <= "0100";
        rst_int <= '1';
      WHEN wait_before_s15 =>
        IF counter>=period_factor THEN
          nxt_state <= s15;
        ELSE
          nxt_state <= wait_before_s15;
        END IF;
        led <= "1100";
        rst_int <= '1';
      WHEN wait_before_s20 =>
        IF counter>=period_factor THEN
          nxt_state <= s20;
        ELSE
          nxt_state <= wait_before_s20;
        END IF;
        led <= "0010";        
        rst_int <= '1';
      WHEN problem =>
        IF counter>=problem_factor THEN
          nxt_state <= s0;
        ELSE
          nxt_state <= problem;
        END IF;
        led <= "1110";
        rst_int <= '1';
      WHEN OTHERS =>
        nxt_state <= problem;
        led <= "1110";
        rst_int <= '0';
    END case;
  END process;
 
  rst <= j_down;
  money(2) <= NOT j_left;
  money(1) <= NOT j_up;
  money(0) <= NOT j_right;
 
END behavioral;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.