読み込み中...

VHDLセンシティビティリスト完全解説!初心者向け10選

VHDLのセンシティビティリストを図解したイメージ VHDL
この記事は約17分で読めます。

【サイト内のコードはご自由に個人利用・商用利用いただけます】

この記事では、プログラム(回路記述)の基礎知識を前提に話を進めています。

説明のためのコードや、サンプルコードもありますので、もちろん初心者でも理解できるように表現してあります。

本記事のサンプルコードを活用して機能追加、目的を達成できるように作ってありますので、是非ご活用ください。

※この記事は、一般的にプロフェッショナルの指標とされる『実務経験10,000時間以上』を満たす現役のプログラマチームによって監修されています。

※Japanシーモアは、常に解説内容のわかりやすさや記事の品質に注力しております。不具合、分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

VHDLのセンシティビティリストは、デジタル回路設計における重要な概念の一つです。

この記事では、初心者向けにVHDLセンシティビティリストの基本から応用まで、サンプルコードと共に詳しく解説します。

VHDLのセンシティビティリストを理解し、より効率的なデジタル回路設計を目指しましょう。

●VHDLセンシティビティリストの基本

○センシティビティリストとは?

センシティビティリストは、VHDLにおけるプロセスが動作するトリガーとなる信号のリストを表します。

このリストの中に含まれる信号が変更されると、関連するプロセスが起動されます。

○なぜセンシティビティリストが必要か

センシティビティリストは、プロセスが実行されるタイミングを制御することで、不要な動作を避けるための重要な要素です。

これにより、回路の動作を効率的にし、エネルギー消費や回路のサイズを削減できます。

●センシティビティリストの基本的な使い方

○サンプルコード1:基本的なセンシティビティリストの使用方法

このコードでは、センシティビティリストを使って基本的な動作を実現する方法を表しています。

この例では、信号AとBが変更されたときにプロセスが起動します。

process (A, B)
begin
    C <= A and B;
end process;

このコードでは、信号AとBが変わるたびに、CにAとBの論理ANDの結果が代入されます。

○サンプルコード2:異なる信号を持つセンシティビティリスト

このコードでは、異なる信号を持つセンシティビティリストの動作を表しています。

この例では、信号XとYが変更されたときに、Dの値が変更されます。

process (X, Y)
begin
    D <= X or Y;
end process;

XまたはYのいずれかが変更されると、DにXとYの論理ORの結果が代入されます。

●センシティビティリストの応用例

○サンプルコード3:複雑なロジックの実装

このコードでは、複数の信号を使用して複雑なロジックを実装する方法を表しています。

この例では、信号E, F, Gを使って、Hの値を決定します。

process (E, F, G)
begin
    H <= (E and F) or G;
end process;

このコードの動作としては、EとFの論理ANDの結果とGの論理ORの結果がHに代入されます。

○サンプルコード4:外部モジュールとの組み合わせ

VHDLのセンシティビティリストをさらに高度に利用する方法として、外部モジュールとの組み合わせが考えられます。

外部モジュールを組み込むことで、より複雑なロジックを効率的に実装することが可能になります。

このコードでは、外部のモジュールとセンシティビティリストを組み合わせて動作させる方法を紹介しています。

この例では、外部モジュールを呼び出して、その結果をセンシティビティリストで監視することで特定の動作を実行します。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity main_module is
    Port ( clk : in STD_LOGIC;
           rst : in STD_LOGIC;
           input_signal : in STD_LOGIC_VECTOR(7 downto 0);
           output_signal : out STD_LOGIC_VECTOR(7 downto 0));
end main_module;

architecture Behavioral of main_module is
    signal internal_signal : STD_LOGIC_VECTOR(7 downto 0);

    component external_module
    Port ( ext_input : in STD_LOGIC_VECTOR(7 downto 0);
           ext_output : out STD_LOGIC_VECTOR(7 downto 0));
    end component;

