概要
題名通り、遊びとしてストップウォッチをVHDLで作りました。以下では、実行環境と作成したプログラムを示します。
実行環境
次に実行環境を示します。
Soft and Hard | バージョン |
---|---|
VHDL | 1076-2008 |
Quartus Ⅱ | 9.0 |
EDA-002 | Rev2 |
VHDLのシミュレーション及び評価ボード書きこみ用途して、Quartus Ⅱを用いました。QuartusがPrimeより古いものを使用している理由としましては、評価ボードにPrimeで書き込めなかったからです。また、評価ボードは有限会社ヒューマンデータのEDA-002を使用しました。
VHDLコード
以下に作成したコードを示します。作成したストップウォッチでは、小数点第1位から10の桁まで表示します。
stopwatch.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity HIROSE_STOP_WATCH_2 is
Port(
CLK : in std_logic;
RESET : in std_logic;
STOP_SIG : in std_logic;
RESTART_SIG : in std_logic;
LED : out std_logic_vector( 7 downto 0 );
Position_LED : out std_logic_vector( 3 downto 0 )
);
end HIROSE_STOP_WATCH_2;
architecture Behavioral of HIROSE_STOP_WATCH_2 is
signal DD : std_logic_vector(15 downto 0 );
signal CE : std_logic;
signal inter_LED : std_logic_vector( 7 downto 0);
signal decimal_under_two : std_logic_vector( 3 downto 0);
signal decimal_under_two_flg : std_logic;
signal decimal_under_one : std_logic_vector( 3 downto 0);
signal decimal_under_one_flg : std_logic;
signal WORK : std_logic_vector(3 downto 0);
signal unit_flg : std_logic;
signal ten_digit : std_logic_vector( 3 downto 0 );
signal ten_digit_flg : std_logic;
signal select_SegLED : std_logic_vector( 2 downto 0);
signal Division_Hz : std_logic_vector( 9 downto 0 );
signal STOP_flg : std_logic;
signal START_flg : std_logic;
begin
process(CLK)
begin
if (CLK'event and CLK='1') then
Division_Hz <= Division_Hz + '1';
if(Division_Hz = "1111101000") then
select_SegLED <= select_SegLED + '1';
if(select_SegLED = "001") then
decimal_under_two_flg <= '1';
decimal_under_one_flg <= '0';
unit_flg <= '0';
ten_digit_flg <= '0';
elsif(select_SegLED = "010") then
decimal_under_two_flg <= '0';
decimal_under_one_flg <= '1';
unit_flg <= '0';
ten_digit_flg <= '0';
elsif(select_SegLED = "011") then
decimal_under_two_flg <= '0';
decimal_under_one_flg <= '0';
unit_flg <= '1';
ten_digit_flg <= '0';
elsif(select_SegLED = "100") then
decimal_under_two_flg <= '0';
decimal_under_one_flg <= '0';
unit_flg <= '0';
ten_digit_flg <= '1';
select_SegLED <= "000";
end if;
Division_Hz <= "0000000000";
end if;
end if;
end process;
process(CLK)
begin
if (CLK'event and CLK='1') then
if(RESTART_SIG = '0') then
START_flg <= '1';
STOP_flg <= '0';
end if;
--
if(START_flg = '1') then
DD <= DD + '1';
end if;
--
if(STOP_SIG = '0') then
STOP_flg <= '1';
START_flg <= '0';
end if;
if(DD = "1110101001100000") then
DD <= "0000000000000000";
end if;
end if;
end process;
process(CLK)
begin
if(DD = "1110101001100000") then
CE <= '1';
else
CE <= '0';
end if;
end process;
process(CLK)
begin
if(CE'event and CE='1') then
if(RESET = '0') then
decimal_under_two <= "0000";
decimal_under_one <= "0000";
WORK <= "0000";
ten_digit <= "0000";
end if;
if(STOP_flg = '0' and START_flg = '1') then
decimal_under_two <= decimal_under_two + '1';
if(decimal_under_two = "1001") then
decimal_under_two <= "0000";
decimal_under_one <= decimal_under_one + '1';
if(decimal_under_one = "1001") then
decimal_under_one <= "0000";
WORK <= WORK + '1';
if(WORK = "1001") then
WORK <= "0000";
ten_digit <= ten_digit + '1';
if(ten_digit = "1001") then
ten_digit <= "0000";
end if;
end if;
end if;
end if;
end if;
end if;
end process;
process(CLK)
begin
if( decimal_under_two_flg = '1') then
Position_LED <= "ZZZ0";
case decimal_under_two is
when "0000" => LED <= "11000000";
when "0001" => LED <= "11111001";
when "0010" => LED <= "10100100";
when "0011" => LED <= "10110000";
when "0100" => LED <= "10011001";
when "0101" => LED <= "10010010";
when "0110" => LED <= "10000010";
when "0111" => LED <= "11011000";
when "1000" => LED <= "10000000";
when "1001" => LED <= "10010000";
when others => LED <= null;
end case;
elsif( decimal_under_one_flg = '1') then
Position_LED <= "ZZ0Z";
case decimal_under_one is
when "0000" => LED <= "11000000";
when "0001" => LED <= "11111001";
when "0010" => LED <= "10100100";
when "0011" => LED <= "10110000";
when "0100" => LED <= "10011001";
when "0101" => LED <= "10010010";
when "0110" => LED <= "10000010";
when "0111" => LED <= "11011000";
when "1000" => LED <= "10000000";
when "1001" => LED <= "10010000";
when others => LED <= null;
end case;
elsif( unit_flg = '1') then
Position_LED <= "Z0ZZ";
case WORK is
when "0000" => LED <= "01000000";
when "0001" => LED <= "01111001";
when "0010" => LED <= "00100100";
when "0011" => LED <= "00110000";
when "0100" => LED <= "00011001";
when "0101" => LED <= "00010010";
when "0110" => LED <= "00000010";
when "0111" => LED <= "01011000";
when "1000" => LED <= "00000000";
when "1001" => LED <= "00010000";
when others => LED <= null;
end case;
elsif( ten_digit_flg = '1') then
Position_LED <= "0ZZZ";
case ten_digit is
when "0000" => LED <= "11000000";
when "0001" => LED <= "11111001";
when "0010" => LED <= "10100100";
when "0011" => LED <= "10110000";
when "0100" => LED <= "10011001";
when "0101" => LED <= "10010010";
when "0110" => LED <= "10000010";
when "0111" => LED <= "11011000";
when "1000" => LED <= "10000000";
when "1001" => LED <= "10010000";
when others => LED <= null;
end case;
end if;
end process;
end Behavioral;
ピン配置は、ご自由にしてください。7segとPushボタンを使っています。
まとめ
パワーエレクトロニクスしている某企業のエンジニアの方いわく、if文を乱用するのはセンスが無いそうです。。。
もっと勉強したいと思います。また、間違っているところや、追加したほうがいい、こういう書き方の方がいいよ!という箇所がありましたら、お教え頂けるととても嬉しいです。