連載
» 2007年05月18日 00時00分 公開

触って学ぼう FPGA開発入門(5):階層構造を意識した設計スタイルとは? (1/4)

大規模回路の場合、1つのモジュールで設計を行うことは難しい。ここでは、大規模回路で用いられる階層構造での記述について解説します

[鳥海佳孝 設計アナリスト,@IT MONOist]

 連載第4回「単相同期回路で設計する理由」では、いわゆる“単相同期回路”を中心に解説しました。単相同期回路の考え方に基づいた設計をするには慣れが必要だと思いますが、現在のトレンドとなる設計手法ですし、設計ツールが基本的に単相同期回路を前提に作られていますから、ぜひこの設計スタイルをマスターしてください。

 さて、これまでの連載で「7セグメントLEDのデコーダ」と「10進のアップ・ダウンカウンタ」を作成しました。今回は、これらを接続してFPGAボード上に実現してみましょう。また、生成された回路の評価を論理合成ツールのログで見てみましょう。


関連リンク:
いまさら聞けない FPGA入門

7セグメントLEDデコーダの修正

 連載第2回「論理シミュレーションを行う癖を付けよう」で作成した7セグメントLEDのデコーダは、スイッチが3bit入力でした。今回は、図1のような接続構造になるので、デコーダの入力は4bitになります。

10進アップ・ダウンカウンタ+7セグメントLEDデコーダ 図1 10進アップ・ダウンカウンタ+7セグメントLEDデコーダ

 これにより、連載第2回で作成した7セグメントLEDデコーダのRTL記述を変更する必要があります。変更したRTL記述をリスト1に示します。

1   module DECODER7(COUNT,LED,SA);
2   input [3:0] COUNT;
3   output [7:0] LED;
4   output [3:0] SA;
5   reg [7:0] LED;
6
7   assign SA = 4'bzzz0;
8
9   always @(COUNT)
10  begin
11   case(COUNT)          //ABCDEFG Dp
12        4'b0000:LED <= 8'b0000001_1;
13        4'b0001:LED <= 8'b1001111_1;
14        4'b0010:LED <= 8'b0010010_1;
15        4'b0011:LED <= 8'b0000110_1;
16        4'b0100:LED <= 8'b1001100_1;
17        4'b0101:LED <= 8'b0100100_1;
18        4'b0110:LED <= 8'b0100000_1;
19        4'b0111:LED <= 8'b0001101_1;
20        4'b1000:LED <= 8'b0000000_1;
21        4'b1001:LED <= 8'b0000100_1;
22        default:LED <= 8'b0110000_1;
23   endcase
24  end
25  endmodule
リスト1 修正した7セグメントLEDのデコーダ記述(DECODER7.v

 主な変更点は、以下のとおりです。

1〜2行目

 入力が4bitに変更になったので、1bitずつバラバラで入力していたものをベクター記述([3:0])に変更し、入力の名前も「COUNT」にします。

9〜11行目

 デコーダの入力、つまりalways文のセンシティビティ・リストとcase文の「()」の部分を「COUNT」に変更します。また、今回はカウンタからの出力が正論理となるため、反転の演算子「~」は使用しません。

20〜21行目

 0〜9の表示となるため、「8」と「9」の表示部分を追加しました。

 以上で、7セグメントLEDデコーダの修正が完了しました。

10進アップ・ダウンカウンタの修正

 続いて、連載第4回「単相同期回路で設計する理由」で作成した10進アップ・ダウンカウンタです。連載第4回では、FPGAボード上のLEDが負論理なのでカウンタの値を反転させて出力させていました。しかし、今回は前述のように7セグメントLEDのデコーダの入力を正論理で扱っているため、その部分を修正します。

 修正した記述を以下(リスト2)に示します。

1   module UPDOWN(RESET, CLK, DEC, COUNT);
2   input RESET, CLK, DEC;
3   output [3:0] COUNT;
4
5   parameter SEC1_MAX = 6000000; // 6MHz
6
7   reg [22:0] tmp_count;
8   reg [3:0] COUNT_TMP;
9   wire ENABLE;
10
11  always @(posedge CLK or negedge RESET)
12  begin
13          if (RESET == 1'b0)
14                  tmp_count <= 23'h000000;
15  //      else
16          else if (ENABLE == 1'b1)
17                  tmp_count <= 23'h000000;
18          else
19                  tmp_count <= tmp_count + 23'h1;
20  end
21  
22  // assign DIVIDE_CLK = tmp_count[22];
23  assign ENABLE = (tmp_count == (SEC1_MAX - 1))? 1'b1 : 1'b0;
24
25  //always @(posedge DIVIDE_CLK or negedge RESET)
26  always @(posedge CLK or negedge RESET)
27  begin
28          if (RESET == 1'b0)
29             COUNT_TMP <= 4'h0;
30          else if (ENABLE == 1'b1)
31  //      else if (DEC == 1'b1)
32                  if (DEC == 1'b1)
33                          if (COUNT_TMP == 4'h9)
34                                  COUNT_TMP <= 4'h0;
35                          else
36                                  COUNT_TMP <= COUNT_TMP + 4'h1;
37                  else
38                          if (COUNT_TMP == 4'h0)
39                                  COUNT_TMP <= 4'h9;
40                          else
41                                  COUNT_TMP <= COUNT_TMP - 4'h1;
42  end
43
44  assign COUNT = COUNT_TMP;
45
46  endmodule
リスト2 修正した10進アップ・ダウンカウンタ記述(UPDOWN10-2.v

44行目

 カウンタの出力の反転を止め、COUNTにCOUNT_TMPそのまま代入する。

 以上で、10進アップ・ダウンカウンタの修正が完了しました。

       1|2|3|4 次のページへ

Copyright © ITmedia, Inc. All Rights Reserved.