第6回: 実習(3): FPGAへの論理回路の実装(分周回路)

今回は、カウンタの応用として、周波数を変えたクロック信号をつくる 分周回路をつくって、好きなな速さでカウントが進む回路をつくってみましょう。

8ビットカウンタ

まず練習として、8ビットカウンタをつくってみます。

プロジェクトの作成

前回の実習(2)と同様に、 Xilinx ISE Project Navigatorを使ってVHDL記述の論理回路の 設計と論理合成(コンパイル)を行います。 基本的な操作は、実習(1)実習(2)の 手引き書を参考にしてください。 以下では、異なる点のみを記載しておきます。 全体構成を自分で描いてみてよく理解した上で、実際に動作をさせてみましょう。

またdiv.vhdを変更し、別の速さ(例えば10Hzや0.5Hz)でカウント動作をさせてみましょう。 ただしそのとき、分周用のカウンタのビット数と取り得る値の範囲には気をつける必要があります。 div.vhdでは分周用カウンタcntは11ビットとして宣言しています。 11ビットの2進数で扱える値は211=2048までです。 div.vhdではcntで取り得る値は最大で999ですので、11ビットで扱える範囲に おさまっていますが、もっと分周比を大きくしたい(生成するクロック信号の 周波数を低くしたい)ときには、宣言するcntのビット数をそれにあわせて 増やす必要があります。 ちなみにこの例ではcntのビット数は10ビットでも足りますが、 余裕を見て(?)11ビットで宣言しています。 ハードウエアリソースの制限がぎりぎりの場合は、10ビットとするべきでしょう。

このように分周回路の速度(分周比)を容易に変えられるのも、 HDLでの論理回路設計のメリットと言えます。

7セグメントLEDでの表示(オプション)

時間に余裕のある人は、カウンタの値を7セグメントLEDに表示する機能を 追加してみましょう。 以下のファイルを使って新規にプロジェクトを作成(またはさきほどのcount8divを修正)してみてください。 なお4桁の7セグメントLEDの駆動は、一筋縄ではいかず、ダイナミック駆動と呼ばれるテクニックが必要です。 今回は詳細は理解しなくてもよいですが、興味のある人はこちらなどの情報とseg7.vhdの記述を見比べてみてください。 全体構成のcount8div7seg_top.vhdの、さきほどのcountdiv_top.vhdからの変更点は以下の3つです。
  1. エンティティ記述:以下のように7セグメントLED関係の信号SA, SGを追加
        Port ( PSW : in  STD_LOGIC_VECTOR (3 downto 0);
               LED : out  STD_LOGIC_VECTOR (7 downto 0);
               CLK : in  STD_LOGIC;
               SA : out STD_LOGIC_VECTOR(3 downto 0);
               SG : out STD_LOGIC_VECTOR(7 downto 0));
    
  2. コンポーネント宣言: 7セグメントLED駆動回路seg7の宣言を追加。d0~d3が、それぞれ1の位(右端)~1000の位(左端)に表示するべき値(4ビット2進数)。ちなみに0~9はその数字が、10~15(16進数でA~F)は、アルファベットA~Fが表示される。
        component seg7 is
        Port ( clk : in  STD_LOGIC;
               rst : in  STD_LOGIC;
               d0 : in  STD_LOGIC_VECTOR (3 downto 0);
               d1 : in  STD_LOGIC_VECTOR (3 downto 0);
               d2 : in  STD_LOGIC_VECTOR (3 downto 0);
               d3 : in  STD_LOGIC_VECTOR (3 downto 0);
               sa : out  STD_LOGIC_VECTOR (3 downto 0);
               sg : out  STD_LOGIC_VECTOR (7 downto 0));
        end component;
    
  3. インスタンス呼び出し: 7セグメント駆動回路を呼び出し。1の位にはカウンタの出力qの下位4ビット、10の位にはqの上位4ビット、100の位と1000の位には"0"を節即している。
    	iseg7: seg7 port map(CLK, rst, q(3 downto 0), q(7 downto 4), "0000", "0000", SA, SG);
    
なおカウンタの表示は「16進数表記」ですので、そのつもりで動作を確認してみてください。
戻る