Anda di halaman 1dari 6

Currently I am studying the "Circuit Design with VHDL" by Volnei A. Pedroni.

On page 207 the run a simulation but do not provide the test bench. I would like to run the same simulation but I am not familiar with how to write a testbench. If possible please provide a testbench to mimic the simulation shown on page 207. If you are unfamiliar with this book or the simulation run, I would also appreciate ANY KIND of testbench which could simulate it's funcionality. Also if there are any errors with the code, please let me know! Your help is much appreciated! thank you! Here is the code we are trying to implement: library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity vending_machine is Port ( clk, rst : IN STD_LOGIC; nickel_in, dime_in, quarter_in : IN BOOLEAN; candy_out, nickel_out, dime_out, quarter_out: OUT STD_LOGIC); end vending_machine; architecture fsm of vending_machine IS TYPE state IS (st0, st5, st10, st15, st20, st25, st30, st35, st40, st45); SIGNAL present_state, next_state: STATE; begin PROCESS(rst, clk) BEGIN IF(rst='1') THEN present_state <=st0; ELSIF(clk' EVENT AND clk ='1') THEN present_state <= next_state; END IF; END PROCESS; PROCESS(present_state, nickel_in, dime_in, quarter_in) BEGIN CASE present_state IS WHEN st0 => candy_out <= '0'; nickel_out <='0'; dime_out <= '0'; IF (nickel_in) THEN next_state <= st5; ELSIF (dime_in) THEN next_state <= st10; ELSIF (quarter_in) THEN next_state <= st25; ELSE next_state <=st0; END IF; WHEN st5 => candy_out <= '0'; nickel_out <='0'; dime_out <= '0'; IF (nickel_in) THEN next_state <= st10; ELSIF (dime_in) THEN next_state <= st15; ELSIF (quarter_in) THEN next_state <= st30; ELSE next_state <=st5; END IF; WHEN st10 => candy_out <= '0'; nickel_out <='0'; dime_out <= '0'; IF (nickel_in) THEN next_state <= st15;

WHEN

WHEN

WHEN

WHEN

WHEN

WHEN

ELSIF (dime_in) THEN next_state <= st20; ELSIF (quarter_in) THEN next_state <= st35; ELSE next_state <=st10; END IF; st15 => candy_out <= '0'; nickel_out <='0'; dime_out <= '0'; IF (nickel_in) THEN next_state <= st20; ELSIF (dime_in) THEN next_state <= st25; ELSIF (quarter_in) THEN next_state <= st40; ELSE next_state <=st15; END IF; st20 => candy_out <= '0'; nickel_out <='0'; dime_out <= '0'; IF (nickel_in) THEN next_state <= st25; ELSIF (dime_in) THEN next_state <= st30; ELSIF (quarter_in) THEN next_state <= st45; ELSE next_state <=st20; END IF; st25 => candy_out <= '1'; nickel_out <='0'; dime_out <= '0'; next_state <= st0; st30 => candy_out <= '1'; nickel_out <='1'; dime_out <= '0'; next_state <= st0; st35 => candy_out <= '1'; nickel_out <='0'; dime_out <= '1'; next_state <= st35; st45 => candy_out <= '0'; nickel_out <='0'; dime_out <= '1'; next_state <= st35;

END CASE; END PROCESS; END fsm;

Main Page EEng School DCU

Vending Machine Assignment


This assignment is proposed to the students in order to self-test their comprehenssion of the subjects discussed in the previous alarm-lock project. The VHDL source code for the core of the vending machine will be provided. The code is very well commented. The students will be asked to attach video display and keyboard facilities to it.

The vending machine has three components: coins module: This module's purpose is to keep track of the different types of coins used in the machine. If the supply of a particular coin runs low, the exact_change light is turned on. If the machine fills up with coins, the coin_reject line is put high. It drives the total line, i.e. the current amount entered by the user. When a coin is entered, the total is incremented by the coin value. When an item is purchased, the total is decremented by the value of the item; when change is required, it decrements the total by the value of the coin outputted. change module: When an item is dispensed, it subtracts the price of the item (from dispenser module) from the user's credit (from coins module) to calculate the change required. It then repeatedly subtracts the largest coin possible from this total and returns it to the user, until all the user's change has been returned. dispenser module: This module's purpose is to keep track of the items being sold by the vending machine, lighting the particular empty button for the item when the stocks of this item are depleted. It also keeps account of the prices of the items, and allows them to be reprogrammed to new values. Whenever request_strobe goes high, this module checks which item is requested, finds it's price, ensures the user's credit is high enough, outputs the item, and sends the price to the coin and change modules so they can update their values and calculate change. Below we are going to give the students some stepwise hints on how the original vending machine code should be enhanced with vdeo and keyboard features. first of all it can be noticed that the number of inputs/outputs required by the original vending machine code is big comparing to the available number of pins provided by the EPF10K20 chip. Therefore, one should find out which vending machine circuit input/output buses are not used simultaneously and hence be multiplexed together. Below we have the entity declaration of the original vending machine code. Then is given the suggested changed entity declaration. We can do this multiplexion because the new_item_price inputs are used only when the new price list is loaded on the machine by the retailer (programming mode), while total gives user's current credit when the machine is in the selling mode. entity declaration of the original vending machine code: entity drinks_machine is port (item_requested: in std_logic_vector(2 downto 0); --user's choice of item item_request_strobe: in std_ulogic; --latch in this request clock: in std_ulogic; --provide timing reset: in std_ulogic; --asynchronous reset of all registers coin_entered: in std_logic_vector(2 downto 0); --type of coin entered coin_strobe: in std_ulogic; --pulse in this coin set_price_strobe: in std_ulogic; --reprogram an item price new_item_price: in integer; --new price coin_reject: out std_ulogic; --to prevent coins from entering item_out: out std_logic_vector(2 downto 0); --item to be dispensed item_out_strobe: out std_ulogic; --pulse to dispense item coke_empty: out std_ulogic; --indicate when stocks of an fanta_empty: out std_ulogic; --item have been diminished lilt_empty: out std_ulogic;

