VHDLのサンプルと、SYNOPSYS社のVHDLシミュレータ操作方法を紹介します。
まずやってみよう
もう少しやってみよう

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;

SYNOPSYS社のVHDLシミュレータを使用する場合の操作例を以下に示します。 シミュレータを実行する前に、どの信号を観察するかを指定するファイルを 作成しておくと良いでしょう。例えば以下のような内容になります。
set PROMPT ^$file->^

trace /BENCH/CLK
trace /BENCH/INITIALIZE
trace /BENCH/ENABLE
trace /BENCH/CARRY
trace /BENCH/counter0/COUNT
trace /BENCH/counter0/CARRY

シミュレータ実行操作は以下の通りです。 `host[10]'などはUNIXのシェルプロンプト、 `counter_bench.vhd->'の部分は、シミュレータのコマンドプロンプトです。 `run 5000'と入力して、5000nsのシミュレーションを実行します。
host[10] vhdlan counter.vhd
host[11] vhdlan counter_bench.vhd
host[12] vhdlsim COUNTER_TEST
counter_bench.vhd->restart
counter_bench.vhd->run 5000
5000 NS
counter_bench.vhd->

結果は以下のようになります。


上の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[10] vhdlan count20.vhd
host[11] vhdlan bench.vhd
host[12] vhdlsim COUNTER_TEST
bench.vhd->restart
bench.vhd->run 10000
10000 NS
bench.vhd->

結果は以下のようになります。

(c) 2000 埼玉大学 伊藤和人