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

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

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

インスタンスの記述方法

 10進アップ・ダウンカウンタと7セグメントLEDデコーダを接続します。リスト3のように1つのファイルに両方を記述する、つまり階層構造を用いない記述でも構いませんが、ここでは大規模回路で用いられる階層構造を意識した記述方法を用います。


1   module UPDOWN_7SEG(RESET, CLK, DEC, LED, SA);
2   input RESET, CLK, DEC;
3   output [7:0] LED;
4   output [3:0] SA;
5
6   parameter SEC1_MAX = 6000000; // 6MHz
7
8   assign SA = 4'bzzz0;
9
10  reg [22:0] tmp_count;
11  reg [3:0] COUNT_TMP;
12  wire ENABLE;
13  reg [7:0] LED;
14
15  always @(posedge CLK or negedge RESET)
16  begin
17      if (RESET == 1'b0)
18          tmp_count <= 23'h000000;
19  //  else
20      else if (ENABLE == 1'b1)
21          tmp_count <= 23'h000000;
22      else
23          tmp_count <= tmp_count + 23'h1;
24  end
25
26  // assign DIVIDE_CLK = tmp_count[22];
27  assign ENABLE = (tmp_count == (SEC1_MAX - 1))? 1'b1 : 1'b0;
28
29  //always @(posedge DIVIDE_CLK or negedge RESET)
30  always @(posedge CLK or negedge RESET)
31  begin
32      if (RESET == 1'b0)
33              COUNT_TMP <= 4'h0;
34      else if (ENABLE == 1'b1)
35  //  else if (DEC == 1'b1)
36              if (DEC == 1'b1)
37                      if (COUNT_TMP == 4'h9)
38                              COUNT_TMP <= 4'h0;
39                      else
40                              COUNT_TMP <= COUNT_TMP + 4'h1;
41              else
42                      if (COUNT_TMP == 4'h0)
43                              COUNT_TMP <= 4'h9;
44                      else
45                              COUNT_TMP <= COUNT_TMP - 4'h1;
46  end
47  
48  always @(COUNT_TMP)
49  begin
50     case(COUNT_TMP)      //ABCDEFG Dp
51          4'b0000:LED <= 8'b0000001_1;
52          4'b0001:LED <= 8'b1001111_1;
53          4'b0010:LED <= 8'b0010010_1;
54          4'b0011:LED <= 8'b0000110_1;
55          4'b0100:LED <= 8'b1001100_1;
56          4'b0101:LED <= 8'b0100100_1;
57          4'b0110:LED <= 8'b0100000_1;
58          4'b0111:LED <= 8'b0001101_1;
59          4'b1000:LED <= 8'b0000000_1;
60          4'b1001:LED <= 8'b0000100_1;
61          default:LED <= 8'b0110000_1;
62     endcase
63  end
64  endmodule
リスト3 階層構造を用いない10進アップ・ダウンカウンタ+7セグメントLEDデコーダの記述(UPDOWN_7SEG-2.v

 階層構造を用いるといっても、それほど難しいことではありません。単に図1の接続となるように10進アップ・ダウンカウンタと7セグメントLEDデコーダのモジュールをそれぞれインスタンス(箱を置く)して接続するだけです。インスタンスした記述をリスト4に示します。

1   module UPDOWN_7SEG(RESET, CLK, DEC, LED, SA);
2   input RESET, CLK, DEC;
3   output [7:0] LED;
4   output [3:0] SA;
5
6   wire [3:0] COUNT;
7
8   parameter SEC1_MAX = 6000000; // 6MHz
9
10  UPDOWN #(.SEC1_MAX(SEC1_MAX)) i0(.RESET(RESET), .CLK(CLK),
 .DEC(DEC), .COUNT(COUNT));
11  DECODER7 i1(.COUNT(COUNT), .LED(LED), .SA(SA));
12
13  endmodule
リスト4 10進アップ・ダウンカウンタ+7セグメントLEDでコーダのインスタンス記述(UPDOWN_7SEG.v

 これまで、インスタンスの記述方法に関してあまり詳しく説明してこなかったので、ここで少し解説します。

 10、11行目に10進アップ・ダウンカウンタと7セグメントLEDデコーダのモジュールをそれぞれインスタンスしています。記述方法は以下のとおりです。

UPDOWN #(.SEC1_MAX(SEC1_MAX)) i0(.RESET(RESET), .CLK(CLK), .DEC(DEC), .COUNT(COUNT));
DECODER7 i0(.COUNT(COUNT), .LED(LED), .SA(SA));
             ↑
同じインスタンス名を使用してはいけない

 また、この例ではドット付きの(例えば.RESET)パラメータ名、ポート名と「()」内の接続したいパラメータ、信号名の名前を一致させていますが、必ずしも同じである必要はありません。

 さらに、このインスタンスの記述部分がRTLの最上位記述となるため、少し冗長に見えますが、parameter文で再度SEC1_MAXを6000000に指定して、下位の10進アップ・ダウンカウンタにそのパラメータの値を渡しています。

 defparam構文で階層的にパラメータを渡すことができる方法もありますが、論理合成ツールによってはこのパラメータを階層的に渡すという記述方法に対応していないものもありますので、ここではリスト4の記述を採用しました。

モジュール名 #(.モジュール内のパラメータ名(渡したいパラメータ), ……) 
        インスタンス名(.モジュールのポート名(接続したい信号名), ……); 

 この記述で特に気を付けなければいけないのが、インスタンス名です。任意の名前を付けられますが、同じモジュール内ではユニークな名前である必要があります。つまり、同じインスタンス名を用いることができないという文法的なルールがあるのです。

 以下のように、モジュール名が違っているからといって、同じ「i0」というインスタンス名を使用してはいけません。

Copyright © ITmedia, Inc. All Rights Reserved.