Verilog設計演習 Ⅰ   入 門 編...

92
1 設設設設 Verilog 設 設 設 設設設設 設設設設設設設設設 西

description

Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター. 1.作業ディレクトリの作成  まず、エクスプローラを起動し、  ルートディレクトリの下にseminarというディレクトリを、  その下にVerilogというディレクトリを作成して下さい。 ( DOS/V の場合) C:¥seminar¥Verilog (98の場合) A:¥seminar¥Verilog 以下、Verilog演習で作成するファイルはVerilogの下に作ります。 それ以外の、ディレクトリには何も作らないで下さい。. A. B. F. C. D. - PowerPoint PPT Presentation

Transcript of Verilog設計演習 Ⅰ   入 門 編...

Page 1: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

1

Verilog設計演習

Ⅰ  入 門 編

広島県立西部工業技術センター

Page 2: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

2

1.作業ディレクトリの作成

 まず、エクスプローラを起動し、 ルートディレクトリの下にseminarというディレクトリを、 その下にVerilogというディレクトリを作成して下さい。

( DOS/V の場合)C:¥seminar¥Verilog

(98の場合)A:¥seminar¥Verilog

以下、Verilog演習で作成するファイルはVerilogの下に作ります。それ以外の、ディレクトリには何も作らないで下さい。

Page 3: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

3

2.Verilogの基本ブロック例題1 aoiゲート   aoi.v   module aoi(a,b,c,d,f);

input a,b,c,d;output f;assign f=~((a & b)|(c & d));

   endmodule

AB

CD

Page 4: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

4

( 1 ) verilog の基本ブロックはモジュール。( 2 )モジュールはキーワード module ではじまり, endmodule で終わる。 ( 3 )キーワード module の次にモジュール名と(ポートリスト) ; がつづく。( 4 )ポートリストに書いた信号名の入出力宣言を次に行う。

入 力 = input出 力 = output双方向 = inout

( 5 )入出力宣言と endmodule の間にモジュールの本体機能を書く。   endmodule にはセミコロン ; はいらない。 ( 6 )簡単な本体機能は,信号代入文 assign を使って記述する。

assign 左辺 = 右辺( 7 ) Verilog のビット演算子は,C言語と同じ。

& AND 小林テキスト P64 表 3.2| OR~ NOT^ EX-OR

( 8 )わかりやすい様に ( ) を使ってよい。

Page 5: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

5

クイックロジック社QuickWorks

論理合成Synplify

VerilogシミュレータSILOSⅢ

HDLエディタターボライタ

配置配線ツールSpDE兼 統合化環境

回路図入力SYNARIO

Verilog学習

VHDL学習

Page 6: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

6

3.SpDEの起動 スタート - プログラム - QuickLogic ー SpDEでSpDEを起動します。

Page 7: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

7

4.HDLエディタの起動

SpDEのツールバーから、HDLエディタのアイコン   を押して、HDLエディタを起動し、クリエイトアイコン   を押す。

Page 8: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

8

5. Verilog コードの入力、保存

 例題1のVerilogコードを入力し、FileーSaveAsメニューから¥seminar¥verilogの下に、ファイル名aoi.vで保存する。

 拡張子が定まると、module、inputなどのVerilogキーワードが紺色でハイライトされます。紺色は見にくいのでHDLエディタの  WindowーColorsーKeywordで、青色に変更して下さい。

File-ExitでHDLエディタを終了し、SpDEに戻ります。

6.論理合成Synplifyの起動 SpdeのFile-Import-Verilogメニューから¥seminar¥verilog¥aoi.vを指定し、論理合成ツールを起動します。

Page 9: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

9

7.ターゲットデバイスの指定と論理合成 RUNボタンのすぐ上のChangeボタンを押して、Partをp8x12b、Packageをpl44に変更し、OKを押します。次に、RUNボタンを押して、論理合成をかけます。

Page 10: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

10

8.エラーの修正 ソースファイルにエラーがあると、下の画面で停止します。ViewLogボタンでエラー内容を確認した後、Editボタンを押して、HDLエディタを再度起動し、エラー箇所を修正します。

Page 11: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

11

9.論理合成プロジェクトの保存 エラーがなければDoneが表示されて、下の画面で停止します。「はい」を選んで論理合成プロジェクトを保存し、SpDEに戻ります。

Page 12: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

12

10.配置配線の実行 SpDEのツールバーからRunToolsアイコン   を押して、配置配線を実行します。途中、RUNと「いいえ」を選択します。

Page 13: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

13

11.配置配線結果の確認 SpDEツールバーからFullFitアイコン   を選択し、チップ全体を表示させます。

Page 14: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

14

 次に、View-NormalFitメニューを選択し、Zカーソルを回路のある部分でクリックして、回路部分を拡大表示します。 さらに拡大したければZoomInアイコン   を使います。

Page 15: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

15

ab

cd

 回路部分のみを拡大すると、下図のようになります。台形印のセレクタはr=s・p+s・qを表しますので、全体として

a・b=1またはc・d=1の時 f=0それ以外の時         f=1

となり、最初のVerilogコードを満す回路が生成されていることが分かります。

入力s  出力r 0     p 1     q

※論理合成結果を確認したら、File-Saveメニューで結果を保存します。

Page 16: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

16

module aoi(a,b,c,d,f);input a,b,c,d;output f;

// assign f=~((a & b)|(c & d));

wire ab,cd,o;assign ab=a & b;assign cd=c & d;assign o =ab | cd;assign f = ~o;

endmodule

ABCD

AB

CD

12.基本ブロック(続き) HDLエディタを起動し、aoi.vを次のように修正します。

Page 17: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

17

(1)やや複雑な機能を記述する時は, wire で宣言した   ローカル信号を使うこともできる。        ab,cd,o

(2)1ビット幅の wire は宣言なしでも使える。暗黙宣言。   後出の複数ビット幅の wire は宣言が必要。

(3) // は1行のみのコメント行。   /* ・・・・・ */ は複数行にわたるコメント行である。

