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

128
1 設設設設 VHDL 設 設 設 設設設設 設設設設設設設設設 西

Upload: moral

Post on 06-Jan-2016

61 views

Category:

Documents


0 download

DESCRIPTION

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

TRANSCRIPT

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

1

VHDL設計演習

Ⅰ  入 門 編

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

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

2

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

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

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

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

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

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

3

2.VHDLの基本ブロック例題1 aoiゲート   aoi.vhdlibrary ieee;use ieee.std_logic_1164.all;

entity aoi is port(a,b,c,d:in std_logic; f :out std_logic);end aoi;

architecture aoi_body of aoi isbegin

f<=not((a and b)or(c and d));end aoi_body;

ABCD

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

4

(1) VHDL の基本ブロックはエンティティとアーキテクチャ。 (2)エンティティは

ブロックの名前(これをエンティティ名と呼ぶ。)入出力ピン名とその方向,ビット幅など

  ブロックを外部から見た場合の仕様を記述する部分。(3)アーキテクチャはブロックの内部表現,  論理回路としての構造を記述する部分。(4)上の例ではaoiがエンティティ名、aoi _ bodyがアーキテクチャ名。(5) library は使用するライブラリ名を,   use はライブラリ中の使用するパッケージ名を宣言する。   両方とも決まり文句と思ってよい。 (6)入出力ピン宣言はエンティティの port 部分で行い,

入 力 = in std_logic    出 力 = out std_logic

双方向 = inout std_logic(7)簡単な機能は,信号代入文 <= で記述する。 (8) VHDL のビット演算子は論理演算子と共用で

and or not xor   が使える。(9)わかりやすい様に ( ) を使ってよい。参照:長谷川テキストp17~23

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

5

クイックロジック社QuickWorks

論理合成Synplify

VerilogシミュレータSILOSⅢ

HDLエディタターボライタ

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

回路図入力SYNARIO

Verilog学習

VHDL学習

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

6

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

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

7

4.HDLエディタの起動

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

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

8

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

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

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

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

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

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

9

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

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

10

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

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

11

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

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

12

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

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

13

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

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

14

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

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

15

ab

cd

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

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

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

入力s  出力r 0     p 1     q

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

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

16

12.ここで、この後のシミュレーションのために、シミュレータ・タイプを変更しておきます。 SpDEツールバーからToolOptionsボタン   を押して、BackAnnotationタブのSimulatorを

Vital3.0 Compliantに変更してから、SaveSettingしてから、OKを押します、

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

17

library ieee;use ieee.std_logic_1164.all;

entity aoi is port(a,b,c,d:in std_logic; f :out std_logic);end aoi;

architecture aoi_body of aoi issignal ab,cd,o:std_logic;

begin-- f<=not((a and b)or(c and d));

ab<=a and b;cd<=c and d;o <=ab or cd;f <= not o;

end aoi_body;

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

ABCD

AB

CD

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

18

(1)やや複雑な機能は、 signal 宣言したローカル信号を使う  ことができる。上の例では ab,cd,o がローカル信号。  ローカル信号はアーキテクチャ内部でのみ有効。

(2) VHDL には暗黙宣言はない。

(3) -- は1行のみのコメント行。  VHDLには、Verilogの/*    */の様に  複数行を一度にコメントアウトする方法はない。

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

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

19

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

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

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

20

14.階層設計例題2 マルチプレクサ mux2.vhdlibrary ieee;use ieee.std_logic_1164.all;-- inverter ---entity inv is

port(a:in std_logic; f:out std_logic);

end inv;architecture inv_body of inv isbegin

f<=not a;end inv_body;---------------------------------------library ieee;use ieee.std_logic_1164.all;-- multiplexer --entity mux2 is

port(sel,a,b:in std_logic; f :out std_logic);

end mux2;

architecture mux2_body of mux2 is component inv

port(a:in std_logic; f:out std_logic);

end component; component aoi port(a,b,c,d:in std_logic; f :out std_logic); end component; signal selb,o:std_logic;begin g1:inv port map(sel,selb); g2:aoi port map(sel,a,selb,b,o); g3:inv port map(o,f);end mux2_body;

g1g2 g3

SELBO

SELA

AOI F

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

21

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

(2)階層設計は複数のエンティティ,アーキテクチャ宣言と コンポーネント宣言およびコンポーネントインスタンスを使う。

(3)複数のエンティティ,アーキテクチャ宣言は   inv の様に同一ファイル内に書いても良いし,   aoi の様に別ファイルに書いても良い。  ただし、 library と use はエンティティ毎に必要。

(4)コンポーネントインスタンスは,サブルーチンコールの様なもので,   g1 , g2 , g3 の様に

インスタンス名 : コンポーネント名 port map(ポートリスト );  の形式で行う。 verilog とは順序が逆なのに注意。

参照:長谷川テキストp24~26

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

22

(5)コンポーネントインスタンスのポートリストは、  呼び出す側と呼び出される側のポートを接続するもので,  上の例の様に並びによる接続が一般的。

  次の例の様に名前による接続も使える。 g3:inv port map(a=>o,f=>f);

  出力信号を接続しない場合は、予約語 open を使う。

(6)コンポーネント・インスタンスをするためには,  アーキテクチャ内で予めコンポーネント宣言して  おかなければならない。

component コンポーネント名port(ポートリスト );

end component;  の形式で行う。エンティティ宣言から is を取ったのと同じ形式。  C言語のプロトタイプ宣言に似た概念。    コンポーネント宣言時の信号名は、エンティティ宣言時と  同じであること。

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

23

(7)メインブロックmux2のサブブロックaoiは、別ファイルに入って  いるので、下図のようにSynplifyで2つのファイルを指定して  論理合成します。ファイルを追加するにはAddボタンを使います。  この時、メインのmux2が一番下に来るように指定します。

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

24

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

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

となっています。

sel

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

25

15.条件付き信号代入文例題3 セレクタ mux21.vhd

library ieee;use ieee.std_logic_1164.all;-- multiplexer --entity mux21 is

port(sel,a,b:in std_logic; f :out std_logic);

end mux21;

architecture v1 of mux21 isbegin

f <= a when (sel='1') else b;end v1;

selab

mux21

※後のシミュレーションの為にファイル名、エンティティ名とも必ず、mux21にして下さい。 ファイル名とエンティティ名が一致しないと、遅延シミュレーション時にエラーが出ます。

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

26

(1)前の例 (mux2) では,階層設計を説明するため,複雑な  書き方をしたが,セレクタ自体はもっと簡単に記述できる。

(2)信号代入文 <= には,C言語の条件演算子に似た  条件付信号代入文があり,

左辺 <=(右辺1 ) when (条件式 ) else (右辺2 );  が使える。

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

(4)条件式に使う関係演算子は =  等しい >  大     >=  以上/=  等しくない <  小     <=  以下

  が使え,それらの論理演算 AND  論理積 OR 論理和    NOT 論理否定

  も使える。

