FSMのためのテストベンチ / 自販機

pp.547-548

ここでは下の自販機をDUVとして試す。

  • 投入できる貨幣は5セント硬貨(ニッケル)と10セント硬貨(ダイム)のみ。
  • 投入された合計金額をamountポートに出力する。
  • 投入額が15セント以上になったらdispenseポートからパルスを出す(投入金額が15セントを上回ってもおつりは出ない)。
  • (同時に2枚投入された場合は低いほうの硬貨を無視する。)
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

use work.vending_machine_fsm_pkg.all;
/*
package vending_machine_fsm_pkg is
    type state_type is (zero_cent, five_cents, ten_cents, fifteen_cents);
end;*/

entity vending_machine_fsm is
    port (
        clock: in std_ulogic;
        reset: in std_ulogic;
        nickel_in: in std_ulogic;
        dime_in: in std_ulogic;
        dispense: out std_ulogic;
        amount: out std_ulogic_vector(3 downto 0)
    );
end;

architecture rtl of vending_machine_fsm is
begin
    process (clock, reset)
        variable state: state_type;
    begin
        if reset then
            state := zero_cent;
            dispense <= '0';
        elsif rising_edge(clock) then
            case state is
                when zero_cent =>
                    if dime_in then
                        state := ten_cents;
                    elsif nickel_in then
                        state := five_cents;
                    end if;
                when five_cents =>
                    if dime_in then
                        state := fifteen_cents;
                    elsif nickel_in then
                        state := ten_cents;
                    end if;
                when ten_cents =>
                    if dime_in then
                        state := fifteen_cents;
                    elsif nickel_in then
                        state := fifteen_cents;
                    end if;
                when fifteen_cents =>
                    state := zero_cent;
            end case;
            
           -- dispense <= '1' when state = fifteen_cents else '0';
           -- whenステートメントはVHDL-2008からシーケンシャル文にも使えるようになったがQuartus Liteはまだのよう。
            if state = fifteen_cents then
                dispense <= '1';
            else
                dispense <= '0';
            end if;
            
            amount <= std_ulogic_vector(to_unsigned((5 * state_type'pos(state)), 4));
        end if;
    end process;
end;