修正が終わったらソースコードを保存し、論理合成をかけて配置配線を実行して下さい。結果は同じになります。

Page 18: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

18

問題1 インバータLS04.vを設計し、結果を確認しなさい。 問題2 NANDゲートLS00.vを設計し、結果を確認しなさい。

問題3 NORゲートLS02.vを設計し、結果を確認しなさい。 

Page 19: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

19

13.階層設計例題2 マルチプレクサ  mux2.v`include "aoi.v"module inv(a,f);

input a;output f;assign f=~a;

endmodule

module mux2(sel,a,b,f);input sel,a,b;output f;

inv g1 (sel,selb);aoi g2 (sel,a,selb,b,fb);inv g3 (.a(fb),.f(f));

endmodule

g1g2 g3

SELB

FB

SELA

AOI F

Page 20: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

20

(1) もっと複雑な回路記述には階層設計を使う。

(2) 階層設計は,複数のモジュール宣言と モジュールインスタンスで行う。

(3) 複数モジュールの宣言は, inv の様に,同一ファイル内に書いても良いし, aoi の様に,別ファイルに書いて, `include しても良い。

(4) モジュールインスタンスは,サブルーチンコールの様なもので,

モジュール名 インスタンス名 ( ポートリスト );

の形式で行う。上の例では, g1 , g2 , g3 がインスタンス名。

Page 21: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

21

(5) モジュールインスタンスのポートリストは上位モジュールと 下位モジュールを接続するもので, g1 , g2 の様に,並びによる接続が一般的。 g3 の様に,名前による接続も使える。

(6) 出力信号を接続しない時はカンマを余分に書く。

(7) 上の例では selb と fb は,暗黙宣言された wire である。

※ ` はバック・シングル・クォートで DOSV では shift + @98 では shift + ^

  shift + 7 ではないことに注意。

Page 22: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

22

例題2を入力し、論理合成、配置配線を実行します。結果は、論理圧縮の効果で例題1より簡単になり、下図のようになります。

sel=1なら f=asel=0なら f=b

となっています。

sel

Page 23: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

23

14.条件付きassign文例題3 セレクタ mux21.v   module mux21(sel,a,b,f);

input sel,a,b;output f;assign f=sel ? a:b;

   endmodule

selab

mux21

(1) 例題2 (mux2.v) では階層設計を説明するため,複雑な書き方を   したが,セレクタ自体はもっと簡単に記述できる。( 2 ) assign 文にはC言語の3項演算子(条件演算子ともいう)に似た  条件付き assign 文があり,

assign 左辺= (条件式1 ) ? ( 右辺1 ) : ( 右辺2 );

  が使える。(3)上の例では, sel=1 なら f=a , sel=0 なら f=b になる。

Page 24: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

24

15.always文とif文例題3 セレクタ mux21.v   module mux21(sel,a,b,f);

input sel,a,b;output f;reg f;

always@(sel or a or b) beginif(sel==1'b1) f=a;

else f=b;end

   endmodule

selab

mux21

(1)3項演算子よりも,わかりやすい if 文もあるが,   module-endmodule 間に,ダイレクトには記述できない。  上の例のように, always ブロックの中で記述する。

Page 25: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

25

(2) always 文は always@( 信号名 ) begin : :end    ←セミコロンがないのに注意

の形で記述し, ( ) 内の信号名の値が変化したときのみ評価される。つまり, ( ) 内には always ブロックとしての入力信号を記述する。正しくはセンシティビティ・リストという。 複数の入力信号が有る時は,カンマではなくor で区切って記述する。

(3) always ブロックで組合せ回路を生成する場合,入力信号を全てセンシティビティ・リストに記述しなければならない。  (順序回路の場合はそうとは限らない)

Page 26: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

26

(4) always ブロック内では, if 文 ,case 文が使え, if(条件式 ) 式1 ; else 式2 ;

 と書く。多重 if 文も使える。 if(条件式1 ) 式1 ; else if(条件式2 ) 式2 ; else 式3;

(5)条件式に使う関係演算子はC言語と同じで ==  等しい >  大     >=  以上!=  等しくない <  小     <=  以下

が使え,かつ,それらの論理演算 &&  論理積 || 論理和     ! 論理否定

も使える。

(6)1ビット幅の定数は

1 , 0 , 1'b1 , 1'b0と書く。  '  はSHIFT+7です。

Page 27: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

27

(7)最も重要なのは, always ブロック内での ・信号代入には, assign 文は使わないこと。・代入文の左辺にくる信号は,レジスタ宣言 しなければならないこと。

である。上の例では  f  がこれにあたる。

(8)上の例からわかる様に,生成される回路が組合せ回路で あってもレジスタ宣言が必要である。逆に言うと,レジスタ宣言 してもフリップフロップが必ず生成されるわけではない。

(9) if 文で全ての条件が列挙されていれば,つまり,   if の数だけ else があれば,組合せ回路が,  そうでなければ,順序回路が生成される。

例題3を入力し、論理合成、配置配線を実行します。結果は例題2と同じになります。

Page 28: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

28

 Verilog設計演習

Ⅱ シミュレーション編

   広島県立西部工業技術センター

Page 29: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

29

1.テスト・フィクスチャの準備

 例題3の設計mux21.vを、Verilogシミュレータを用いて検証します。 設計検証用テストパターンを発生させるVerilogコードのことをテスト・フィクスチャと呼びます。拡張子は通常 .tf を使います。 HDLエディタでmux21.vを開いた状態で、

HDLー GenerateTestBenchを実行すると、テストフィクスチャの雛形mux21.tfが生成されます。(遅いマシンでは数分かかることも有ります。)(1) `timescale 1ns/1ns(2) module t;(3) reg sel,a,b;(4) wire f;(5) mux21 m (.sel(sel),.a(a),.b(b),.f(f));(6) // Enter fixture code here(7) endmodule // t

Page 30: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

30