(5)1ビット幅の定数は '1' '0'  と書く。

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

27

16.process文とif文例題3 セレクタ mux21.vhd

library ieee;use ieee.std_logic_1164.all;-- multiplexer --entity mux21 is

port(sel,a,b:in std_logic; f :out std_logic);

end mux21;

architecture v2 of mux21 isbegin

process(sel,a,b) beginif(sel='1') then f<=a;

else f<=b;end if;

end process;end v2;

selab

mux21

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

28

(1)条件演算子よりもわかりやすい if 文もあるが,  アーキテクチャ内にダイレクトに書くことはできない。  上の例の様に process ブロックの中で記述する。  ( verilog の always ブロックに相当)

(2) process 文は process( 信号名 ) begin :end process;

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

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

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

29

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

  と書く。( then と end if がある点が, verilog と違う)。   多重 if は,

if(条件式1) then 式1 ;elsif(条件式2) then 式2 ; else 式3 ;

end if;  と書く。 elseif でない点に、特に注意。

(5) if 文で全ての条件が列挙されていれば組合せ回路,  そうでなければ順序回路が生成されるのは verilog と同じ。

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

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

30

 VHDL設計演習

Ⅱ シミュレーション編

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

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

31

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

HDLー GenerateTestBenchを実行すると、テストベンチの雛形mux21.tbが生成されます。※遅いマシンでは数分かかることもあります。  library ieee;  use ieee.std_logic_1164.all;①ENTITY TestBench IS  END TestBench;②ARCHITECTURE HTWTestBench OF TestBench IS

③COMPONENT mux21 PORT (sel,a,b:in std_logic; f :out std_logic);

   END COMPONENT;④SIGNAL selSignal,aSignal,bSignal: std_logic;④SIGNAL fSignal : std_logic;

  BEGIN ⑤U1 : mux21 PORT MAP (sel => selSignal, a => aSignal, b => bSignal, f => fSignal); ⑥②END HTWTestBench;

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

32

①テストベンチのエンティティには、ポートリストが有りません。 エンティティ名は何でもかまいませんが、ここでは TestBench です。

②アーキテクチャ名は何でもかまいませんが、  ここでは HTWTestBench です。

③シミュレーション対象である mux21 をコンポーネント宣言します。

④入力信号、出力信号ともに、シグナル宣言します。信号名は  元の信号名に Signal をつけたものが自動生成されています。

⑤シミュレーション対象mux21をコンポーネント・インスタンスとして、 呼び出します。信号の接続には、名前による接続が行われていま すが、並びによる接続でも構いません。

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

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

33

 それでは、⑥の位置に下記を追加して、テストベンチを完成させてから、mux21.tbとして保存して下さい。

process beginselSignal <='0'; aSignal <='0'; bSignal <='0'; wait for 100ns;selSignal <='0'; aSignal <='0'; bSignal <='1'; wait for 100ns;selSignal <='0'; aSignal <='1'; bSignal <='0'; wait for 100ns;selSignal <='0'; aSignal <='1'; bSignal <='1'; wait for 100ns;

selSignal <='1'; aSignal <='0'; bSignal <='0'; wait for 100ns;selSignal <='1'; aSignal <='0'; bSignal <='1'; wait for 100ns;selSignal <='1'; aSignal <='1'; bSignal <='0'; wait for 100ns;selSignal <='1'; aSignal <='1'; bSignal <='1'; wait for 100ns;wait;

end process;

 この例で分かるように、テストベンチでの信号値の代入にはprocess文とwait文を使用します。 意味としては、sel,a,bの初期値として全て0を代入した後、100ns毎に異なる値を代入しています。最後のwaitが無いと、800ns毎に同じ信号入力が繰り返されてしまいます。

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

34

2.機能シミュレーション(Pre-Layout)(1)QuickWorksにはVHDLシミュレータは付属していないので、Accolade社のPeakVHDLを使います。 スタート  ー プログラム ー Accolade PeakVHDL

ー PeakVHDL Version4 でPeakVHDLを立ち上げます。

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

35

(2)PeakVHDLは拡張子が*.vh*のファイルしか入力できない  ので、エクスプローラでテストベンチmux21.tbのファイル名を mux21.tb.vhdに変更して下さい。      (重要!!)(3)PeakVHDLのNewProjectアイコン   を押して、新しいプロ  ジェクトをオープンし、File-SaveProjectAsでこのプロジェクト  に名前を付けます。ここでは¥seminar¥VHDL¥mux21.acc  として保存します。

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

36

(4)AddModuleアイコン   を押して、mux21.vhdとmux21.tb.vhdを選択します。

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

37

(5)Rebuildアイコン   を押して、階層構造の再構築をし、モジュールの前に+マークが付くことを確認します。

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

38

(6)オプションボタン   を押して、Optionsウインドウを表示させます。 ①Compileタブの  compile only if out of date  をチェック無 ②Linkタブ   の  link only if out of date  をチェック無 ③Simulateタブの  Run to time  を1000

Time unit  を ns ④Systemタブの  Save options as default  をチェック有に設定してから、OKを押して下さい。

③以外は1回だけ行えば、結構です。③はこれから行うシミュレーション時間を1000nsに設定するものですので、別の設計をシミュレーションするなど、シミュレーションすべき時間が変わった場合は、適宜、変更します。

※シミュレーション時間は波形表示ウインドウ(10)で マウス右ボタンのoptionsからも変更できます。

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

39

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

40

(7)mux21.tb.vhdをクリックして、ハイライトした状態で

シミュレーションボタン    を押します。エラーがあるとトランスクリプト・ウインドウにエラーメッセージが表示されます。エラーがなければ、(9)に進みます。

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

41

(8)mux21.vhdは論理合成のチェックを通っているので、エラーがあるとすれば、mux21.tb.vhdの方です。

 エラーメッセージを確認後、mux21.tb.vhdをダブルクリックすると、エディタが立ち上がるので、エラー箇所を修正します。

 修正が終わったら、File-SaveModuleで保存し、mux21.tb.vhdウインドウのアイコン化ボタン   でアイコン化します。

 シミュレーションボタン    を押して、エラーがなければ、(9)に進みます。

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

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

42

(9)エラーがなければ、下の画面で停止するので、AddPrimariesボタンとCloseボタンを、この順番に押します。

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

43

(10)下の画面で停止するので、GOボタン   を押します。  波形の一部が表示されるので、PeakSimウインドウの  ツールバーからView-ZoomAllを選び、波形全体を  表示させます。

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

44

(11)sel=0の時 f=b、 sel=1の時 f=a を確認します。

ZoomINボタン   を押して拡大しても、入力信号 a,b、selと出力信号fには時間差がありません。これは、現在表示している結果が遅延時間情報の入っていない機能シミュレーション(Pre Layout)である為です。 結果を確認したら、PeakSimウインドウを閉じた後、SaveProjectアイコン   を押して、プロジェクトを保存します。

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

45

