FPGAの使い方のお勉強として、今回は『分周器』をVHDLで実装していきたいと思います。
分周器とは、クロック信号等の周波数を整数分の1に落とす装置のことです。例えば、16MHzのクロック信号を4分の1の4MHzにするといった感じです。
ちなみに、筆者はFPGA初心者で、備忘録として開発環境を整える方法をブログとして残しているので、多少間違っている点などもあるかもしれませんのでご了承ください。
今回設計する分周器
今回設計する分周器は、外部から3bitデータで分周比を変更できるような分周器にします。分周比のテーブルは以下の表のような形です。また、リセット信号も入れています。
M2 | M1 | M0 | 分周比 |
0 | 0 | 0 | 2 |
0 | 0 | 1 | 4 |
0 | 1 | 0 | 8 |
0 | 1 | 1 | 16 |
1 | 0 | 0 | 32 |
1 | 0 | 1 | 64 |
1 | 1 | 0 | 128 |
1 | 1 | 1 | 256 |
VHDL記述
VHDLで記述すると次のようになります。分周比の指定については、テーブルを用意して、Mbitの入力値に応じてリセット時に切り替わるようにしています。分周の部分は、CLK_INの立ち上がりに同期してカウントをし、所定のカウント量に到達したら、CLK_OUTの論理を切り替えるようなプログラムとしています。
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
entity freq_div is
port( RST, CLK_IN : in std_logic;
Mbit : in std_logic_vector(2 downto 0);
CLK_OUT : out std_logic );
end freq_div;
architecture RTL of freq_div is
signal DR, CNT : std_logic_vector(7 downto 0);
signal CLK_DIV : std_logic;
begin
process(RST, CLK_IN, Mbit)
begin
-- initialize --
if (RST = '0') then
-- Frequency devider rate Map ( DR = Rate /2 -1 )
case Mbit is
when "000" => DR <= "00000000"; -- Rate : 2
when "001" => DR <= "00000001"; -- : 4
when "010" => DR <= "00000011"; -- : 8
when "011" => DR <= "00000111"; -- : 16
when "100" => DR <= "00001111"; -- : 32
when "101" => DR <= "00011111"; -- : 64
when "110" => DR <= "00111111"; -- : 128
when "111" => DR <= "01111111"; -- : 256
when others => DR <= "XXXXXXXX";
end case;
CNT <= (others => '0');
CLK_DIV <= '0';
-- Divided CLK generate --
else
if(CLK_IN'event and CLK_IN='1') then
if(CNT = DR) then
CLK_DIV <= not CLK_DIV;
CNT <= (others => '0');
else
CNT <= CNT +1;
end if;
end if;
end if;
CLK_OUT <= CLK_DIV;
end process;
end RTL;
次回、今回作成したVHDLプログラムをシミュレーションし、動作確認をしていきます。
【FPGA学習】分周器を作る②~シミュレーションで動作確認~
前回作成した分周器のVHDLプログラムについて、ModelSimというシミュレーションソフトを使って、動作確認を行っていきたいと思います。前回のVHDL作成の記事はこちらです。 ちなみに、筆者はFPGA初心者で、備忘録として開発環境を整える...
VHDLおすすめ書籍
リンク
コメント