(1)timescale文はシミュレーションの時間単位を定めるもので、  /の前がこのモジュール内での時間記述#の時間単位、  /の後ろがシミュレーション時に使用される時間精度  になります。この例ではいずれも1nsになります。

(2)テストフィクスチャのモジュールには、ポートリストが有りません。  モジュール名は何でもかまいませんが、ここでは t です。

(3)元の設計データの入力信号は、このモジュール内では値を代入  するので、レジスタ宣言します。

(4)出力信号は観測するだけなので、ワイヤ宣言します。

(5)元の設計データをモジュールインスタンスとして、呼び出します。  信号の接続には、名前による接続が行われていますが、  並びによる接続でも構いません。

(6)この位置に、実際のテストパターン用コードを追加します。

Page 31: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

31

`timescale 1ns/1nsmodule t;reg sel,a,b;wire f; mux21 m (.sel(sel),.a(a),.b(b),.f(f)); // Enter fixture code here

initial begin    sel=0; a=0; b=0;#100 sel=0; a=0; b=1;#100 sel=0; a=1; b=0;#100 sel=0; a=1; b=1;#100 sel=1; a=0; b=0;#100 sel=1; a=0; b=1;#100 sel=1; a=1; b=0;#100 sel=1; a=1; b=1;

endendmodule // t

 それでは、6行目の位置に右の四角の部分を追加してテスト・フィクスチャを完成させてから、mux21.tfとして保存して下さい。

 この例で分かるように、テストフィクスチャでの信号値の代入には、initial文を使用します。 意味としては、sel,a,bの初期値として全て0を代入した後、100ns毎に異なる値を代入しています。

Page 32: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

32

2.機能シミュレーション(Pre-Layout)(1)SpDEのツールバーから、シミュレータのアイコン   を押して、SILOS3を起動します。 シミュレーションタイプでPre-Layoutを選択します。テストフィクスチャがmux21.tf、トップレベルモジュールがmux21.vになっていることを確認後、OKを押して下さい。

Page 33: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

33

(2)mux21.vは論理合成のチェックを通っているので、エラーがあるとすればmux21.tfの方です。 エラーがあるとoutputウインドウにエラーメッセージが表示され、下の画面で停止するので、キャンセルを押します。 outputウインドウにエラーがなければ、(4)に進みます。

Page 34: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

34

(3)エラーメッセージを確認後、SILOS3のFileーOpenメニューからmux21.tfを選択し、エラー箇所を修正します。 修正が終わったら、SILOS3のFile-Saveで保存し、

mux21.tfウインドウのアイコン化ボタン   でアイコン化します。

 Load/Reloadアイコン   を押して、修正結果をSILOS3に反映させます。

 outputウインドウにエラーが無ければ、GOアイコン   を押して(4)に進みます。

 outputウインドウにエラーが有れば、エラーメッセージを確認後アイコン化していたmux21.tfを通常の大きさに戻し、修正を繰り返します。

Page 35: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

35

(4)テストフィクスチャにエラーが無ければ、下の画面で停止しますので、シミュレーション時間1000nsを入力し、OKを押します。

Page 36: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

36

(5)エラーが無ければ、outputウインドウに32 State changes on observable nets.Simulation stopped at the end of time 1.000us. が表示されるのでデータアナライザのアイコン   を押して、波形表示ウインドウを開きます。 

Page 37: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

37

次に、モジュールエクスプローラのアイコン   を押して、t:tのa,b,f,selを選択後、マウス右クリックからAddSignaltoAnalyzerを選ぶと、波形が表示されます。

Page 38: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

38

 データアナライザ・ウインドウをアクティブにしてから、View-ZoomAllを選ぶと、波形全体が表示されます。sel=0の時f=b、   sel=1の時f=aを確認します。

Page 39: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

39

(1)データアナライザ・ウインドウの時間軸上で、マウス右クリックし、timescaleを選んで、切りの良い値を入れれば、時間軸を見やすい値に変更できます。

(2)波形上でマウスを左クリックすると、青色の第1カーソル、右クリックすると、赤色の第2カーソルを置くことができます。各カーソルの時間および時間差がT1,T2,Tdeltaで表示されます。

(3)信号名を選択後、カーソルスキャン・アイコン           を押すと、カーソルが選択信号の変化点に移動します。 この機能を使って、入力信号a,b,selと出力信号fの時間差を測定してみると、Tdelta=0になります。

 これは、現在表示している結果が、遅延時間情報の入っていない機能シミュレーション(Pre Layout)であるためです。 結果を確認したら、SILO3のFile-Exitを選び、途中、「はい」を選んで終了します。

Page 40: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

40

3.遅延シミュレーション(Post-Layout) 再びSpDEのツールバーから、シミュレータのアイコン   を押して、SILOS3を起動します。 今度はシミュレーションタイプでPost-Layoutを選択します。テストフィクスチャがmux21.tf、 SDFがmux21.sdf、トップレベルモジュールがmux21.vq になっていることを確認後、OKを押して下さい。

Page 41: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

41

1000nsを確認後、OKを押します。

Page 42: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

42

outputウインドウに 92 State changes on observable nets.S imulation stopped at the end of time 1000.000ns. が表示され、モジュールエクスプローラ、データアナライザウインドウも表示されるので、ズームオール   で波形全体を表示させます。

Page 43: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

43

(1)波形上でマウスを左クリックすると、青色の第1カーソル、右クリックすると、赤色の第2カーソルを置くことができます。各カーソルの時間および時間差がT1,T2,Tdeltaで表示されます。

(2)信号名を選択後、カーソルスキャン・アイコン           を押すと、カーソルが選択信号の変化点に移動します。 この機能を使って、入力信号a,b,selと出力信号fの時間差を測定してみると、今度はTdelta=9ns程度が表示されます。

 これは、現在表示している結果が、遅延時間情報(mux21.sdf)を考慮した遅延シミュレーション(Post Layout)であるためです。 また、Verilogコードも元のmux21.vではなく、配置配線ツールの出力したmux21.vqが使用されています。SDFはスタンダード・ディレイ・フォーマットといい、遅延時間情報の標準フォーマットです。 結果を確認したら、SILO3のFile-Exitを選び、終了します。興味があれば、*.sdf、*.vqをエディタで開いて見て下さい。

Page 44: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

44

遅延シミュレーションの結果

Page 45: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

45

問題4 インバータLS04.vのテストパターンを設計し、     機能シミュレーションと遅延シミュレーションを

 実行しなさい。

問題5 NANDゲートLS00.vのテストパターンを設計し、     機能シミュレーションと遅延シミュレーションを

 実行しなさい。

問題6 NORゲートLS02.vのテストパターンを設計し、     機能シミュレーションと遅延シミュレーションを

 実行しなさい。

Page 46: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

46

4.ピン配置の指定 ピン配置は配置配線ツールが遅延時間や配線効率を考慮して最適に近いものに自動配置するので、これを使うのが無難です。 しかし、設計の最終段階に近く、プリント基板の変更ができない場合などは、次の方法でピン配置を直接指定することも可能です。 SpDEのTools-Optionsメニューから、BackAnnotationタブを選択し、FixPlacementのIOcellsをチェックonにします。

Page 47: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

47

 OKを選択後、RunToolsアイコン   を押して、配置配線を実行すると、ピン配置情報mux21.scpが生成されます。 現在、ピン16,17,18,19が割り当てられていることを確認します。(マシンによっては異なることも有ります。)エディタで ql_placement 以下のピン番号を変更し、保存します。#mux21.scp#Synplicity Synthesis pin location command file#Automatically generated by SpDE version SpDE 7.0#Date: 8/10/98 at 10:02#

#---Fixed I/O cells---portprop f ql_placement="IO2";portprop a ql_placement="IO3";portprop sel ql_placement="IO4";portprop b ql_placement="IO5";

Page 48: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

48

 論理合成Synplifyを立ち上げて、Addボタンを押します。ファイルの種類をPropertyFiles(*.sc*)にして、mux21.scpを選択し、「開く」を押します。

Page 49: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

49

 SourceFilesにmux21.scpが追加されたことを確認後、RUNを押して論理合成をかけます。 途中「はい」とOKを選択すると、mux21.scpで指定したピン配置での配置配線が実行されます。

Page 50: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

50

Verilog設計演習

Ⅲ  基 礎 編

広島県立西部工業技術センター

Page 51: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

51

1.ビット幅のある信号の表現

例題1 コンパレータ comp.v

module comp(a,b,eq,ge,le);parameter n= 4 ;input [n-1:0] a,b;output eq,ge,le;reg eq,ge,le;

always@(a or b) beginif(a==b) eq=1; else eq=0;if(a>=b) ge=1; else ge=0;if(a<=b) le=1; else le=0;

endendmodule

geeqle

comp

Page 52: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

52

( 1 )今までは1ビット幅の信号だけ扱ってきたが,  ビット幅のある信号も扱える。 input , output 宣言時に

[MSB:LSB] 信号名 , 信号名 ;

  とすれば良い。  同じビット幅,ビットオーダーの信号は1行で宣言できる。

[15:0] [8:1][1:16] [0:7]

  のいずれも使える。 MSB,LSB の値の大小にかかわらず,  左端が MSB ,右端が LSB である。

( 2 )ビット幅を変更しやすくするために parameter を使うことができる。

Page 53: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

53

例題1の続き

module comp(a,b,eq,ge,le);parameter n=4;input [n-1:0] a,b;output eq,ge,le;

assign eq=(a==b);assign ge=(a>=b);assign le=(a<=b);

endmodule

geeqle

comp

( 3 )上の例の様に,コンパレータ等は if 文よりも assign 文の方がコンパクトに記述できる。

Page 54: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

54

例題1のテストフィクスチャ comp.tf`timescale 1ns/1nsmodule t;parameter n=4;reg [n-1:0] a,b;wire eq,ge,le;integer i,j; comp m (.a(a),.b(b),.eq(eq),.ge(ge),.le(le)); // Enter fixture code here    initial begin