3.遅延シミュレーション(Post-Layout)

 PeakVHDLで遅延シミュレーションを行うには、デバイスメーカ各社が供給するVITALライブラリを、以下の(1)~(4)の手順でPeakVHDL用にコンパイルする必要があります。 VITALは Vhdl Initiative Toward Asic Libaray の頭文字で、VHDLで遅延シミュレーションをするための手法の総称です。(1)~(4)は1度だけ実行すれば、以後は必要ありません。

(1)まず、エクスプローラを起動して、  ¥ACC-EDA¥LIB4の下に QLOGIC というディレクトリを作成します。 次に、クイックロジック社の供給するVITALライブラリ  ¥PASIC¥SPDE¥DATA¥QLVTL95.VHDを、今作成したディレクトリ  ¥ACC-EDA¥LIB4¥QLOGICにコピーします。 

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

46

(2)PeakVHDLのツールバーから、NewProject   を押して、新しいプロジェクトをオープンし、File-SaveAsで ¥ACC-EDA¥LIB4¥QLOGIC¥QLOGIC.accとして名前を付けて、保存します。

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

47

(3)AddModuleアイコン   でQLVTL95.VHDを追加し、

Rebuildアイコン   でモジュールの前に+マークが付くことを、確認します。

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

48

(3)QLVTL95.VHDをクリックしてハイライトした状態で、Optionアイコン   を押して、CompileタブのCompile into Libraryに QLPRIMS  を設定します。

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

49

(4)QLVTL95.VHDをクリックしてハイライトした状態で、コンパイル   を押します。 エラーが無いことを確認後、SaveProjectアイコン   を押して、このプロジェクトを保存します。これでライブラリQLPRIMSができました。

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

50

(5)ここからmux21.vhdの遅延シミュレーションを始めます。NewProjectアイコン   を押して、新しいプロジェクトをオープンし、File-SaveAsで   ¥seminar¥vhdl¥mux21vtl.accと名前を付けて、保存します。

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

51

(6)AddModuleアイコン   を押して、mux21.tb.vhd とmux21.vhq (vhdでないことに注意)を追加し、Rebuildアイコン   でモジュールの前に+マークが付くことを確認します。mux21.vhqが見つからない場合は、入門編の12を確認します。

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

52

(7)Optionsボタン   を押して、SystemタブのSystem Library Pathを

c:\acc-eda\lib4;c:\acc-eda\lib4\qlogic;に設定します。(2番目のc:の前にスペースを入れないこと。)

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

53

(8)LinkタブのSDF File Name  を  mux21.sdfSDF Instance Path を  U1SDF Timing   を  Max

に設定します。

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

54

(9)あとは機能シミュレーションの時と同様に、mux21.tb.vhdをクリックしてハイライトした状態で、シミュレーションボタン   を押して、シミュレーションを開始します。 結果は下の様に、入力信号a,bと出力信号fとの間に時間差9ns程度が観測されます。 これは現在表示している結果が、遅延時間情報(mux21.sdf)を考慮した遅延シミュレーション(Post Layout)であるためです。 また、VHDLコードも配置配線ツールの出力したmux21.vhqを使用しています。SDFはスタンダード・ディレイ・フォーマットと呼び、遅延時間情報の標準フォーマットです。 興味があれば*.sdf、*.vhqをエディタで開いて見て下さい。

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

55

(10)結果を確認したら、PeakSimウインドウを閉じた後、SaveProjectアイコン   を押して、プロジェクトを保存します。

機能シミュレーションのプロジェクトはmux21.acc遅延シミュレーションのプロジェクトはmux21vtl.accとして保存されています。 遅延シミュレーションを実行した後、機能シミュレーションを実行しようとすると、リンクエラーが出ることがありますが、この時はCleanProjectアイコン   を押せば、リンクエラーを回避できます。 これ以外にも、意味不明のエラーが出る場合はCleanProjectアイコン   を試して見て下さい。

※*.vhq内のエンティティ名には、自動的に主ファイル名が採用 されるので、*.vでエンティティ名と主ファイル名が一致していな いと、コンポーネントが見つからない旨のエラーが出る。※シミュレータタイプがVITAL3.0ではなく、VITALになっていると VITALライブラリが無い旨のエラーが出る。※System Library Pathの途中に、スペースが入っていると、 QLPRIMSライブラリが無い旨のエラーが出る。

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

56

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

 実行しなさい。

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

 実行しなさい。

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

 実行しなさい。

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

57

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

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

58

 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 59: VHDL設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

59

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

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

60

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

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

61

VHDL設計演習

Ⅲ  基 礎 編

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

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

62

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

例題1 コンパレータ comp.vhdlibrary ieee;use ieee.std_logic_1164.all;

entity comp isgeneric(n:integer :=4);port(a,b:in std_logic_vector(n-1 downto 0); eq,ge,le:out std_logic);

end comp;

architecture v1 of comp isbegin

eq <= '1' when (a= b) else '0';ge <= '1' when (a>=b) else '0';le <= '1' when (a<=b) else '0';

end v1;

geeqle

comp

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

63

------------------------------------architecture v2 of comp isbegin

process(a,b) beginif(a= b) then eq<='1'; else eq<='0'; end if;if(a>=b) then ge<='1'; else ge<='0'; end if;if(a<=b) then le<='1'; else le<='0'; end if;

end process;end v2;

(1)1つのエンティティは複数のアーキテクチャを持つことができる。  上の例ではcompがエンティティで、v1とv2がアーキテクチャ。  明示的にアーキテクチャを指定する場合はコンフィグレーション  文を使うが,シンプリファイライトはコンフィグレーションをサポ  ートしていない。  上の例では v2 の方がコンパイルされる。

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

64

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

std_logic_vector(15 downto 0)  あるいは,

std_logic_vector(0 to 15)  を使う。 MSB は左, LSB は右。   MSB>LSB なら downto を, MSB<LSB なら to を使う。

(3)ビット幅を変更しやすくするためには generic(n:integer :=4);

  を使う。

(4)上の例の様にコンパレータ等は、 if 文よりも条件付信号  代入文の方がコンパクトに記述できる。

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

65

例題1のテストベンチ comp.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all; …①

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench IS

COMPONENT comp GENERIC (n:integer :=4); PORT (a,b:in std_logic_vector(n-1 downto 0);

eq,ge,le:out std_logic);END COMPONENT;

constant n:integer:=4; …②     SIGNAL aSignal,bSignal: std_logic_vector(n-1 downto 0);

SIGNAL eqSignal,geSignal,leSignal: std_logic;

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

66

BEGIN U1 : comp

GENERIC MAP (n => 4)PORT MAP (a => aSignal, b => bSignal, eq => eqSignal, ge => geSignal, le => leSignal);

process begin  …③L1:for i in 0 to 15 loop   …④ 

aSignal <=conv_std_logic_vector(i,4); …⑤  L2:for j in 0 to 15 loop   …⑥

bSignal <=conv_std_logic_vector(j,4); …⑦wait for 100ns;

end loop L2;end loop L1;wait; 

