アフィリエイト広告
アフィリエイト広告

VerilogHDL 7セグメントデコーダのシミュレーション

引き続き、例題をシミュレーションしてみましょう。今回は、これ。

【問題6】 7セグメントLEDデコーダを作成しよう
今回は、Verilog HDLで記述された10進カウンタの“テスト・ベンチ”を作成し、シミュレーションと波形表示にチャレンジする。

えーと、記述のお作法ってゆーか、VerilogHDL の記述って新旧いろいろあるらしい。これまでの記述も間違いじゃなくて、そんなふうにも書けます、ってところかな。どれが新しいのか、どれが一般的なのか、ちょっとよくわかんないんですけど、気づいたところは変更していこうかなと思ってます。
んなわけで、これまでと違う記述がでてきますが、いちいち説明しませんので、あしからず。

7 セグメント LED デコーダをシミュレーションする

図 1 7セグメントLEDデコーダ

問題は図 1 のようになっています。

逆らうわけじゃないですが、どうせやるなら、いつも使っている TC4511 を倣いたいと思います。なので、DP は考慮しません。出力は TC4511 の真理値表に従います。BI などの制御入力は、なしです。

問題の解説にもありますが、回路の記述には 2 とおりのやりかたがあります。ひとつは always による組み合わせ回路の記述、もうひとつは function による組み合わせ回路の記述、です。

always による組み合わせ回路の記述

まずは、理解しやすかった always による組み合わせ回路の記述。

  1. module DECODER_7SEGMENT (
  2.   input wire [3:0] DATA_INPUT,
  3.   output reg [6:0] DATA_OUTPUT
  4. );
  5. always @*
  6.   begin
  7.     case (DATA_INPUT)
  8.       4'd0: DATA_OUTPUT = 7'b1111110;
  9.       4'd1: DATA_OUTPUT = 7'b0110000;
  10.       4'd2: DATA_OUTPUT = 7'b1101101;
  11.       4'd3: DATA_OUTPUT = 7'b1111001;
  12.       4'd4: DATA_OUTPUT = 7'b0110011;
  13.       4'd5: DATA_OUTPUT = 7'b1011011;
  14.       4'd6: DATA_OUTPUT = 7'b0011111;
  15.       4'd7: DATA_OUTPUT = 7'b1110000;
  16.       4'd8: DATA_OUTPUT = 7'b1111111;
  17.       4'd9: DATA_OUTPUT = 7'b1110011;
  18.       default: DATA_OUTPUT = 7'b0000000;
  19.     endcase
  20.   end
  21. endmodule

3 行目。always を使うばあい、出力信号は reg で変数宣言します。
6 行目。always は、カウンタのシミュレーションでも使いましたが、@ の信号が変化した時に実行されて、無限にループします。@* とは、入力のいずれかが変化したら、という意味。ここでは、入力 DATA_INPUT が変化したら begin~end を実行、always へ戻り、信号の変化を待つ、ということになります。

8~20 行。おなじみの case 文。たとえば DATA_INPUT が 0 だったら、0b1111110 を出力する。これは、セグメント a~f が点灯、g が消灯の意。10 以上のときは全消灯。
なお、ケースが一致したら case 文を抜けます。同じケースがあったら、上の記述が優先される。C 言語とちょっと違いますね。

ちなみに、出力を不定にしたければ、7’bx とします。ビット列が長くてみづらければ、7’b111_1110 とか、書いてもいいらしい。

function による組み合わせ回路の記述

function とは、関数のこと。論理式で簡単に記述できないデーコーダなどの回路は、関数にするってことね。

  1. module DECODER_7SEGMENT (
  2.   input wire [3:0] DATA_INPUT,
  3.   output wire [6:0] DATA_OUTPUT
  4. );
  5. function [6:0] DECDR (
  6.   input [3:0] DECDR_INPUT
  7. );
  8.   begin
  9.     case (DECDR_INPUT)
  10.       4'd0: DECDR = 7'b1111110;
  11.       4'd1: DECDR = 7'b0110000;
  12.       4'd2: DECDR = 7'b1101101;
  13.       4'd3: DECDR = 7'b1111001;
  14.       4'd4: DECDR = 7'b0110011;
  15.       4'd5: DECDR = 7'b1011011;
  16.       4'd6: DECDR = 7'b0011111;
  17.       4'd7: DECDR = 7'b1110000;
  18.       4'd8: DECDR = 7'b1111111;
  19.       4'd9: DECDR = 7'b1110011;
  20.       default: DECDR = 7'b0000000;
  21.     endcase
  22.   end
  23. endfunction
  24. assign DATA_OUTPUT = DECDR(DATA_INPUT);
  25. endmodule

6~8 行目が、function の記述。DECDR_INPUT は引数で、関数名そのものが戻り値になる、みたいな。function の中身は、always と同様の case 文です。
26 行目。assign で function を呼び出す。なので、出力信号は wire でネット宣言する (3 行目)。

テストベンチ

テストベンチファイルです。

  1. module DECODER_7SEGMENT_TEST;
  2. reg [3:0] DATA_INPUT;
  3. wire [6:0] DATA_OUTPUT;
  4. parameter STEP = 10;
  5. DECODER_7SEGMENT DEC0(DATA_INPUT, DATA_OUTPUT);
  6. initial begin
  7.         DATA_INPUT = 4'd0;
  8.   #STEP DATA_INPUT = 4'd1;
  9.   #STEP DATA_INPUT = 4'd2;
  10.   #STEP DATA_INPUT = 4'd3;
  11.   #STEP DATA_INPUT = 4'd4;
  12.   #STEP DATA_INPUT = 4'd5;
  13.   #STEP DATA_INPUT = 4'd6;
  14.   #STEP DATA_INPUT = 4'd7;
  15.   #STEP DATA_INPUT = 4'd8;
  16.   #STEP DATA_INPUT = 4'd9;
  17.   #STEP DATA_INPUT = 4'd10;
  18.   #STEP DATA_INPUT = 4'd11;
  19.   #STEP DATA_INPUT = 4'd12;
  20.   #STEP DATA_INPUT = 4'd13;
  21.   #STEP DATA_INPUT = 4'd14;
  22.   #STEP DATA_INPUT = 4'd15;
  23.   #STEP $finish;
  24. end
  25. initial begin
  26.   $monitor("input = %d, output = %b", DATA_INPUT, DATA_OUTPUT);
  27.   $dumpfile("dec_7seg_test.vcd");
  28.   $dumpvars(0, DECODER_7SEGMENT_TEST);
  29. end
  30. endmodule

6 行目。遅延時間をパラメータ宣言にしてみました。
その他、これまでと同様です (^_^;)

シミュレーション結果

図 2 7セグメントLEDデコーダ シミュレーション波形

図 2 が、シミュレーション波形です。

入力 0~15 に対して、表示に応じたセグメントデータが出力されています。

んー、それ以上でもそれ以下でもない (;´Д`)

タイトルとURLをコピーしました