for(i=0;i<16;i=i+1) begina=i;for(j=0;j<16;j=j+1) begin b=j; #100;   end

end    endendmodule // t

(1)initial文の中ではinteger宣言した i 、jを用いたforループが使えます。i++ではないことに注意。

Page 55: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

55

2.case文とビット幅のある定数例題2 デコーダ decoder.vmodule decoder(enb,adr,y);input enb;input [2:0] adr;output [7:0] y;reg [7:0] y;always @(enb or adr) begin if(!enb) case(adr) 3'b000: y=8'b11111110; 3'b001: y=8'b11111101; 3'b010: y=8'b11111011; 3'b011: y=8'b11110111; 3'b100: y=8'b11101111; 3'b101: y=8'b11011111; 3'b110: y=8'b10111111; 3'b111: y=8'b01111111; endcase else y=8'b11111111;endendmodule

decode

adr

enby

Page 56: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

56

(1)デコーダは, if 文を並べて書くこともできるが,case 文を使った方がわかりやすい。

case( 信号名 )ケース1 :式1 ;ケース2 :式2 ; : :

default:式n ;endcase

と記述する。 endcase にはセミコロンはつけない。

(2)ビット幅のある定数は,( 2進数) 3'b001 , 8'b1111_1101 , 8'bZZZZ_ZZZZ(16進数) 3'h1 , 8'hfc , 8'hZZ と書く。

   ' の前はビット幅である。

(3) if 文の条件 (!enb) は,本来 (~enb) と書くべきであるが,    (!enb) も許される。 (4) else y=8'b11111111;  が無いとラッチが生成されるので注意。

Page 57: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

57

例題2のテストフィクスチャ decoder.tf

