2004年04月11日

VHDLはじめました その3

引き続き、「FPGAボードで学ぶ論理回路設計」で遊んでいます。

まずは前回の続きで、2入力にしてみました。ボタンを2つとも押すとLEDが光ります。
コンパイルしてみるとステータスの中のTotal logic elementsが1/576になって、こんなのでも1消費することがわかりました(前回の、入出力直結で何もしないのでも、やはり1消費するんです ね)。この調子では576個のゲートを使うと一杯になりそうですが、1万ゲート相当ということは、20ゲートを組み合わて実現するような処理を、 logic element1つで実現できるということでしょうか。
---
library ieee;
use ieee.std_logic_1164.all;

entity test3 is
port (
sw1_in : in std_logic;
sw2_in : in std_logic;
led_out: out std_logic
);
end test3;

architecture rtl of test3 is
begin
led_out <= not ((not sw1_in) and (not sw2_in));
end rtl;
---

今度はチュートリアルを変更して次のようなものを作ってみました。ボタンを押していないときは0が表示され、押すと1が表示されます。これで消費logic element数は4です。
---
library ieee;
use ieee.std_logic_1164.all;

entity test4 is
port (
sw_in : in std_logic;
led_out: out std_logic_vector(7 downto 0)
);
end test4;

architecture rtl of test4 is
signal counter: std_logic_vector(3 downto 0);
begin
counter <= "0001" when sw_in = '0' else "0000";

process (counter)
begin
case counter is
when "0000" => led_out <= "00000011";
when "0001" => led_out <= "10011111";
when "0010" => led_out <= "00100101";
when "0011" => led_out <= "00001101";
when "0100" => led_out <= "10011001";
when "0101" => led_out <= "01001001";
when "0110" => led_out <= "01000001";
when "0111" => led_out <= "00011111";
when "1000" => led_out <= "00000001";
when "1001" => led_out <= "00001001";
when "1010" => led_out <= "00010001";
when "1011" => led_out <= "11000001";
when "1100" => led_out <= "11100101";
when "1101" => led_out <= "10000101";
when "1110" => led_out <= "01100001";
when "1111" => led_out <= "01110001";
when others => led_out <= "11111110";
end case;
end process;
end rtl;
---

sw_inボタンを押したときにLEDの表示をカウントアップするように、次のようにしてみました。チャタリング対策をしていないので、案の定うまくいきませんが。これで消費logic element数は11です。
---
process (reset_in, sw_in)
begin
if reset_in = '0' then
counter <= "0000";
elsif sw_in'event and sw_in = '0' then
counter <= counter + 1;
end if;
end process;
---

チャタリング対策のために、まずはカウンタを理解しましょうということで、次のように1秒ごとに表示が変わるようにしてみました。これで消費logic element数は45と、ずいぶん増えました。
---
process (clk)
begin
if clk'event and clk = '1' then
sec_clk <= sec_clk + 1;
if sec_clk = 33000000 then
sec_clk <= 0;
counter <= counter + 1;
end if;
end if;
end process;
---

で、これを使って、と思いましたが今日は時間切れ。