階層構造を意識した設計スタイルとは?:触って学ぼう FPGA開発入門(5)(1/4 ページ)
大規模回路の場合、1つのモジュールで設計を行うことは難しい。ここでは、大規模回路で用いられる階層構造での記述について解説します
連載第4回「単相同期回路で設計する理由」では、いわゆる“単相同期回路”を中心に解説しました。単相同期回路の考え方に基づいた設計をするには慣れが必要だと思いますが、現在のトレンドとなる設計手法ですし、設計ツールが基本的に単相同期回路を前提に作られていますから、ぜひこの設計スタイルをマスターしてください。
さて、これまでの連載で「7セグメントLEDのデコーダ」と「10進のアップ・ダウンカウンタ」を作成しました。今回は、これらを接続してFPGAボード上に実現してみましょう。また、生成された回路の評価を論理合成ツールのログで見てみましょう。
関連リンク: | |
---|---|
⇒ | いまさら聞けない FPGA入門 |
7セグメントLEDデコーダの修正
連載第2回「論理シミュレーションを行う癖を付けよう」で作成した7セグメントLEDのデコーダは、スイッチが3bit入力でした。今回は、図1のような接続構造になるので、デコーダの入力は4bitになります。
これにより、連載第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進アップ・ダウンカウンタの修正が完了しました。
Copyright © ITmedia, Inc. All Rights Reserved.