`timescale 1ns/1nsmodule t;reg enb;reg [2:0] adr;wire [7:0] y;integer i; decoder m (.enb(enb),.adr(adr),.y(y)); // Enter fixture code here

initial beginenb=0;for(i=0;i<8;i=i+1) begin

adr=i; #100;end

enb=1;for(i=0;i<8;i=i+1) begin

adr=i; #100;end

endendmodule // t

Page 58: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

58

3.算術演算子と連接演算子例題3 アダー  adder.vmodule adder(cin,a,b,cout,s);

parameter n= 4 ;input cin;input [n-1:0]a,b;output [n-1:0]s;output cout;

// assign {cout,s}=a+b+cin;reg [n-1:0]s;reg cout;always@(a or b or cin) begin

{cout,s}=a+b+cin;end

endmodule

(1)加算器,減算器,乗算器を生成するのに算術演算子+、-、*が使える。 (2)加算結果には,キャリ出力がつきものであるが,連接演算子 { , } を使って

{cout,s}=a+b+cin;とわかりやすく記述できる。

adderab

cin

cout

44

Page 59: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

59

例題3のテストフィクスチャ adder.tf

`timescale 1ns/1nsmodule t;parameter n=4;reg cin;reg [n-1:0]a,b;wire [n-1:0]s;wire cout;integer i; adder m (.cin(cin),.a(a),.b(b),.cout(cout),.s(s)); // Enter fixture code here

initial begincin=0;for(i=0;i<256;i=i+1) begin

{a,b}=i; #100;endcin=1;for(i=0;i<256;i=i+1) begin

{a,b}=i; #100;end

endendmodule // t

このテストフィクスチャでは連接演算子を使って、二重ループを一重ループで済ませています。

Page 60: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

60

4.フリップフロップの記述例題4 フリップフロップ dff.vmodule dff(d,clk,sclr,aclr,enb,q,qsc,qac,qen);input d,clk,sclr,aclr,enb;output q,qsc,qac,qen;reg q,qsc,qac,qen;// simple ff //always@(posedge clk)

q <= d;// sync clear ff //always@(posedge clk)

if(~sclr) qsc <= 0; else qsc <= d;

// async clear ff //always@(posedge clk or negedge aclr)

if(~aclr) qac <= 0; else qac <= d;

// enb ff //always@(posedge clk)

if(enb) qen <= d;endmodule

dclk

qac

aclr

非同期クリア FF

dclk

qsc

sclr

同期クリア FF

dclk

q通常 FF

dclk

qen

enb

イネーブル機能付 FF

Page 61: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

61

(1)フリップフロップの生成には always@(posedge clk)

  を使う。 clk 信号の立ち上がりエッジで always 文が実行される。  立ち下がり動作のFFには negedge を使います。

(2)同期クリア信号は, always@( 信号名)の  センシティビティ・リストに記述しない。

(3)非同期クリア信号は,センシティビティ・リストに記述する。  aclrが正論理なら、 posedge を使います。

(4)イネーブル信号は同期クリア信号と同じ。

(5)この例で用いている <= はノンブロッキング代入文と呼ばれ,  順序回路では,これを使った方がよい。   = はブロッキング代入文と呼ばれ組合せ回路用。  但し,上の例では全て = にしても同じ回路が生成される。

Page 62: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

62

例題4のテストフィクスチャ dff.tfmodule t;reg d,clk,sclr,aclr,enb;wire q,qsc,qac,qen; dff m (.d(d),.clk(clk),

.sclr(sclr),.aclr(aclr),.enb(enb),

.q(q),.qsc(qsc),.qac(qac),.qen(qen)); // Enter fixture code here

initial beginclk=0;forever begin

#50; clk=~clk;end

end

initial beginaclr=1; sclr=1; enb=1; d=1;#125 d=0;#200 d=1;#300 aclr=0;sclr=0;enb=0;#200 d=0;#300 aclr=1;sclr=1;enb=1;#200 d=1;

endendmodule // t

※クロック生成の無限ループには forever を使うことができる。

Page 63: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

63

5.ブロッキング代入文とノンブロッキング代入文例題5 エッジ検出 edg.vmodule edg(clk,d,reset,rise,fall);input clk,d,reset;output rise,fall;reg q1,q2;

always@(posedge clk) beginif(!reset) begin  q1=0; end   else   begin   q1=d; end

end

always@(posedge clk) beginif(!reset) begin   q2=0;   end   else   begin   q2=q1; end

end

assign rise= q1 & !q2;assign fall=!q1 & q2;

endmodule

riseclk

d q1 q2

fall

Page 64: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

64

(1)スイッチが押された時,1回だけある動作をさせたい時など,入力信号の立ち上がり,立ち下がりを検出する手段として,図のようなエッジ検出回路が使用される。

( 2 )この rise,fall検出回路を1つの always 文で実現しようとすれば, <= ノンブロッキング      = ブロッキング

の違いがわかる。上記の四角の部分は下記に置き換えられるが、<=の代わりに、=を使うと, q1 と q2 が同じになり, rise , fall も消える。

always@(posedge clk) beginif(!reset) begin q1<=0; q2<=0;    end   else   begin q1<=d; q2<=q1;   end

end

(3)ノンブロッキング<=は、各右辺の処理が終了してから代入処理が行われる。記述の順番に動作が影響されないので順序回路向き。

(4)ブロッキング=は、一つの代入処理が終了するまで次の処理が行われない。記述の順番に動作が影響される。組合せ回路向き。

Page 65: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

65