begin

    process(clk, rst)
    begin
        if rst = '1' then
            internal_signal <= "00000000";
        elsif rising_edge(clk) then
            external_module_inst : external_module
            port map(ext_input => input_signal, ext_output => internal_signal);
        end if;
    end process;

    process(clk)
    begin
        if rising_edge(clk) then
            output_signal <= internal_signal;
        end if;
    end process;

end Behavioral;

上記のVHDLコードにおいて、main_moduleという主要なモジュールが存在しています。

この中に、external_moduleという外部モジュールがコンポーネントとして宣言され、その後インスタンス化されています。

外部モジュールの結果はinternal_signalに格納され、その後output_signalに転送されます。

ここでのポイントは、センシティビティリストの動作を外部モジュールと組み合わせて行っている点です。

外部モジュールの結果をリアルタイムで監視し、それに基づいて主モジュールでの動作を調整することができます。

このようにして、外部モジュールの結果をうまく組み込んだ動作を実現することができるのです。この方法を利用することで、多機能なVHDLロジックを効率的に構築することができます。

●VHDLプログラミングの注意点とその対処法

VHDLのコーディングでは、特にセンシティビティリストに関連する部分でいくつかの注意点が存在します。

センシティビティリストはVHDLでの記述の中心となる部分ですが、その扱い方によっては予期しない動作をする可能性があります。

○センシティビティリストの欠点とは?

センシティビティリストは、プロセス内の信号の変化に対して反応するためのリストです。

しかし、全ての信号をリストに含めないと、その信号の変化には反応しないという問題があります。

これは、特に大規模なプロジェクトや複雑なロジックを扱っている場合において、信号の欠落が原因でのバグを生む可能性があります。

○サンプルコード5:注意点を踏まえた安全なコーディング

このコードでは、センシティビティリストを使ってLEDの点滅を制御するコードを表しています。

この例では、クロック信号とリセット信号をセンシティビティリストに追加して、LEDの点滅タイミングを制御しています。

entity blink_led is
    Port ( clk : in STD_LOGIC;
           rst : in STD_LOGIC;
           led : out STD_LOGIC);
end blink_led;

architecture Behavioral of blink_led is
    signal counter : integer := 0;
begin
    process(clk, rst) -- センシティビティリストにclkとrstを追加
    begin
        if rst = '1' then
            counter <= 0;
            led <= '0';
        elsif rising_edge(clk) then
            if counter = 5000000 then
                counter <= 0;
                led <= not led; -- LEDの状態を切り替える
            else
                counter <= counter + 1;
            end if;
        end if;
    end process;
end Behavioral;

このコードのポイントは、クロックの立ち上がりエッジでカウンタをインクリメントし、特定のカウント値でLEDの状態を切り替えることです。

リセット信号がアクティブになった場合、カウンタとLEDの状態を初期化します。

このコードが実行されると、LEDは一定の間隔で点滅します。

クロック信号の立ち上がりエッジに反応して動作するため、クロック信号とリセット信号をセンシティビティリストに追加することが重要です。

●カスタマイズの方法

VHDLのセンシティビティリストは、基本的な使い方だけでなく、さまざまなカスタマイズの方法も提供しています。

これにより、プロジェクトの要件に応じて最適な動作をするハードウェア記述を行うことができます。

○サンプルコード6:独自のセンシティビティリストの作成

このコードでは、独自のセンシティビティリストを作成して、特定の条件下でのみ反応するロジックを実装する方法を表しています。

この例では、2つの入力信号AとBの両方が’1’の場合にのみ、出力信号outを’1’にします。

entity custom_sensitivity is
    Port ( A, B : in STD_LOGIC;
           out : out STD_LOGIC);
end custom_sensitivity;

architecture Behavioral of custom_sensitivity is
begin
    process(A, B) -- センシティビティリストにAとBを追加
    begin
        if (A = '1' and B = '1') then
            out <= '1';
        else
            out <= '0';
        end if;
    end process;
end Behavioral;

このコードの特徴は、センシティビティリストにAとBの2つの信号を追加している点です。

これにより、AまたはBのどちらかの信号が変わったとき、プロセスが実行され、出力信号outの値が更新されます。