end process;END HTWTestBench;

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

67

①あとで、関数 conv_std_logic_vector ()を使うために必要です。

②次の行のSignal宣言に出てくる n のために必要です。

③このprocess文が、実際のテストパターンを発生させます。

④回数指定の繰り返しは for…loop で記述します。ラベル名:for ループ変数 in 初期値 to 終了値 loop

:end loop ラベル名;

  ※ループ変数 i は宣言が不要です。ラベル名は省略可能。

⑤関数 conv_std_logic_vector ()を使って、整数 i を4ビット幅の  std_logic_vector に変換してから、 aSignal に代入します。 VHDLは型チェックが厳しいので、直接代入はできません。

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

68

⑥整数 j のループです。⑦整数 j を型変換したあと、 bSignal に代入します。

シミュレーション時間は、100ns × 16 × 16=25600ns以上に設定します。結果は下図のようになります。

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

69

2.case文とビット幅のある定数例題2 デコーダ decoder.vhdlibrary ieee;use ieee.std_logic_1164.all;

entity decoder is  port(enb:in std_logic; adr:in std_logic_vector(2 downto 0); y :out std_logic_vector(7 downto 0));end decoder;

decode

adr

enby

architecture v1 of decoder isbegin process(enb,adr) begin if(enb='0') then case(adr) is when "000" => y<="11111110"; when "001" => y<="11111101"; when "010" => y<="11111011"; when "011" => y<="11110111"; when "100" => y<="11101111"; when "101" => y<="11011111"; when "110" => y<="10111111"; when others => y<="01111111"; end case; else y<="11111111"; end if; end process;end v1;

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

70

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

case( 信号名 ) iswhen ケース1 => 式1 ;when ケース2 => 式2 ; : :when others => 式n ;

end case;  と記述する。 others は列記したケース以外、全ての場合とい  う意味です。これが無いとラッチを生成する処理系もある。

(2)ビット幅のある定数は,( 2進数) B"001"     B"1111_1110"(16進数) X"FC"

  と書く。2進数を表す B は省略できる。

(3) else y<= "11111111" がないと,ラッチが生成される。

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

71

例題2のテストベンチ decoder.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench IS

COMPONENT decoder PORT (enb:in std_logic;

adr:in std_logic_vector(2 downto 0);   y :out std_logic_vector(7 downto 0));

END COMPONENT;

SIGNAL enbSignal: std_logic;SIGNAL adrSignal: std_logic_vector(2 downto 0);SIGNAL ySignal : std_logic_vector(7 downto 0);

BEGIN U1 : decoder

PORT MAP (enb => enbSignal, adr => adrSignal, y => ySignal);

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

72

process beginenbSignal <='0';for i in 0 to 7 loop   adrSignal <=conv_std_logic_vector(i,3);  wait for 100ns;end loop;

enbSignal <='1';for i in 0 to 7 loop  adrSignal <=conv_std_logic_vector(i,3);  wait for 100ns;end loop;wait;

end process;END HTWTestBench;シミュレーション時間=2000ns

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

73

3.算術演算子と連接子例題3 アダー  adder.vhd

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;

entity adder is generic (n :integer :=4); port(cin :in std_logic; a,b :in std_logic_vector(n-1 downto 0); cout:out std_logic; s :out std_logic_vector(n-1 downto 0));end adder;

adderab

cin

cout

44

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

74

architecture v1 of adder is signal ax,bx,cx,sx:std_logic_vector(n downto 0);begin

ax(n downto 0)<= '0' & a(n-1 downto 0);bx(n downto 0)<= '0' & b(n-1 downto 0);cx <= (0=>cin, others=>'0');

sx <= ax+bx+cx;s(n-1 downto 0)<= sx(n-1 downto 0);cout <= sx(n);

end v1;--------------------------------------------------------------architecture v2 of adder is signal sx:std_logic_vector(n downto 0);begin

sx <= ('0' & a)+('0' & b)+cin;s <= sx(n-1 downto 0);cout <= sx(n);

end v2;

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

75

(1)加算器,減算器,乗算器を生成するのに算術演算子   +、ー、*が使える。

(2)算術演算子を使うためには, use ieee.std_logic_unsigned.all;  符号なし算術演算パッケージ

  または, use ieee.std_logic_signed.all;   符号有り算術演算パッケージ

  が必要。

(3)キャリ入出力 cin,cout がなければ s <= a + b;

  とコンパクトに記述できる。

(4) verilog の連接演算子 { , } に相当するものは VHDL では  連接子 ( & ) であるが, verilog の様に信号代入文の左辺  には使えないのでアーキテクチャ v2 の様に,   a,b より1ビット多いローカル信号 sx を使って記述するしかない。参照:長谷川テキストp28~30

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

76

  また, VHDL は型チェックが厳しく,左辺と右辺のビット幅が  異なると,代入できないので,

sx <= a+b+cin;  はエラーになってしまう。

(5)アーキテクチャ v2 も,コンパイラによっては通らないかもしれない。  なぜなら, sx と cin のビット幅が違うためである。そのときは(6)の  ように書く。

(6)0ビット目が cin で,他のビットが全て0の幅nビットの信号は,  アーキテクチャ v1 の様に

(0 => cin , others => '0')  と書く。これは,集合体と呼ばれ,0ビット目に限らず,ビット位置を  指定してビット幅のある信号を記述するのに使われる。   ただし,集合体の要素としては,ビット幅1のものしか書けない。  つまり, ('0',a) はエラーになる。 参照:長谷川テキストp28~30

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

77

例題3のテストベンチ adder.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench IS

COMPONENT adder GENERIC (n :integer :=4); PORT (cin :in std_logic; a,b :in std_logic_vector(n-1 downto 0); cout:out std_logic; s :out std_logic_vector(n-1 downto 0));END COMPONENT;

constant n:integer:=4;SIGNAL cinSignal : std_logic;SIGNAL aSignal,bSignal : std_logic_vector(n-1 downto 0);SIGNAL coutSignal: std_logic;SIGNAL sSignal : std_logic_vector(n-1 downto 0);

BEGIN U1 : adder GENERIC MAP (n => 4)

PORT MAP (cin => cinSignal, a => aSignal, b => bSignal, cout => coutSignal, s => sSignal);

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

78

process begin cinSignal <='0';L1:for i in 0 to 15 loop

aSignal <=conv_std_logic_vector(i,4);L2:for j in 0 to 15 loop

bSignal <=conv_std_logic_vector(j,4); wait for 100ns;end loop L2;

end loop L1; cinSignal <='1';L3:for i in 0 to 15 loop

aSignal <=conv_std_logic_vector(i,4);L4:for j in 0 to 15 loop

bSignal <=conv_std_logic_vector(j,4); wait for 100ns;end loop L4;

end loop L3; wait;end process;

END HTWTestBench;シミュレーション時間=16x16x2x100ns=51200ns

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

79

4.フリップフロップの記述例題4 フリップフロップ dff.vhdlibrary ieee;use ieee.std_logic_1164.all;