例題5のテストフィクスチャ  edg.tf`timescale 1ns/1nsmodule t;reg clk,d,reset;wire rise,fall; edg m (.clk(clk),.d(d),.reset(reset),

.rise(rise),.fall(fall)); // Enter fixture code here

initial begin   clk=0;forever begin

#50 clk=~clk;end

end

initial beginreset=0; d=0;#75 reset=1;#200 d=1;#300 d=0;#400 d=1;#400 d=0;

endendmodule // t

Page 66: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

66

6.同期クリア付きカウンタ例題6 countsc.vmodule countsc(clk,clr,count);input clk,clr;output [3:0]count;   reg [3:0]count;

always@(posedge clk) beginif(!clr) count <= 0;else count <=count+1;

endendmodule

( 1 )同期クリア付カウンタは,同期クリアFFのクリア信号の書き方と, 算術演算子+の応用であり,上の例の様にかける。 順序回路なので代入には、ノンブロッキングを使った方が良い。

(小テスト)これを10進カウンタにするには、どうすればよいか。

4countclk

clr

countsc

Page 67: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

67

例題6のテストフィクスチャ countsc.tf`timescale 1ns/1nsmodule t;reg clk,clr;wire [3:0]count; countsc m (.clk(clk),.clr(clr),.count(count)); // Enter fixture code here

initial begin clk=0;forever begin

#50; clk=~clk;end

end

initial beginclr=1;#125; clr=0;#200; clr=1;

endendmodule // t

Page 68: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

68

7.非同期クリア付きカウンタ例題7 countac.vmodule countac(clk,clr,count);input clk,clr;output [3:0]count;   reg [3:0]count;

always@(posedge clk   or   negedge   clr) beginif(!clr) count <= 0;else count <=count+1;

endendmodule

( 1 )非同期クリア付カウンタは,非同期クリアFFのクリア信号の  書き方と,算術演算子+の応用であり,上の例の様にかける。  順序回路なので代入には、ノンブロッキングを使った方が良い。

(小テスト)これにキャリー入出力を付けるには、どうすればよいか。

4countclk

clr

countac

Page 69: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

69

例題7のテストフィクスチャ countac.tf

`timescale 1ns/1nsmodule t;reg clk,clr;wire [3:0]count; countac m (.clk(clk),.clr(clr),.count(count)); // Enter fixture code here

initial begin clk=0;forever begin

#50; clk=~clk;end

end

initial beginclr=1;#125; clr=0;#200; clr=1;

endendmodule // t

Page 70: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

70

8.ステートマシンの記述例題8 state.vmodule state(clk,a,res,ss);input clk,a,res;output [1:0]ss;reg [1:0]ss;parameter s00=2'b00;parameter s01=2'b01;parameter s10=2'b10;parameter s11=2'b11;

always@(posedge clk) begin   if(~res) ss=s00;

else case(ss)s00: if(a) ss=s01; else ss=s10;s01: if(a) ss=s11;s10: if(~a) ss=s11;s11: ss=s00;

endcaseendendmodule

a a

 a

 a

S00

S01

S11

S10

Page 71: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

71

( 1 ) verilog のステートマシン記述では,上の例の様に  ステートの値は, parameter を使って,物理的な値を割り当てます。

(2)このステートマシンは, s00 が初期状態で,

 入力 a=1 なら s00 → s01 → s11  (但し, s01 で a=0 なら, s01 のまま) ↑ │ └─────┘ 入力 a=0 なら s00 → s10 → s11  (但し , s10 で a=1 なら, s10 のまま) ↑ │ └─────┘と回るものです。 case 文を使えば,上述のようにすっきり書けます。

(3)ステートマシンには、出力値がステート値のみに依存するムーア型と入力値とステート値に依存するミーリー型

がありますが、ここでは深くは述べません。

Page 72: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

72

例題8のテストフィクスチャ state.tf`timescale 1ns/1nsmodule t;reg clk,a,res;wire [1:0]ss; state m (.clk(clk),.a(a),.res(res),.ss(ss)); // Enter fixture code here

initial beginclk=0;forever begin

#50; clk=~clk;end

end

initial beginres=0;a=0;#100; res=1;

#700; res=0;a=1;#100; res=1;

endendmodule // t

Page 73: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

73

9.トライステート出力例題9 triout.vmodule triout(a,oe,y);input a,oe;output y;

assign y=oe? a: 1'bZ;endmodule

(1)トライステート出力、双方向バスの記述は実用的なLSIを  設計する上でさけて通れない。 (2)1ビットのハイインピーダンスは 1'bZ と書く。   Zだけではローカル信号になるので注意。

8ビットは 8'bZZZZ_ZZZZ  または  8'hZZ(3)トライステート出力は,上の例の様に条件付 assign 文で記述する。  トライステート出力は output 宣言する。

(小問題) if 文を使って、トライステート出力を記述しなさい。

a y

oe

Page 74: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

74

例題9のテストフィクスチャ triout.tf`timescale 1ns/1nsmodule t;reg a,oe;wire y;integer i; triout m (.a(a),.oe(oe),.y(y)); // Enter fixture code here

initial beginoe=0; #450;oe=1; #500;

end

initial begina=0;for(i=0;i<10;i=i+1)

#100 a=~a;end

endmodule // t

Page 75: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

75

10.双方向バスの記述例題10 bidir.vmodule bidir(rd,wr,db);  input rd,wr;  inout   db;  wire idb;  reg odb;  assign idb=db;

  always@(posedge wr)odb<=idb;

  assign db=rd? 1'bZ : odb;endmodule

(1)双方向バスも,上の例の様に条件付 assign 文で記述する。  双方向バスは inout 宣言する。

(2) if 文を使って書こうとしても、双方向バスはうまくいかない。

rd

wr

db idb

odb

D Q

Page 76: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

76

例題10のテストフィクスチャ bidir.tf`timescale 1ns/1nsmodule t;reg rd,wr;wire db;reg rd_data; bidir m (.rd(rd),.wr(wr),.db(db)); // Enter fixture code here

task wr_task;   input wr_dt;     begin

force db=wr_dt; #50; wr=0; #50; wr=1; #50; release db; #50;

     end

endtask

task rd_task;   output rd_dt;     begin

rd=0; #100;rd_dt=db; rd=1; #100;

     endendtask

initial begin   rd=1; wr=1; db=1'bZ;   #100; wr_task(1); rd_task(rd_data);   $display("time=%4d rd_data=%b",

$time,rd_data);

   #100; wr_task(0); rd_task(rd_data);   $display("time=%4d rd_data=%b",

