VHDLのサンプルと、SYNOPSYS社VHDLシミュレータDVEの操作方法を紹介します。
-
まずやってみよう
-
もう少しやってみよう
VHDLで記述した5進カウンタです。ファイル名を`counter.vhd'としましょう。
-- 使用するライブラリの宣言(とりあえず以下の3行を書いておけばよい)
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
-- エンティティ宣言(回路の名前と入出力ポートの宣言)
entity COUNTER is
port(
CLK : in std_logic;
INITIALIZE : in std_logic;
ENABLE : in std_logic;
CARRY : out std_logic
);
end COUNTER;
-- アーキテクチャ定義(内部の回路、動作を記述)
architecture RTL of COUNTER is
signal COUNT : integer range 0 to 4;
begin
-- カウント値が4のときに出力する桁上げ信号CARRYの生成
CARRY <= '1' when (COUNT=4) else
'0';
-- クロックに同期して動作する回路の記述例
-- 同期リセット(INITIALIZE)とカウント進行/停止(ENEBLE)を有する
-- 同期5進カウンタの例
process (CLK) begin
if( CLK'event and CLK='1' )then
if( INITIALIZE='1' )then
COUNT <= 0;
elsif( ENABLE='1' )then
if( COUNT=4 )then
COUNT <= 0;
else
COUNT <= COUNT+1;
end if;
end if;
end if;
end process;
end RTL;
この5進カウンタのシミュレーションを行うためには、クロックCLK、
初期化信号INITIALIZEなどをカウンタに供給しなければなりません。
シミュレーションを行うために必要な信号の発生は、やはりVHDLで記述する
ことができます。これをテストベンチと呼びます。
5進カウンタのテストベンチの例を以下に示します。このファイル名を
`counter_bench.vhd'とします。
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
-- エンティティ宣言(テストベンチには入出力ポートはない)
entity BENCH is
end BENCH;
architecture SIM of BENCH is
-- 定数定義(ここではクロックの半周期を100nsにする)
constant STEP : time := 100 ns;
signal CLK : std_logic;
signal INITIALIZE : std_logic;
signal ENABLE : std_logic;
signal CARRY : std_logic;
-- 使用するモジュールの宣言
component COUNTER
port(
CLK : in std_logic;
INITIALIZE : in std_logic;
ENABLE : in std_logic;
CARRY : out std_logic
);
end component;
begin
-- 5進カウンタCOUNTERをモジュールとして呼び出し
counter0: COUNTER port map( CLK, INITIALIZE, ENABLE, CARRY );
-- クロックCLKを発生
process begin
CLK <= '1'; wait for STEP/2;
CLK <= '0'; wait for STEP/2;
end process;
-- INITIALIZE, ENABLEを発生
process begin
INITIALIZE <= '1', '0' after STEP*2;
ENABLE <= '0', '1' after STEP*4, '0' after STEP*30,
'1' after STEP*40;
wait;
end process;
end SIM;
---------
-- 構成定義(シミュレータと合成ツールで使用する情報)
-- 1つのエンティティについてアーキテクチャ定義が1つしか存在しなければ
-- ここはおまじないと考えて以下のように書いておけばよい
configuration COUNTER_TEST OF BENCH IS
for SIM end for;
end COUNTER_TEST;
VHDL解析
まず、VHDLファイルの解析(analyze)を行います。ここでは、文法エラーが検査されます。
モジュールの階層を考慮し、下位のモジュールから順に解析を行います。
もしVHDLファイルを書き換えた場合は、そのVHDLファイルの解析をやり直すとともに、
上位のモジュールを含むVHDLファイルも再度解析する必要があります。
具体的な操作は以下の通りです。
`host[10]'などはUNIXのシェルプロンプトです。
host[10] vhdlan counter.vhd
host[11] vhdlan counter_bench.vhd
|
シミュレーション用実行バイナリの作成
シミュレーションでは、VHDLで書かれた回路の通りに信号(signal)を処理する
計算機プログラムに変換し、そのプログラムを実行することで回路を動作させ、
回路内部の信号値の変化の様子を観察します。
そのためには、VHDL(の解析結果)から実行プログラムを生成する処理が必要です。
これは、vcsコマンドを利用します。
生成された実行プログラムはsimvというファイル名に
なります。
具体的な操作は以下の通りです。
host[12] vcs -debug COUNTER_TEST
|
シミュレーション実行
dveを実行します。
文字フォントがつぶれて見づらいときは、フォント設定を変更するとよいでしょう。
Edit ⇒ Preferences ⇒ General Settings
シミュレーション用実行バイナリを指定します。先にvcsコマンドを実行して生成したsimvファイルを選択します。
波形を観察したい信号を指定します。
指定した信号は、Waveウィンドウ(波形表示ウィンドウ)に追加されます。
モジュール内部の信号を観察したい場合は、階層(Hierachy)をモジュールに移動して
信号を選択します。
いくつかの信号を指定した様子。
シミュレーションを実行します。DVEウィンドウ最下部のコマンド入力部に'run 5000'と入力してEnterキーを押します。
信号波形がWaveウィンドウに表示されます。ツールボタンを使って時間軸の拡大・縮小ができます。
なお、後でもう一度dveで同じシミュレーションを行う場合に、simvの指定や、観測する
波形の指定を再度行うのは面倒です。
現在の設定を保存しておき、後で設定を復元するといった使い方ができます。
現在の設定を保存するには以下のように操作します。
後で設定を復元するには File ⇒ Load Session で行います。
上の5進カウンタをモジュールとして使用する20進カウンタの例を以下に示します。
このファイル名をcount20.vhdとします。
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity COUNT20 is
port(
CLK : in std_logic;
INITIALIZE : in std_logic;
ENABLE : in std_logic;
DECODE_OUT : out std_logic
);
end COUNT20;
architecture RTL of COUNT20 is
signal COUNT : integer range 0 to 3;
signal CARRY5 : std_logic;
component COUNTER
port(
CLK : in std_logic;
INITIALIZE : in std_logic;
ENABLE : in std_logic;
CARRY : out std_logic
);
end component;
begin
-- 5進カウンタをモジュールとして組み込む
counter5: COUNTER port map( CLK, INITIALIZE, ENABLE, CARRY5 );
-- process文による組み合わせ回路
-- カウンタ出力をデコードして所望の信号波形を得る
process (CARRY5,COUNT)
begin
if( COUNT=2 or (COUNT=3 and CARRY5='1') )then
DECODE_OUT <= '1';
else
DECODE_OUT <= '0';
end if;
end process;
-- 順序回路
-- 下位の5進カウンタが桁上げ信号を出力しているときだけ
-- カウントアップする4進カウンタ
process (CLK) begin
if( CLK'event and CLK='1' )then
if( INITIALIZE='1' )then
COUNT <= 0;
elsif( ENABLE='1' and CARRY5='1' )then
if( COUNT=3 )then
COUNT <= 0;
else
COUNT <= COUNT+1;
end if;
end if;
end if;
end process;
end RTL;
テストベンチは以下のようになります。ファイル名を`bench.vhd'とします。
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;
entity BENCH is
end BENCH;
architecture SIM of BENCH is
constant STEP : time := 100 ns;
signal CLK : std_logic;
signal INITIALIZE : std_logic;
signal ENABLE : std_logic;
signal DEC_OUT : std_logic;
component COUNT20
port(
CLK : in std_logic;
INITIALIZE : in std_logic;
ENABLE : in std_logic;
DECODE_OUT : out std_logic
);
end component;
begin
counter0: COUNT20 port map( CLK, INITIALIZE, ENABLE, DEC_OUT );
-- クロックCLKを発生
process begin
CLK <= '1'; wait for STEP/2;
CLK <= '0'; wait for STEP/2;
end process;
process begin
INITIALIZE <= '1', '0' after STEP*2;
ENABLE <= '0', '1' after STEP*4, '0' after STEP*30,
'1' after STEP*40;
wait;
end process;
end SIM;
---------
configuration COUNTER_TEST OF BENCH IS
for SIM end for;
end COUNTER_TEST;
以下のように操作します。
host[20] vhdlan counter.vhd (書き換えていなければ不要)
host[21] vhdlan count20.vhd
host[22] vhdlan bench.vhd
host[23] vcs -debug COUNTER_TEST
host[24] dve
|
以降の操作は、上記5進カウンタの場合と同様です。
Copyright (c) 2009,2014 埼玉大学 伊藤和人