entity dff is port(d,clk,sclr,aclr,enb:in std_logic; q,qsc,qac,qen:out std_logic);end dff;

dclk

qsc

sclr

同期クリア FF

dclk

q通常 FF

architecture RTL of dff isbegin -- simple ff --- process(clk) begin if(clk'event and clk='1') then q <= d; end if; end process;

-- sync clear ff --- process(clk) begin if(clk'event and clk='1') then

if(sclr='0') then qsc <= '0'; else qsc <= d;

end if;end if;

end process;

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

80

-- async clear ff -- process(clk,aclr) begin if (aclr='0') then qac <= '0'; elsif(clk'event and clk='1') then qac <= d; end if; end process;

-- enb ff -- process(clk) begin if(clk'event and clk='1') then

if(enb='1') then qen <= d; end if;

end if; end process;end RTL;

dclk

qen

enb

イネーブル機能付 FF

dclk

qac

aclr

非同期クリア FF

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

81

(1)フリップフロップの生成には,上の例の様に if(clk'event and clk='1') then

  を使う。 if 文なので process ブロックの中で使う。

(2)同期クリア信号は, process( 信号名 ) のセンシティビティ・リストには記述しないで,はじめの if 文の条件にクロックイベントを次の if 文の条件にクリア信号を記述する。

(3)非同期クリア信号は,センシティビティ・リストに記述するとともに  はじめの if 文の条件にクリア信号を,  次の elsif 文の条件に,クロックイベントを記述する。

(4)イネーブル信号は,同期クリア信号同じ考え方。  つまり、センシティビティ・リストには記述しないで,  はじめの if 文の条件にクロックイベントを  次の if 文の条件にイネーブル信号を記述する。

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

82

例題4のテストベンチ dff.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench IS

COMPONENT dff PORT (d,clk,sclr,aclr,enb:in std_logic;

q,qsc,qac,qen:out std_logic);END COMPONENT;

SIGNAL dSignal,clkSignal,sclrSignal,aclrSignal,enbSignal: std_logic;SIGNAL qSignal,qscSignal,qacSignal,qenSignal: std_logic;

BEGIN U1 : dff   PORT MAP (d => dSignal, clk => clkSignal,

sclr => sclrSignal,   aclr => aclrSignal,   enb => enbSignal, q => qSignal, qsc => qscSignal, qac => qacSignal, qen => qenSignal);

process beginclkSignal <='0';loop …①クロック生成には  for 無しloop が使える。

wait for 50ns;clkSignal <=not clkSignal;

end loop;end process;

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

83

process beginaclrSignal <='1'; sclrSignal <='1'; enbSignal <='1'; dSignal <='1';  wait for 125ns;dSignal <='0';  wait for 200ns;dSignal <='1';  wait for 300ns;aclrSignal <='0'; sclrSignal <='0'; enbSignal <='0';   wait for 200ns;dSignal <='0';  wait for 300ns;aclrSignal <='1'; sclrSignal <='1'; enbSignal <='1';   wait for 200ns;dSignal <='1';wait;

end process;END HTWTestBench;シミュレーション時間=2000ns

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

84

5.エッジ検出回路の記述例題5 エッジ検出 edg.vhdlibrary ieee;use ieee.std_logic_1164.all;

entity edg is port(clk,d,reset:in std_logic; rise,fall:out std_logic);end edg;

architecture v1 of edg is signal q1,q2:std_logic;begin  process(clk) begin if(clk'event and clk='1') then if(reset='0') then q1<='0'; q2<='0'; else q1<=d; q2<=q1; end if; end if; end process;

  rise<= q1 and (not q2);  fall <=(not q1) and q2 ;end v1;

riseclk

d q1 q2

fall

reset

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

85

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

(2)VHDLでは立ち下がり,立ち上がりエッジの検出は  上の例の様に書ける。

(3)VHDLの場合、 q1 用と q2 用の process ブロックを分けても,  分けなくても同じ論理合成結果が得られる。    Verilogの場合は、ブロックを分けるか分けないか、また  =を使うか、<=を使うかで論理合成結果が異なる。

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

86

例題5のテストベンチ  edg.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench IS

COMPONENT edg PORT (clk,d,reset:in std_logic; rise,fall:out std_logic);END COMPONENT;

SIGNAL clkSignal,dSignal,resetSignal: std_logic; SIGNAL riseSignal,fallSignal: std_logic;

BEGIN U1 : edg PORT MAP (clk => clkSignal, d => dSignal, reset => resetSignal,

rise => riseSignal, fall => fallSignal); clock:process begin   …① processにも名前が付けられる。

clkSignal <='0';loop wait for 50ns;

clkSignal <= not clkSignal; end loop; end process;

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

87

d_reset:process begin resetSignal <='0'; dSignal <='0'; wait for 75ns; resetSignal <='1'; wait for 200ns; dSignal <='1'; wait for 300ns; dSignal <='0'; wait for 400ns; dSignal <='1'; wait for 400ns; dSignal <='0'; wait; end process;END HTWTestBench;

シミュレーション時間=2000ns

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

88

6.同期クリア付きカウンタ例題6 countsc.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;

entity countsc isport(clk,clr:in std_logic;   count :out std_logic_vector(3 downto 0)); …②

end countsc;

architecture countsc_body of countsc issignal count_tmp:std_logic_vector(3 downto 0);

begin count <= count_tmp; …③process(clk) begin

if(clk'event and clk='1') thenif(clr='0') then count_tmp <= "0000";

else count_tmp <= count_tmp+1; end if;end if;

end process;end countsc_body;

4countclk

clr

countsc

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

89

(1)同期クリア付カウンタは同期クリアFFのクリア信号の書き方と  算術演算子 + の応用である。

(2)同期クリア信号はイベントリストに記述しないで、  最初のif文の条件にクロックイベントを、  次のif文の条件に同期クリア信号を記述する。

(4)重要なのは VHDL の out 宣言された信号(この例では count )は, アーキテクチャ内部で,読み出し参照できない点である。

(5)信号代入文の左辺には,もちろん書けるので count_tmp の様に,  ローカル信号を宣言し,再代入してやればよい。

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

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

90

例題6のテストベンチ countsc.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench IS

COMPONENT countsc PORT (clk,clr:in std_logic;

count :out std_logic_vector(3 downto 0));END COMPONENT; SIGNAL clkSignal:std_logic:='0';  …① SIGNAL clrSignal:std_logic:='1';  …① SIGNAL countSignal : std_logic_vector(3 downto 0);BEGIN U1 : countsc

   PORT MAP (clk => clkSignal, clr => clrSignal, count => countSignal);clrSignal<='0' after 125ns, '1' after 325ns; …②clkSignal<=(not clkSignal) after 50ns;    …③

END HTWTestBench;

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

91

①シグナルの初期値は、シグナル宣言時に与えることも可能。  =や<=ではなく、:=であることに注意。

②簡単なシグナル値は、カンマで区切って与えることができる。  wait forの場合は相対時間であったが、afterの場合は  絶対時間であることに注意。この例では、clrの初期値は1で、  125nsで0,325nsで1になる。

③初期値を与えたクロック信号はprocess文で囲まなくても、  この書き方で50ns毎に反転する信号になる。

④同期クリアなので、clr=0の次のclk立ち上がりでcount=0と  なることを確認する。  

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

92

7.非同期クリア付きカウンタ例題7 countac.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;

entity countac isport(clk,clr:in std_logic; count :out std_logic_vector(3 downto 0));

end countac;

architecture countac_body of countac issignal count_tmp:std_logic_vector(3 downto 0);

begin count <= count_tmp;process(clk,clr) begin

if(clr='0') then count_tmp <= "0000";elsif(clk'event and clk='1') then count_tmp <= count_tmp+1;end if;

end process;end countac_body;

4countclk

clr

countac

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

93

例題7のテストベンチ countac.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench IS

COMPONENT countac PORT (clk,clr:in std_logic;

  count :out std_logic_vector(3 downto 0));END COMPONENT; SIGNAL clkSignal:std_logic:='0'; SIGNAL clrSignal:std_logic:='1';    SIGNAL countSignal : std_logic_vector(3 downto 0);BEGIN U1 : countac

   PORT MAP (clk => clkSignal, clr => clrSignal, count => countSignal);clrSignal<='0' after 125ns, '1' after 325ns;clkSignal<=(not clkSignal) after 50ns;

END HTWTestBench;

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

94

(1)非同期クリア付カウンタは非同期クリアFFのクリア信号の  書き方と算術演算子 + の応用である。

(2)非同期クリア信号は、イベントリストに記述すると共に 、  はじめのif文の条件にクリア信号を、  次のelsif文の条件にクロックイベントを記述する。

(2)テストベンチは同期クリア付きカウンタと同じもの。  非同期クリアなので、clr=0と同時に、count=0となっている  ことを確認する。

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

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

95

8.ステートマシンの記述例題8 state.vhd

library ieee;use ieee.std_logic_1164.all;

entity state is port(clk,a,res:in std_logic; ss:out std_logic_vector(1 downto 0));end state;architecture v1 of state is signal ss_tmp:std_logic_vector(1 downto 0); constant s00:std_logic_vector(1 downto 0):=B"00"; constant s01:std_logic_vector(1 downto 0):=B"01"; constant s10:std_logic_vector(1 downto 0):=B"10"; constant s11:std_logic_vector(1 downto 0):=B"11";

a a

 a

 a

S00

S01

S11

S10

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

96

begin ss<=ss_tmp; process(clk) begin if(clk'event and clk='1') then

if(res='0') then ss_tmp<=s00;   else case(ss_tmp) is

when s00=> if(a='1') then ss_tmp<=s01; else ss_tmp<=s10; end if;when s01=> if(a='1') then ss_tmp<=s11; end if;when s10=> if(a='0') then ss_tmp<=s11; end if;when s11=> ss_tmp<=s00;

end case; end if; end if; end process;end v1;(1) VHDL のステートマシン記述では,ステートの値は

①  type宣言した論理的な値 ②  constant宣言した物理的な値

  のどちらかを用いる。 (2)上の例では,ステートの値を出力として観測したいので,   constant宣言した物理的な値を用いている。

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

97

(2)このステートマシンは,Verilogの時と同様に s00 が初期状態で,

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

(3) case 文の when に続くケース値にステートマシンのステート値を  記述することになるが,これは process ブロック内の読み出し参  照にあたるので,カウンタの時と同様に,ローカル信号 ss_tmp を  宣言し使っている。

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

98

(4)ステートの値を直接,出力として観測する必要がなければ,   type 宣言した論理的な値を用いても良い。  この場合,アーキテクチャは次のように記述する。

architecture v2 of state istype st_val is (s00,s01,s10,s11);signal st:st_val;

beginprocess(clk) begin : ss_tmp を : st に書き換えたものend process;process(st) begin : st と出力の : 関係の記述end process;

end v2;

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

99

例題8のテストベンチ state.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench IS

COMPONENT state PORT (clk,a,res:in std_logic; ss:out std_logic_vector(1 downto 0));END COMPONENT; SIGNAL clkSignal,aSignal,resSignal: std_logic; SIGNAL ssSignal: std_logic_vector(1 downto 0);BEGIN U1 : state

PORT MAP (clk => clkSignal,a => aSignal,               res => resSignal,ss => ssSignal); clock:process begin

clkSignal<='0';loop wait for 50ns; clkSignal<=not clkSignal; end loop;

end process;

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

100

other:process begin resSignal<='0'; aSignal<='0'; wait for 100ns; resSignal<='1'; wait for 700ns; resSignal<='0'; aSignal<='1'; wait for 100ns; resSignal<='1'; wait; end process;END HTWTestBench;

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

101

9.トライステート出力例題9 triout.vhd

library ieee;use ieee.std_logic_1164.all;

entity triout is port(a,oe:in std_logic; y :out std_logic);end triout;

architecture v1 of triout isbegin y<=a when oe='1' else 'Z';end v1;

a y

oe

architecture v2 of triout isbegin process(a, oe) begin

if(oe='1') then y <=a; else y <='Z';end if;

end process;end v2;

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

102

(1)トライステート出力、双方向バスの記述は実用的なLSIを  設計する上でさけて通れない。

(2)1ビットのハイインピーダンスは 'Z' と書く。   8ビットは X "ZZ"  または  B"ZZZZ_ZZZZ"  と書く。   ただし、PeakVHDLではX "ZZ" は使えない。    (others => 'Z') と書けば、ビット幅に無関係に使える。

(3)トライステート出力は,  V1のように、条件付信号代入文で記述しても良いし、  V2のように、process文とif文で記述しても良い。

(4)トライステート出力は out 宣言する。

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

103

例題9のテストベンチ triout.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench IS

COMPONENT triout PORT (a,oe:in std_logic; y :out std_logic);END COMPONENT; SIGNAL aSignal:std_logic:='0'; SIGNAL oeSignal:std_logic:='0'; SIGNAL ySignal : std_logic;

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

104

BEGIN U1 : triout

PORT MAP (a => aSignal, oe => oeSignal, y => ySignal);

aSignal <=(not aSignal) after 100ns;oeSignal <= '1' after 450ns;

END HTWTestBench;

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

105

10.双方向バスの記述例題10 bidir.vhdlibrary ieee;use ieee.std_logic_1164.all;entity bidir is

port(rd,wr:in std_logic; db :inout std_logic);

end bidir;architecture v1 of bidir is

signal idb,odb:std_logic;begin

idb<=db;db <= odb when(rd='0') else 'Z'; process(wr) begin

if(wr'event and wr='1') then odb<=idb; end if;

end process;end v1;

rd

wr

db idb

odb

D  Q

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

106

architecture v2 of bidir issignal idb,odb:std_logic;

beginidb<=db;process(odb , rd) begin

if(rd=‘0’) then db<=odb; else db<=‘Z’; end if;end process;

process(wr) beginif(wr'event and wr='1') then odb<=idb; end if;

end process;end v2;

(1)双方向バスも,  V1のように条件付信号代入文で記述しても良いし、  V2のようにprocess文とif文で記述しても良い。  ※ Verilog の always 文では,トライステート出力は書けたが,  双方向バスは書けなかった。

(2)双方向バスは inout 宣言する。

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

107

例題10のテストベンチ bidir.tb.vhd

library ieee;use ieee.std_logic_1164.all;ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench ISCOMPONENT bidir PORT (rd,wr:in std_logic;

db :inout std_logic);END COMPONENT; SIGNAL rdSignal,wrSignal: std_logic; SIGNAL dbSignal : std_logic; signal rd_data:std_logic; BEGIN U1 : bidir   PORT MAP (rd => rdSignal,

wr => wrSignal, db => dbSignal);

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

108

   process procedure wr_proc(wr_dt:in std_logic) is begin

dbSignal <= wr_dt; wait for 50ns;    wrSignal <='0'; wait for 50ns; wrSignal <='1'; wait for 50ns; dbSignal <='Z'; wait for 50ns;

end procedure;        procedure rd_proc(signal rd_dt:out std_logic) is

  beginrdSignal <='0'; wait for 100ns;rd_dt <= dbSignal;rdSignal <='1'; wait for 100ns;

  end procedure; begin rdSignal <='1'; wrSignal <='1'; dbSignal <='Z'; wait for 100ns; wr_proc('1'); rd_proc(rd_data); report"time="&time'image(NOW); report"rd_data="&std_logic'image(rd_data);

wait for 100ns; wr_proc('0'); rd_proc(rd_data); report"time="&time'image(NOW); report"rd_data="&std_logic'image(rd_data); wait; end process;END HTWTestBench;

0 50 100 150 200db wr_dt Zwr

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

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

109

(1)プロシージャはテストベンチで使用されるサブルーチン。

(2)プロシージャはキーワードprocedureで始まり、  end procedure;で終わる。

(3)キーワードprocedureの次に、プロシージャ名を書く。  上の例ではでは wr_proc と rd_proc がプロシージャ名。

(4)プロシージャ名の続きの(  )内で引数宣言を行う。wr_procでは、std_logic型の入力引数wr_dt rd_procでは、std_logic型の出力引数rd_dt

が宣言されている。値をメインルーチンに戻すときはrd_dtのようにsignal宣言する。

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

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

110

(6)report文はメッセージを出力する命令であり、  NOWは現在時刻を返す関数です。  信号値などをreport文で表示するときは、型’image(変数)を  使って、型タイプの変数を文字列に変換してから表示します。

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

111

VHDL設計演習

Ⅳ  応 用 編

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

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

112

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桁ストップウオッチをVHDLで記述しなさい。

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

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

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

113

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

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;entity digit is port(clk,res,cin:in std_logic; cout:out std_logic; led :out std_logic_vector(6 downto 0));end digit; architecture v1 of digit is signal dgt:std_logic_vector(3 downto 0);begin process(clk) begin if(       and          ) then

if( ) then dgt<=X"0"; elsif(cin='1' and            ) then dgt<=dgt+1; elsif(cin='1' and dgt =X"9") then dgt<=X"0"; end if; end if; end process; cout<=cin when( ) else '0';

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

114

process(dgt) begincase(dgt) is

when X"0"=> led<= not B"011_1111"; --3f;when X"1"=> led<= not B"000_0110"; --06;when X"2"=> led<= ;when X"3"=> led<= ;when X"4"=> led<= ;when X"5"=> led<= ;when X"6"=> led<= ;when X"7"=> led<= ;when X"8"=> led<= ;when X"9"=> led<= ;when others=> led<= ;

end case; end process;end v1;

④7セグメントデコーダ部は、カウント値を数字表示用データに変換する組合せ回路です。④

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

115

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

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

library ieee;use ieee.std_logic_1164.all;

entity watch is port(start,stop,clk:in std_logic; led1,led2,led3,led4

:out std_logic_vector(6 downto 0));end watch;architecture v1 of watch is component digit port(clk,res,cin:in std_logic; cout:out std_logic; led :out std_logic_vector(6 downto 0)); end component; signal dres,enb1,enb2,enb3,enb4:std_logic; signal state:std_logic_vector(1 downto 0);

constant reset:std_logic_vector(1 downto 0):="00"; constant count:std_logic_vector(1 downto 0):="01"; constant display:std_logic_vector(1 downto 0):="10";

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

116

digit4 enb4 digit3 enb3 digit2 enb2 digit1 enb1

begin process(clk) begin if(clk'event and clk='1') then if(start='1' and stop='1') then state<=reset; elsif( and ) then state<=count; elsif( and ) then state<=display; end if; end if; end process;

enb1<= ; dres<='1' when (state=reset) else '0';

digit1: digit port map(clk,dres,enb1,enb2,led1); digit2: digit port map(clk,dres, , ,led2); digit3: digit port map(clk,dres, , ,led3); digit4: digit port map(clk,dres, , ,led4);

end v1;

⑥digit1 ~ digit4 はそれぞれ   digit1 1/100 秒の桁   digit2 1/10 秒の桁   digit3 1 秒の桁   digit4 10 秒の桁に相当するコンポーネントインスタンスです。

⑦enb1 ~ enb4 は digit1 ~ digit4のキャリ入力とキャリ出力を接続するローカル信号です。

⑥⑦

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

117

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 118: VHDL設計演習 Ⅰ   入 門 編 広島県立西部工業技術センター

118

並列IO  pio.vhdlibrary ieee;use ieee.std_logic_1164.all;entity pio is generic(n:integer:=8); port(cs,rd,wr,res:in std_logic; adr :in std_logic_vector(1 downto 0); db,pa,pb,pc :inout std_logic_vector(n-1 downto 0));end pio;

architecture pio_body of pio is signal qa,qb,qc,cr,odb:std_logic_vector(n-1 downto 0);begin ----- internal register (reset , cs & wr) -----process(wr,res) begin

if(       ) then qa<=(others=>'0'); qb<=(others=>'0'); qc<=(others=>'0'); cr<=(others=>'1');

elsif( and ) then    if( ) then

case( ) is when "00"=> qa<=db;   when "01"=> qb<=db;when "10"=> qc<=db;   when others=> cr<=db;

end case;      end if;      end if;end process;

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

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

119

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

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

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

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

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

----- port tri-state assign -----pa<=qa when (           ) else (others => 'Z');pb<=qb when (           ) else (others => 'Z');pc<=qc when (           ) else (others => 'Z');

----- data selecter -----process( , , , , ) begin

case(        ) iswhen "00"=> odb<=pa;when "01"=> odb<=pb;when "10"=> odb<=pc;when others=> odb<=cr;

end case;end process;

----- databus tri-state assign (cs & rd) ----- db<=odb when(      and       ) else (others => 'Z');

end pio_body;

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

120

PIOのテストベンチ  pio.tb.vhdlibrary ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use ieee.std_logic_arith.all;

ENTITY TestBench ISEND TestBench;

ARCHITECTURE HTWTestBench OF TestBench ISCOMPONENT pio GENERIC (n:integer:=8); PORT (cs,rd,wr,res:in std_logic; adr:in std_logic_vector(1 downto 0); db,pa,pb,pc :inout std_logic_vector(n-1 downto 0));END COMPONENT; constant n:integer:=8; SIGNAL csSignal,rdSignal,wrSignal,resSignal: std_logic; SIGNAL adrSignal : std_logic_vector(1 downto 0); SIGNAL dbSignal,paSignal,pbSignal,pcSignal : std_logic_vector(n-1 downto 0); signal rd_data:std_logic_vector(n-1 downto 0);BEGIN U1 : pio GENERIC MAP (n => 8)

PORT MAP (cs => csSignal, rd => rdSignal, wr => wrSignal, res => resSignal, adr => adrSignal, db => dbSignal,

pa => paSignal, pb => pbSignal, pc => pcSignal); paSignal <= pbSignal after 1ns; -- connect from PB to PA

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

121

processprocedure wr_proc(adr_dt:in std_logic_vector(1 downto 0);

wr_dt:in std_logic_vector(7 downto 0)) isbegin csSignal <='0'; adrSignal <= adr_dt; dbSignal <= wr_dt; wait for 50ns;

wrSignal <='0'; wait for 100ns;wrSignal <='1'; wait for 50ns;csSignal <='1'; adrSignal <= B"11"; dbSignal <= B"ZZZZ_ZZZZ"; wait for 50ns;

end procedure;procedure rd_proc(adr_dt:in std_logic_vector(1 downto 0);

signal rd_dt:out std_logic_vector(7 downto 0)) is begin csSignal <='0'; adrSignal <= adr_dt; wait for 50ns;

rdSignal <='0'; wait for 100ns;rd_dt <= dbSignal;rdSignal <='1'; wait for 50ns;csSignal <='1'; adrSignal <= B"11"; wait for 50ns;

end procedure;begin

csSignal <='1'; rdSignal <='1'; wrSignal <='1';dbSignal <=B"ZZZZ_ZZZZ"; resSignal <='0'; wait for 50ns;resSignal <='1'; wait for 50ns;wr_proc(B"11",X"01"); -- write CW to CRfor i in 0 to 255 loop wr_proc(B"01",conv_std_logic_vector(i,8)); -- write to PB rd_proc(B"00",rd_data); -- read from PA report "i="&integer'image(i)&" rd_data="&integer'image(conv_integer(rd_data));end loop; wait;

end process;END HTWTestBench;

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

122

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

123

解答例watch1.vhd 1/4

library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;

entity digit is port(clk,res,cin:in std_logic; cout:out std_logic; led :out std_logic_vector(6 downto 0));end digit; architecture v1 of digit is signal dgt:std_logic_vector(3 downto 0);begin process(clk) begin if(clk'event and clk='1') then

if(res='1') then dgt<=X"0"; elsif(cin='1' and dgt/=X"9") then dgt<=dgt+1; elsif(cin='1' and dgt =x"9") then dgt<=X"0"; end if; end if; end process; cout<=cin when(dgt=X"9") else '0';

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

124

process(dgt) begincase(dgt) is

when X"0"=> led<= not B"011_1111"; --X"3f";when X"1"=> led<= not B"000_0110"; --X"06";when X"2"=> led<= not B"101_1011"; --X"5b";when X"3"=> led<= not B"100_1111"; --X"4f";when X"4"=> led<= not B"110_0110"; --X"66";when X"5"=> led<= not B"110_1101"; --X"6d";when X"6"=> led<= not B"111_1101"; --X"7d";when X"7"=> led<= not B"010_0111"; --X"27";when X"8"=> led<= not B"111_1111"; --X"7f";when X"9"=> led<= not B"110_1111"; --X"6f";when others=> led<= not B"000_0000"; --X"00";

end case; end process;end v1;

解答例watch1.vhd 2/4

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

125

library ieee;use ieee.std_logic_1164.all;

entity watch is port(start,stop,clk:in std_logic; led1,led2,led3,led4:out std_logic_vector(6 downto 0));end watch;architecture v1 of watch is component digit port(clk,res,cin:in std_logic; cout:out std_logic; led :out std_logic_vector(6 downto 0)); end component; signal dres,enb1,enb2,enb3,enb4:std_logic; signal state:std_logic_vector(1 downto 0); constant reset:std_logic_vector(1 downto 0):="00"; constant count:std_logic_vector(1 downto 0):="01"; constant display:std_logic_vector(1 downto 0):="10";

解答例watch1.vhd 3/4

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

126

begin process(clk) begin if(clk'event and clk='1') then if(start='1' and stop='1') then state<=reset; elsif(start='1' and stop='0') then state<=count; elsif(start='0' and stop='1') then state<=display; end if; end if; end process;

enb1<=state(0); dres<='1' when (state=reset) else '0';

digit1: digit port map(clk,dres,enb1,enb2,led1); digit2: digit port map(clk,dres,enb2,enb3,led2); digit3: digit port map(clk,dres,enb3,enb4,led3); digit4: digit port map(clk,dres,enb4,open,led4);

end v1;

解答例watch1.vhd 4/4

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

127

library ieee;use ieee.std_logic_1164.all;entity pio is generic(n:integer:=8); port(cs,rd,wr,res:in std_logic; adr :in std_logic_vector(1 downto 0); db,pa,pb,pc :inout std_logic_vector(n-1 downto 0));end pio;

architecture pio_body of pio is signal qa,qb,qc,cr,odb:std_logic_vector(n-1 downto 0);begin ----- internal register (reset , cs & wr) -----process(wr,res) begin

if(res='0') then   qa<=(others=>'0'); qb<=(others=>'0');qc<=(others=>'0'); cr<=(others=>'1');

elsif(wr'event and wr='1') then    if(cs='0') then

case(adr) is when "00"=> qa<=db;   when "01"=> qb<=db;when "10"=> qc<=db;   when others=> cr<=db;

end case;      end if;      end if;end process;

解答例pio.vhd  1/2

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

128

----- port tri-state assign -----pa<=qa when (cr(0)='0') else (others => 'Z');pb<=qb when (cr(1)='0') else (others => 'Z');pc<=qc when (cr(2)='0') else (others => 'Z');

----- data selecter -----process(adr,pa,pb,pc,cr) begin

case(adr) iswhen "00"=> odb<=pa;when "01"=> odb<=pb;when "10"=> odb<=pc;when others=> odb<=cr;

end case;end process;

----- databus tri-state assign (cs & rd) ----- db<=odb when(cs='0' and rd='0') else (others => 'Z');

end pio_body;

解答例pio.vhd  2/2