$time,rd_data);endendmodule // t

0 50 100 150 200db wr_dt Zwr

0 50 100 150 200 rdrd_dt  前の値    rd↑時の db の値

Page 77: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

77

(1)タスクはテストフィクスチャで使用されるサブルーチン。

(2)タスクはキーワードtaskで始まり、endtaskで終わる。

(3)キーワードtaskの次に、タスク名を書く。  上の例ではでは wr_task と rd_task がタスク名。

(4)タスク名の次に引数宣言を行う。wr_taskでは、入力引数wr_dt rd_taskでは、出力引数rd_dt

が宣言されている。

(5)上の例ではinitial文のメインルーチンから、 wr_taskとrd_taskを2回づつコールして、 データバスから1と0の書込み、読出しの確認をしている。

Page 78: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

78

(6)双方向バスdbはテストフィクスチャ内では、ワイヤ宣言する。

(7)双方向バスdbの初期値=Zとする。(Zは代入可能)

(8)双方向バスdbにZ以外の値を代入するときは、force文を使う。

(9)強制代入を解除するときは、release文を使う。

(10)$displayはoutputウインドウに値を表示するための  システムタスクであり、書式はC言語のprintf文と同じ。  $timeは現在時刻を表すシステム関数。

Page 79: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

79

Verilog設計演習

Ⅳ  応 用 編

広島県立西部工業技術センター

Page 80: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

80

1.ストップウオッチの設計 次の回路図のハードウエアを用意しています。

14

24

37

+51/100秒

+51/10秒

+5  1秒

+5+5

+5

+5

10秒

1k

1k

1k

1k

100k

100k

0.1μ

0.1μ

START

START

STOP

STOP

100HzCLK GND

VCC

LED4

LED3

LED2

LED1

MACH210

WATCH

1143

1021

13811 10 9

44,22

1,12,23,34

93

20

30

43

g

a

e d c h COM2

f g a bCOM1

a

bf

g

ce

hd

7セグメント LED

TLR306

(アノードコモン)

LEDi[0]

LEDi[2]

LEDi[4]

LEDi[6]

g abcdef

h

LEDi[5]

LEDi[3]

LEDi[1]

(i=1~4)

COM2COM1

(問題1)100Hzの方形波をカウントして、下記の仕様の4桁ストップウオッチをVerilog-HDLで記述しなさい。

startスイッチを押すと、カウント開始stopスイッチを押すと、カウント停止両方同時に押すと、リセット

(問題2) startスイッチだけで、スタート、ストップ、リセットができる仕様に変更しなさい。

Page 81: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

81

①module digit(clk,res,cin,cout,led);   input clk,res,cin;   output cout;   output [6:0]led;   reg [3:0]dgt;   reg [6:0]led;②always@( clk) begin

if( ) dgt<=0;else if(cin && ( )) dgt<=dgt+1;else if(cin && (dgt==9)) dgt<=0;

   end③assign cout=cin & ( );④always@(dgt) begin

case(dgt)0: led=~7'h3f; 1: led=~7'h06;2: led= ; 3: led= ;4: led= ; 5: led= ;6: led= ; 7: led= ;8: led= ; 9: led= ;default: led=~7’h00;

endcase  end  endmodule

①モジュール digit は LED一桁に相当するサブモジュールで、カウンタ部と7セグメントデコーダ部で構成されています。②カウンタ部は clk をクロック、 resを正論理の同期クリア信号とする4ビットカウンタです。10進カウンタなので、9の次は0に戻らなければなりません。③キャリー入力が有り、かつカウント値が9の時、キャリー出力が出なければなりません。④7セグメントデコーダ部は、カウント値を数字表示用データに変換する組合せ回路です。

Page 82: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

82

⑤module watch1(start,stop,clk,led1,led2,led3,led4);   input start,stop,clk;   output [6:0]led1,led2,led3,led4;   reg [1:0]state;   wire dres,enb1,enb2,enb3,enb4;

⑤parameter reset=2'b00;   parameter count=2'b01;   parameter display=2'b10;

⑤always@(posedge clk) beginif(start & stop) state=reset;else if(     &     ) state=count; else if(     &     ) state=display;

   end

   assign enb1=(         );   assign dres=(state==reset);

⑥digit digit1(clk,dres,enb1,enb2,led1);⑦digit digit2(clk,dres,     ,     ,led2);  digit digit3(clk,dres,     ,     ,led3);  digit digit4(clk,dres,     ,    ,led4);

endmodule

⑤モジュール watch1 がメインモジュールでreset,count,display の3つの状態を遷移するステートマシンです。条件は下記の通り。

start のみで count へstop のみで display へ両方で reset へ

⑥digit1 ~ digit4 はそれぞれ   digit1 1/100 秒の桁   digit2 1/10 秒の桁   digit3 1 秒の桁   digit4 10 秒の桁に相当するモジュールインスタンスです。⑦enb1 ~ enb4 は digit1 ~ digit4 のキャリ入力とキャリ出力を接続するローカル信号です。

digit4 enb4 digit3 enb3 digit2 enb2 digit1 enb1

Page 83: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

83

2.並列IOの設計 下記仕様の8ビット × 3ポート入出力LSI(インテル8255の簡易版)を設計しなさい。cs rd wr adr 動    作 H  ×   ×   ××  非 動 作

00 DB←PAピン L L  H  01 DB←PBピン

10 DB←PCピン 11 DB←CRレジスタ 00 DB→PAレジスタ

L H ↑ 01 DB→PBレジスタ 10 DB→PCレジスタ 11 DB→CRレジスタ

CRレジスタはPA、PB、PCの入出力を決める内部レジスタ。CR(0) 0 PA=出力モード      1 PA=入力モードCR(1) 0 PB=出力モード             1 PB=入力モード       CR(2) 0 PC=出力モード             1 PC=入力モード

   PIO

ADR   PA

CS    PBRDWR    PC

DB   CRRES

RESはPA,PB,PCを全て入力モードにする負論理の非同期リセット信号。