このコードが実行されると、AとBの両方が’1’の場合にのみ、出力信号outが’1’になる動作を表します。

それ以外の場合、出力信号outは’0’になります。

○サンプルコード7:複数のセンシティビティリストの組み合わせ

このコードでは、複数のセンシティビティリストを組み合わせて使用する方法を表しています。

この例では、2つの異なるセンシティビティリストを持つ2つのプロセスを定義し、それぞれのプロセスで異なる動作をさせています。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity MultipleSensitivityList is
    Port ( X : in STD_LOGIC;
           Y : in STD_LOGIC;
           Z : out STD_LOGIC;
           W : out STD_LOGIC);
end MultipleSensitivityList;

architecture Behavioral of MultipleSensitivityList is
begin
    process(X) -- Xをセンシティビティリストに追加
    begin
        if X = '1' then
            Z <= '1';
        else
            Z <= '0';
        end if;
    end process;

    process(Y) -- Yをセンシティビティリストに追加
    begin
        if Y = '1' then
            W <= '1';
        else
            W <= '0';
        end if;
    end process;

end Behavioral;

このコードでは、Xの値が変更されたときに、Zの出力がトリガされ、Yの値が変更されたときに、Wの出力がトリガされます。

これにより、2つの入力信号XとYが独立して2つの出力信号ZとWに影響を与える動作が確認できます。

この例をVHDLのシミュレータで実行した場合、Xが1の時にZの出力が1となり、Xが0の場合、Zの出力は0となります。

同様に、Yが1の時にWの出力が1となり、Yが0の場合、Wの出力は0となります。

このように、複数のセンシティビティリストを組み合わせることで、複雑なロジックや条件分岐を持つVHDLプログラムを簡単に実装することができます。

これは特に、大規模なVHDLプロジェクトや、多くの入力信号や出力信号を持つモジュールを開発する際に非常に役立ちます。

次に、VHDLのコーディングスタイルと最適化について解説します。

効率的なコードの書き方や実際のプロジェクトでの活用法など、VHDLプログラミングのベストプラクティスを紹介しますので、是非参考にしてみてください。

●VHDLのコーディングスタイルと最適化

VHDLを使用したハードウェアの設計では、効率的なコーディングスタイルや最適化技術を駆使することで、より高速で正確な動作を持つ回路を設計することが可能となります。

ここでは、VHDLでのコーディングスタイルの良し悪しや、最適化の基本的な考え方を解説します。

○サンプルコード8:効率的なコードの書き方

このコードでは、効率的なコーディングスタイルを採用して、単純な加算器をVHDLで記述する方法を表しています。

この例では、入力と出力の信号を明確に定義し、読みやすくメンテナンスしやすいコードを心がけています。

-- 効率的なコーディングスタイルを用いた加算器の例
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

entity adder is
    port(
        A, B : in STD_LOGIC_VECTOR(7 downto 0);
        SUM : out STD_LOGIC_VECTOR(7 downto 0)
    );
end adder;

architecture Behavior of adder is
begin
    process(A, B)
    begin
        SUM <= A + B;
    end process;
end Behavior;

このコードでは、加算器を効率的なコーディングスタイルで設計しています。

具体的には、信号の名前を一貫性を持って命名し、ライブラリの使用も最小限にとどめています。

コードの実行結果として、8ビットの入力信号AとBが与えられたとき、その和がSUMとして出力されます。

○サンプルコード9:実際のプロジェクトでの活用法

次に、実際のプロジェクトにおけるVHDLの活用法を見てみましょう。

このコードでは、データの保存と取得を行うシンプルなメモリモジュールを紹介しています。

この例では、データの書き込みと読み込みの処理を行うためのセンシティビティリストを使用しています。

-- メモリモジュールの例
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

entity simple_memory is
    port(
        CLK : in STD_LOGIC;
        WE : in STD_LOGIC;
        ADDR : in STD_LOGIC_VECTOR(7 downto 0);
        DATA_IN : in STD_LOGIC_VECTOR(7 downto 0);
        DATA_OUT : out STD_LOGIC_VECTOR(7 downto 0)
    );
