- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Solved it myself by adding more states. If anyone is interested, the solution is in this pastie.
(pastie.org/5478253)
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page