Page 84: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

84

並列IO  pio.vmodule pio(cs,rd,wr,adr,res,db,pa,pb,pc);parameter n=8;input cs,rd,wr,res;input [1:0]adr;inout [n-1:0]db,pa,pb,pc;

reg [n-1:0]qa,qb,qc,cr,odb;

/***** internal register (reset , cs & wr) *****/always@(         or         ) begin

if(      )begin qa=0; qb=0; qc=0; cr=8'hFF;

endelse if(     )   case(     )

0:qa=db; 1:qb=db; 2:qc=db; 3:cr=db;

endcaseend

①①qa,qb,qc,cr は wr をクロック、~res を非同期クリア信号とする FF でcs がアクティブの時、 db の値が adr で選択された qa,qb,qc,cr のいずれかに書き込まれる。

Page 85: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

85

/***** port tri-state assign *****/assign pa=(        )?qa:8'hZZ;assign pb=(        )?qb:8'hZZ;assign pc=(        )?qc:8'hZZ;

/***** data selecter *****/always@(     or    or    or    or    ) begin

case(adr) 0:odb=pa; 1:odb=pb; 2:odb=pc; 3:odb=cr;endcase

end

/***** databus tri-state assign (cs & rd) *****/ assign db=(      &      )? odb:8'hZZ;

endmodule

②pa は ~cr[0] を制御信号とする双方向バッファ pb は ~cr[1] を制御信号とする双方向バッファ pc は ~cr[2] を制御信号とする双方向バッファ

③は pa,pb,pc,cr をデータ入力   adr をセレクト信号   odb をデータ出力とする  データセレクタ

④db は ~cs と ~rd の論理積を制御信号とする双方向バッファ

Page 86: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

86

PIOのテストフィクスチャ pio.tf`timescale 1ns/1nsmodule t;reg cs,rd,wr,res;reg [1:0]adr;wire [7:0]db,pa,pb,pc;

integer i;reg [7:0]rd_data;

pio m (.cs(cs),.rd(rd),.wr(wr),.adr(adr),.res(res),.db(db),.pa(pa),.pb(pb),.pc(pc));assign pa=pb; // connect PB to PA

// Enter fixture code heretask wr_task;

input [1:0]adr_dt; input [7:0]wr_dt;begin

cs=0; adr=adr_dt; force db=wr_dt; #50; wr=0; #100; wr=1; #50; cs=1; adr=2'b11; release db; #50;

endendtask

Page 87: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

87

task rd_task;input [1:0]adr_dt; output [7:0]rd_dt;begin

cs=0; adr=adr_dt; #50;rd=0; #100;rd_dt=db; rd=1; #50;cs=1; adr=2'b11; #50;

endendtask

initial begincs=1; rd=1; wr=1; adr=2'b11; db=8'bZZ; res=0; #50;res=1; #50;wr_task(3,1); //write CW to CR (PA=in PB,PC=out)for(i=0;i<=255;i=i+1) begin

wr_task(1,i);    // write to PB rd_task(0,rd_data); // read from PA$display("i=%x rd_data=%x",i,rd_data);

end#1000; $finish;

endendmodule // t

Page 88: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

88

Page 89: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

89

①module digit(clk,res,cin,cout,led);   input clk,res,cin;   output cout;   output [6:0]led;   reg [3:0]dgt;   reg [6:0]led;②always@(posedge clk) begin

if(res) dgt<=0;else if(cin && (dgt!=9)) dgt<=dgt+1;else if(cin && (dgt==9)) dgt<=0;

   end③assign cout=cin & (dgt==9);④always@(dgt) begin

case(dgt)0: led=~7'h3f; 1: led=~7'h06;2: led= ~7’h5b; 3: led=~7’h4f;4: led= ~7’h66; 5: led=~7’h6d;6: led=~7’h7d; 7: led=~7’h27;8: led=~7’h7f; 9: led=~7’h6f;default: led=~7’h00;

endcase  end  endmodule

解答例watch1.v

Page 90: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

90

⑤module watch1(start,stop,clk,led1,led2,led3,led4);   input start,stop,clk;   output [6:0]led1,led2,led3,led4;   reg [1:0]state;   wire dres,enb1,enb2,enb3,enb4;

⑤parameter reset=2'b00;   parameter count=2'b01;   parameter display=2'b10;

⑤always@(posedge clk) beginif(start & stop) state=reset;else if(start & ~stop) state=count; else if(~start & stop) state=display;

   end

   assign enb1=(state==count);   assign dres=(state==reset);

⑥digit digit1(clk,dres,enb1,enb2,led1);⑦digit digit2(clk,dres,enb2,enb3,led2);  digit digit3(clk,dres,enb3,enb4,led3);  digit digit4(clk,dres,enb4,    ,led4);

endmodule

Page 91: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

91

解答例  pio.vmodule pio(cs,rd,wr,adr,res,db,pa,pb,pc);parameter n=8;input cs,rd,wr,res;input [1:0]adr;inout [n-1:0]db,pa,pb,pc;

reg [n-1:0]qa,qb,qc,cr,odb;

/***** internal register (reset , cs & wr) *****/always@(posedge wr or negedge res) begin

if(~res)begin qa=0; qb=0; qc=0; cr=8'hFF;

endelse if(~cs)   case(adr)

0:qa=db; 1:qb=db; 2:qc=db; 3:cr=db;

endcaseend

Page 92: Verilog設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

92

/***** port tri-state assign *****/assign pa=(~cr[0])?qa:8'hZZ;assign pb=(~cr[1])?qb:8'hZZ;assign pc=(~cr[2])?qc:8'hZZ;

/***** data selecter *****/always@(adr or pa or pb or pc or cr) begin

case(adr) 0:odb=pa; 1:odb=pb; 2:odb=pc; 3:odb=cr;endcase

end

/***** databus tri-state assign (cs & rd) *****/ assign db=(~cs & ~rd)? odb:8'hZZ;

endmodule