Re/Coder

知識蓄積備忘録/State-of-the-Ars

【VHDL】Mealy型状態遷移回路を用いた30円の自動販売機の設計

Mealy型状態遷移回路を用いた30円の自動販売機の設計

以下に,Mealy型状態遷移回路を用いた30円の自動販売機のVHDLソースコードを表示する.

-- Vending Machine of Mealy State

library IEEE;
use IEEE.std_logic_1164.all;

entity MealyState30 is
    port (
        CLK, RESET : in std_logic;
        A, B : in std_logic;
        X, Y : out std_logic;
        Z : out std_logic_vector(2 downto 0)
    );
end MealyState30;

architecture RTL of MealyState30 is
    -- type statement
    type type_state is (S0, S1, S2, S3, S4, S5, S6, S7);

    signal state : type_state;
begin
    process(CLK)
    begin
        if (CLK'event and CLK = '1') then
            if (RESET = '0') then
                state <= S0;
            else
                case state is
                    when S0 =>
                        if (A = '1') then
                            state <= S1;
                        elsif (B = '1') then
                            state <= S5;
                        end if;
                    when S1 =>
                        if (A = '1') then
                            state <= S2;
                        elsif (B = '1') then
                            state <= S6;
                        end if;
                    when S2 =>
                        if (A = '1') then
                            state <= S3;
                        elsif (B = '1') then
                            state <= S7;
                        end if;
                    when S3 | S4 | S5 | S6 | S7 =>
                        state <= S0;
                end case;
            end if;
        end if;
    end process;

    -- Output Signal of Mealy State
    X <= '1' when (state = S2 and A = '1') or
                  (state = S0 and B = '1') or
                  (state = S1 and B = '1') or
                  (state = S2 and B = '1') else
         '0';

    Y <= '1' when (state = S2 and A = '1') or
                  (state = S0 and B = '1') or
                  (state = S1 and B = '1') or
                  (state = S2 and B = '1') else
         '0';

    Z <= "010" when (state = S0 and B = '1') else
         "011" when (state = S1 and B = '1') else
         "100" when (state = S2 and B = '1') else
         "000";

end RTL;

今回の状態遷移回路を以下に示す. f:id:zigzackey:20160615170234p:plain

テストベンチ

以下に,テストベンチのVHDLソースコードを示す.

-- TestBench : Vending Machine of Mealy State

library IEEE, STD;
use IEEE.std_logic_1164.all;
-- file input
use STD.textio.all;
use IEEE.std_logic_textio.all;

entity TestBench_MealyState30 is
end TestBench_MealyState30;

architecture TestBench of TestBench_MealyState30 is
    -- component
    component MealyState30
        port (
            CLK, RESET : in std_logic;
            A, B : in std_logic;
            X, Y : out std_logic;
            Z : out std_logic_vector(2 downto 0)
        );
    end component;

    -- signal
    signal CLKt, RESETt : std_logic;
    signal At, Bt, Xt, Yt : std_logic;
    signal Zt : std_logic_vector(2 downto 0);
    -- constant
    constant CLK_PERIOD : time := 50 ns;
    constant RESET_TIME : time := 5 ns;

begin
    DUT : MealyState30 port map (CLKt, RESETt, At, Bt, Xt, Yt, Zt);
    process
    -- file input / output
    file FILEin : TEXT open READ_MODE is "MealyState30.dat";
    file FILEout : TEXT open WRITE_MODE is "MealyState30.out";
    -- variable
    variable LINEin, LINEout : LINE;
    variable CLOCKen, RESETin : std_logic;
    variable Ain, Bin, Xin, Yin : std_logic;
    variable Zin : std_logic_vector(2 downto 0);
    variable colon : string(1 to 2) := " :";
        begin
            readline(FILEin, LINEin);
            read(LINEin, CLOCKen);
            read(LINEin, RESETin);
            read(LINEin, Ain);
            read(LINEin, Bin);
            CLKt <= '0';
            if (CLOCKen = '1') then
                CLKt <= '1' after RESET_TIME,
                        '0' after RESET_TIME + CLK_PERIOD / 2;
            end if;
            RESETt <= RESETin;
            At <= Ain;
            Bt <= Bin;
            read(LINEin, Xin);
            read(LINEin, Yin);
            read(LINEin, Zin);
            wait for CLK_PERIOD;

            write(LINEout, NOW, right, 4);
            write(LINEout, colon, right, 2);
            write(LINEout, Ain, right, 2);
            write(LINEout, Bin, right, 2);
            write(LINEout, Xin, right, 2);
            write(LINEout, Yin, right, 2);
            write(LINEout, Zin, right, 4);

            if ((Xt /= Xin) or (Yt /= Yin) or (Zt /= Zin)) then
                write(LINEout, Xt, right, 3);
                write(LINEout, Yt, right, 2);
                write(LINEout, Zt, right, 4);
            end if;
            writeline(FILEout, LINEout);

            if (endfile(FILEin)) then
                wait;
            end if;
    end process;
end TestBench;

入力情報である「MealyState30.dat」を以下に示す.

0 0 0 0 0 0 000
1 0 0 0 0 0 000
1 1 0 0 0 0 000
1 1 1 0 0 0 000
1 1 1 0 1 0 000
1 1 1 0 0 1 000
1 1 0 0 0 0 000
1 1 0 1 0 1 010
1 1 0 0 0 0 000
1 1 1 0 0 0 000
1 1 1 0 1 0 000
1 1 0 1 0 1 100
1 1 0 0 0 0 000

出力結果である「MealyState30.out」を以下に示す.

50 ns : 0 0 0 0 000
100 ns : 0 0 0 0 000
150 ns : 0 0 0 0 000
200 ns : 1 0 0 0 000
250 ns : 1 0 1 0 000  1 1 000
300 ns : 1 0 0 1 000  0 0 000
350 ns : 0 0 0 0 000
400 ns : 0 1 0 1 010  0 0 000
450 ns : 0 0 0 0 000
500 ns : 1 0 0 0 000
550 ns : 1 0 1 0 000  1 1 000
600 ns : 0 1 0 1 100  0 0 000
650 ns : 0 0 0 0 000