end simple_memory;

architecture Behavior of simple_memory is
    signal memory_array : array (255 downto 0) of STD_LOGIC_VECTOR(7 downto 0);
begin
    process(CLK)
    begin
        if rising_edge(CLK) then
            if WE = '1' then
                memory_array(to_integer(ADDR)) <= DATA_IN;
            else
                DATA_OUT <= memory_array(to_integer(ADDR));
            end if;
        end if;
    end process;
end Behavior;

このコードでは、クロック信号(CLK)の立ち上がりエッジに同期して、データの書き込みや読み込みの処理を行います。

書き込みを行う場合は、WE信号が’1’にセットされ、指定されたアドレス(ADDR)にDATA_INの値が保存されます。

読み込みを行う場合は、指定されたアドレスのデータがDATA_OUTとして出力されます。

コードの実行結果として、WE信号が’1’のときには指定アドレスにデータが保存され、’0’のときには指定アドレスのデータが出力されます。

●センシティビティリストを活用した実践的なプロジェクト例

VHDLのセンシティビティリストは、特定の信号の変化に反応して動作するプロセスを記述する際に非常に有効です。

ここでは、センシティビティリストを活用した大規模なVHDLプロジェクトの実践例を紹介します。

○サンプルコード10:大規模なVHDLプロジェクトでの応用例

このコードでは、大規模なVHDLプロジェクトにおいてセンシティビティリストを活用する例を紹介しています。

この例では、データパスと制御ユニットを持つシンプルなプロセッサの一部として、アルゴリズムを実装しています。

また、複数のモジュールを組み合わせて、一つの大規模なシステムを構築しています。

-- モジュールの宣言
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Processor is
  Port ( clk : in STD_LOGIC;
         rst : in STD_LOGIC;
         data_in : in STD_LOGIC_VECTOR(7 downto 0);
         data_out : out STD_LOGIC_VECTOR(7 downto 0);
         ctrl_signal : out STD_LOGIC);
end Processor;

architecture Behavior of Processor is

-- 内部信号の宣言
signal internal_data : STD_LOGIC_VECTOR(7 downto 0);
signal ctrl_internal : STD_LOGIC;

begin
  process(clk, rst)
  begin
    if rst = '1' then
      internal_data <= (others => '0');
      ctrl_internal <= '0';
    elsif rising_edge(clk) then
      -- ここで何らかのデータ処理ロジックを記述
      internal_data <= data_in;
      ctrl_internal <= not ctrl_internal;
    end if;
  end process;

  -- 出力信号の割り当て
  data_out <= internal_data;
  ctrl_signal <= ctrl_internal;

end Behavior;

この例では、シンプルなプロセッサの一部を実装しています。クロック信号clkとリセット信号rstを入力として受け取り、data_inのデータを内部で処理してdata_outとして出力します。

さらに、内部での制御信号ctrl_internalを反転させて、ctrl_signalとして出力しています。

このシステムを実際にFPGAやASICに実装し、動作させた場合、入力データが変更されるたびにdata_outが更新され、ctrl_signalはクロックの毎回の立ち上がりで反転するという動作をします。

このように、センシティビティリストを活用して、必要なタイミングでのみロジックが実行されるように設計することができます。

VHDLのセンシティビティリストを利用することで、硬件の動作を正確に記述し、予期しない動作を回避することが可能となります。

特に大規模なプロジェクトでは、複数のモジュールや信号を扱う必要があるため、センシティビティリストの正確な使用は非常に重要です。

このプロジェクトを実際に動作させた場合、前述した通り、入力データに変更があった場合やクロックの立ち上がり時にのみ、出力や制御信号が更新されることが確認できます。

これにより、リソースの無駄な使用を避け、効率的なシステムの実現が期待できます。

まとめ

VHDLのセンシティビティリストは、ハードウェアの動的な振る舞いを記述する際の強力なツールです。

この記事では、センシティビティリストの基本から応用まで、多岐にわたる実例を交えて解説しました。

VHDLを使ったハードウェア設計の参考になれば幸いです。