Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17258 Discussions

Need help with VHDL-project

Altera_Forum
Honored Contributor II
1,458 Views

Hi 

I'm working on a vending machine project. The VHDL code for the entity is in this pastie: 

 

 

 

(pastie.org/5475527

 

 

 

I need some help with getting the system to do what I want. As it is now, when one of the coin-buttons are pressed, the sum-so-far will keep on incrementing every clock cycle for as long as the button is pressed. 

 

I would like for the system to increment the sum only once everytime a button is pressed. 

 

 

 

So far, I have tried different solutions myself, but none seem to work.
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
716 Views

Re-posting with code in-line. 

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity vending_machine_cpu is Port( slow_clk : in std_logic; reset : in std_logic; sync_coin1 : in std_logic;--synchronized and debounced inputs sync_coin2 : in std_logic; sync_coin5 : in std_logic; sync_buy : in std_logic; price : in std_logic_vector(4 downto 0); --price set by switches sum : out std_logic_vector(7 downto 0); --sum-so-far of coins release_can : out std_logic; alarm : out std_logic); end vending_machine_cpu; architecture vending_machine_cpu of vending_machine_cpu is type state_type is (s1,s2); signal c_state,n_state : state_type; signal c_sum,n_sum : std_logic_vector(7 downto 0); begin FSM_state_reg: process(slow_clk,reset) begin if reset='1' then c_state <= s1; elsif (slow_clk'event and slow_clk='1') then c_state <= n_state; end if; end process; next_state: process(c_state,n_state,sync_buy) begin n_state <= c_state; case c_state is when s1 => if sync_buy='1' then n_state <= s2; else n_state <= s1; end if; when others => end case; end process; datapath_reg: process(slow_clk,reset) begin if reset='1' then c_sum <= (others => '0'); elsif (slow_clk'event and slow_clk='1') then c_sum <= n_sum; end if; end process; datapath: process(c_sum,sync_coin1,sync_coin2,sync_coin5,sync_buy,c_state,price) begin n_sum <= c_sum; alarm<='0'; release_can<='0'; case c_state is when s1 => alarm <= '0'; release_can <='0'; when others => if sync_coin1='1' then n_sum <= std_logic_vector(unsigned(c_sum) + 1 ); alarm <= '0'; release_can <='0'; elsif sync_coin2 = '1' then n_sum <= std_logic_vector(unsigned(c_sum) + 2 ); alarm <= '0'; release_can <='0'; elsif sync_coin5 = '1' then n_sum <= std_logic_vector(unsigned(c_sum) + 5 ); alarm <= '0'; release_can <='0'; elsif sync_buy='1' then if unsigned(c_sum) >= unsigned(price) then release_can <='1'; n_sum <= std_logic_vector(unsigned(c_sum)-unsigned(price)); alarm <= '0'; else alarm <= '1'; release_can <='0'; end if; else alarm <= '0'; release_can <='0'; end if; end case; sum <=c_sum; end process; end vending_machine_cpu; 

 

There are a few options that can be tried. I would suggest a rising edge detector, or you can possibly add another state in your state machine. Which path you take is up to you. 

 

A rising edge detector monitors your incoming signal and will send out a 1-clock wide pulse to indicate a rising edge was found. An example is below: 

 

PROCESS(slow_clk,reset) BEGIN IF (reset = '1') THEN input_s <= '0'; input_reg_s <= '0'; ELSIF (rising_edge(slow_clk)) THEN input_s <= sync_coin1; input_reg_s <= input_s; IF (input_reg_s = '0') AND (input_s = '1') THEN rising_edge_detect <= '1'; ELSE rising_edge_detect <= '0'; END IF; END IF; END PROCESS;
0 Kudos
Altera_Forum
Honored Contributor II
716 Views

Solved it myself by adding more states. If anyone is interested, the solution is in this pastie. 

(pastie.org/5478253)
0 Kudos
Reply