【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;
今回の状態遷移回路を以下に示す.
テストベンチ
-- 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
【VHDL】デコーダ回路
3to8デコーダ回路
以下に,3to8デコーダ回路のVHDLソースコードを表示する.
-- Barrel Shifter used Decoder library IEEE; use IEEE.std_logic_1164.all; entity Decoder3to8 is port ( CBA : in std_logic_vector(2 downto 0); D : out std_logic_vector(7 downto 0) ); end Decoder3to8; architecture RTL of Decoder3to8 is component BShifterNbit generic (N : integer); port ( A : in std_logic_vector((2**N) - 1 downto 0); S : in std_logic_vector(N - 1 downto 0); Z : out std_logic_vector((2**N) - 1 downto 0) ); end component; constant N : integer := 3; signal tA : std_logic_vector((2**N) - 1 downto 0); begin tA <= "00000001"; SHIFTER : BShifterNbit generic map (N) port map (tA, CBA, D); end RTL;
バレルシフタを使用して,デコーダ回路を作成しています.
バレル・シフト回路&パリティ回路&デコーダ回路のテストベンチ
以下に,3つの回路をテストするテストベンチを示す.
library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_arith.all; use IEEE.std_logic_unsigned.all; entity TestBench_Parity is end TestBench_Parity; architecture TestBench of TestBench_Parity is component Decoder3to8 port ( CBA : in std_logic_vector(2 downto 0); D : out std_logic_vector(7 downto 0) ); end component; component ParityNbit generic (N : integer); port ( A : in std_logic_vector(N - 1 downto 0); P : out std_logic ); end component; constant N : integer := 8; signal CBAin : std_logic_vector(2 downto 0); signal Dout : std_logic_vector(7 downto 0); signal Pout : std_logic; begin DUT0 : Decoder3to8 port map (CBAin, Dout); DUT1 : ParityNbit generic map (N) port map (Dout, Pout); generator : process begin CBAin <= "000"; wait for 10 ns; for I in 1 to 100 loop CBAin <= CBAin + 1; wait for 10 ns; end loop; end process; end TestBench;
テストベンチの真理値表
以下の真理値表に基づき,テストベンチを作成した.
【VHDL】バレル・シフト回路とrange-based loop
バレル・シフト回路
以下に,バレル・シフト回路のVHDLソースコードを表示する.
-- Barrel Shifter library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; use IEEE.numeric_std.all; entity BShifterNbit is generic (N : integer := 3); port ( A : in std_logic_vector((2**N) - 1 downto 0); S : in std_logic_vector(N - 1 downto 0); Z : out std_logic_vector((2**N) - 1 downto 0) ); end BShifterNbit; architecture RTL of BShifterNbit is begin process(A, S) variable sc : integer; begin sc := to_integer(unsigned(S)); --Debugsc := conv_integer(S); for I in A'range loop --Debug--for I in 0 to 7 Loop if (I + sc <= A'left) then Z(I + sc) <= A(I); else Z(I + sc - A'left - 1) <= A(I); end if; end loop; end process; end RTL;
[引用]range-based loop
for i in a'range loop
...;
end loop;
aの配列またはバスの範囲がある限りiを増加させながらループを繰り返す。
processの中で利用する。
参考文献
【VHDL】パリティ回路とセンシティビティリスト
パリティ回路
-- Even Parity Circuit library IEEE; use IEEE.std_logic_1164.all; entity ParityNbit is generic (N : integer := 4); port ( A : in std_logic_vector(N - 1 downto 0); P : out std_logic ); end ParityNbit; architecture RTL of ParityNbit is begin process(A) variable tmp : std_logic; begin -- even parity -> tmp := '0' -- odd parity -> tmp := '1' tmp := '0'; for I in 0 to N - 1 loop tmp := tmp xor A(I); end loop; P <= tmp; end process; end RTL;
今回のパリティ回路ではXORを使って,パリティビットを決定する.
手計算を行えば,理屈はわかると思うが, 偶数パリティの時,
tmp := '0';
奇数パリティの時,
tmp := '1';
とすればよい.
センシティビティリスト
センシティビティリストは,process文の機能で,
process(A) begin --<順次処理文> end process;
という風に使用する.
この機能は,信号名をカンマで区切って並べたリストで,
ここに記述された信号に変化があると以下の式が活性化されて実行される.