pepsi_empty: out std_ulogic; change: out std_logic_vector(2 downto 0); --coin to be returned change_strobe: out std_ulogic; --pulse out this coin total: out integer; --user's current credit exact_change: out std_ulogic);--indicate when internal change is low end drinks_machine; suggested entity declaration of the input/output multimplexed vending machine code: entity drinks_machine is port (item_requested: in std_logic_vector(2 downto 0); --user's choice of item item_request_strobe: in std_logic; --latch in this request clock: in std_logic; --provide timing reset: in std_logic; --asynchronous reset of all registers coin_entered: in std_logic_vector(2 downto 0); --type of coin entered coin_strobe: in std_logic; --pulse in this coin set_price_strobe: in std_logic; --reprogram an item price new_item_price_total_muxed: in t_value; --new multiplexed price & user's current credit --formerly new_item_price: in t_value; --new price --formerly (see original vending machine project) total: out t_value; --user's current credit coin_reject: out std_logic; --to prevent coins from entering item_out: out std_logic_vector(2 downto 0); --item to be dispensed item_out_strobe: out std_logic; --pulse to dispense item coke_empty: out std_logic; --indicate when stocks of an fanta_empty: out std_logic; --item have been diminished lilt_empty: out std_logic; pepsi_empty: out std_logic; change: out std_logic_vector(2 downto 0); --coin to be returned change_strobe: out std_logic; --pulse out this coin exact_change: out std_logic);--indicate when internal change is low end drinks_machine; attach the video module. Here the student can make use of the video_template.vhd. Students can use the same approach like for the alarm lock but they have to handle here more than one message. Therefore, they have to increase vertically the displaying frame by the number of messages. The longest horizontal message is going to define the horizontal size of the displaying frame. Because some of the messages, e.g. the message which shows the actual price list of the drink items, have to change a bit the memory where the messages are stored has to be a RAM one, comparing to the alarm lock where we used a ROM memory. Since between a message like "COKE CAN PRICE IS: 70p" and another one like "COKE CAN PRICE IS: 85p" only the price digits have to be changed, in the RAM memory. Thus, a MIF file with all the possible messages apart from those with different price lists has to be generated as well. Then only to the wired locations (memory addresses) in the RAM have to be changed the digits when the retailer changes the prices for the drink items.

attach the keyboard module. Here the student can make use of the keyboard_template.vhd. Last Updated: 18/1/2001 Valentin Muresan, Dublin City University, muresanv@eeng.dcu.ie
--using textio.all Entity Soda_Machine is port( --would need maximum of 30 nickles NICKEL_IN : std_logic_vector(4 downto 0); --would need maximum of 15 dimes DIME_IN : std_logic_vector(3 downto 0); --would need maxium of 6 quarters QUARTER_IN: std_logic_vector(2 downto 0); SELECTION: std_logic_vector(15 downto 0); PRICE: out std_logic_vector(15 downto 0); RESET: BOOLEAN; CLK: BIT; --return change and soda NICKEL_OUT, DIME_OUT, DISPENSE: out BOOLEAN ); End Soda_Machine; architecture BEHAVIOR of Soda_Machine is signal Current_Coin_Count, Next_Coin_Count: INTEGER range 0 to 30; -- 30 nickles is $1.50 signal Current_Return_Change, Next_Return_Change : BOOLEAN; begin process(NICKEL_IN, DIME_IN, QUARTER_IN, RESET, CLK, Current_Coin_Count, Current_Return_Change) --maximum amount of coins --possible is 30 niickles variable Temp_Coin_Count: INTEGER range 0 to 30; begin -- Set all Change Returned to 0 NICKEL_OUT <= FALSE; DIME_OUT <= FALSE; DISPENSE <= FALSE; Next_Coin_Count <= 0; NEXT_Return_Change <= FALSE; -- Synchronous reset if (not RESET) then Temp_Coin_Count := Current_Coin_Count; Case SELECTION is when "000" => PRICE := "110010"; End Case; -- Check whether change was put in the Machine if (NICKEL_IN) then Temp_Coin_Count := Temp_Coin_Count + 1; --counting number of nickles inputed elsif(DIME_IN) then Temp_Coin_Count := Temp_Coin_Count + 2; --counting number of dimes inputed elsif(QUARTER_IN) then Temp_Coin_Count := Temp_Coin_Count + 5; --counting number of quarters inputed end if; -- Keeps track if enough change was put in machine

--Macine Requires 25 Nickles if(Temp_Coin_Count >= 25) then Temp_Coin_Count := Temp_Coin_Count - 25; --soda given to customer DISPENSE <= TRUE; end if; --If too many nickles change is returned if(Temp_Coin_Count >= 1 or Current_Return_Change) then if(Temp_Coin_Count >= 2) then --dime returned DIME_OUT <= TRUE; Temp_Coin_Count := Temp_Coin_Count - 2; --stil return more change Next_Return_Change <= TRUE; end if; if(Temp_Coin_Count = 1) then --nickle returned NICKEL_OUT <= TRUE; Temp_Coin_Count := Temp_Coin_Count - 1; end if; end if; Next_Coin_Count <= Temp_Coin_Count; end if; end process; process begin --returns change on positive clock edege wait until CLK' event and CLK = '1'; Current_Return_Change <= NEXT_Return_Change; Current_Coin_Count <= Next_Coin_Count; end process; end BEHAVIOR;

Anda mungkin juga menyukai