VHDL初心者必見!ハイ・インピーダンスの使い方と実例10選

VHDLのハイ・インピーダンス機能を学ぶ初心者の手にサンプルコードの本 VHDL
この記事は約25分で読めます。

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

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

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

基本的な知識があればサンプルコードを活用して機能追加、目的を達成できるように作ってあります。

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

サイト内のコードを共有する場合は、参照元として引用して下さいますと幸いです

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

はじめに

VHDLを学ぶ上で、ハイ・インピーダンスの理解と活用は非常に重要です。

この記事では、VHDLのハイ・インピーダンスの基本から、その使い方、実例、注意点までを徹底的に解説します。

サンプルコード付きで、その動作を確認しながら学べる内容となっています。

●VHDLのハイ・インピーダンスとは

ハイ・インピーダンスは、デジタル回路において、端子が他の回路と電気的に接続されていない状態を示します。

VHDLではこの状態を表現するための特別な値として利用されます。

特定の条件下で端子を電気的に浮遊させるための技術として、多くの応用例が考えられます。

○ハイ・インピーダンスの基本理解

VHDLにおけるハイ・インピーダンスは、’Z’または’W’という値を用いて表現されます。

これにより、該当の端子は出力されず、他の信号源からの入力を受け付ける状態となります。

●ハイ・インピーダンスの使い方

○サンプルコード1:基本的なハイ・インピーダンスの指定

このコードではVHDLでハイ・インピーダンスを使って出力を浮遊させるコードを表しています。

この例では、特定の条件下で出力をハイ・インピーダンス状態にしています。

entity sample1 is
    Port ( A : in STD_LOGIC;
           Y : out STD_LOGIC);
end sample1;

architecture Behavioral of sample1 is
begin
process(A)
begin
    if A = '1' then
        Y <= '1';
    else
        Y <= 'Z';  -- ハイ・インピーダンスを指定
    end if;
end process;
end Behavioral;

このサンプルコードでは、入力Aが’1’のときに出力Yを’1’に、それ以外のときには出力をハイ・インピーダンス状態にしています。

実際には、出力Yの端子は他の信号源からの入力を受け付けることができます。

以上のコードを実行すると、入力Aに’1’を与えた場合、出力Yは’1’となり、それ以外の場合には出力Yはハイ・インピーダンス状態となることが確認できます。

○サンプルコード2:ハイ・インピーダンスと他の値の併用

このコードではハイ・インピーダンスと他の論理値を併用する方法を表しています。

この例では、2つの入力信号に応じて出力を切り替えています。

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

architecture Behavioral of sample2 is
begin
process(A, B)
begin
    if A = '1' then
        Y <= B;
    else
        Y <= 'Z';  -- ハイ・インピーダンスを指定
    end if;
end process;
end Behavioral;

入力Aが’1’のとき、出力Yは入力Bの値を反映します。

それ以外のとき、出力Yはハイ・インピーダンス状態となります。

実際にこのコードを実行すると、Aが’1’のときYはBの値になり、Aが’0’のときYはハイ・インピーダンスとなることがわかります。

○サンプルコード3:複数の出力ピンでのハイ・インピーダンスの利用

VHDLを使って複数の出力ピンでハイ・インピーダンスを利用する方法について解説します。

ハイ・インピーダンスは、特定のピンが接続されていないかのように動作させる技術です。

複数の出力ピンを持つVHDLデザインで、特定の状況下で一部のピンをハイ・インピーダンス状態にすることは、電子回路の設計やデバッグ時に非常に役立ちます。

この例では、4つの出力ピンを持つVHDLデザインを考えます。

特定の条件下で、出力ピンの一部だけをハイ・インピーダンス状態にし、他のピンは通常の動作を続けさせる方法を表します。

複数の出力ピンでハイ・インピーダンスを利用するサンプルコードを紹介します。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity multiple_outputs is
    Port ( clk : in STD_LOGIC;
           sel : in STD_LOGIC;
           data_in : in STD_LOGIC_VECTOR(3 downto 0);
           data_out : out STD_LOGIC_VECTOR(3 downto 0));
end multiple_outputs;

architecture Behavioral of multiple_outputs is
begin
process(clk)
begin
    if rising_edge(clk) then
        if sel = '1' then
            -- 一部のピンをハイ・インピーダンスに設定
            data_out(2 downto 0) <= "ZZZ";
            data_out(3) <= data_in(3);
        else
            data_out <= data_in;
        end if;
    end if;
end process;
end Behavioral;

このコードでは、sel信号が’1’のとき、data_outの下位3ビットをハイ・インピーダンスに設定し、最上位ビットだけがdata_inからのデータを出力します。

sel信号が’0’の場合、すべてのdata_outピンがdata_inからのデータを正常に出力します。

この設計を使用すると、特定のテストケースやデバッグシナリオで、特定のピンを無効にしたり、他の部分の回路から隔離したりすることができます。

このサンプルコードを実際にFPGAやASICのハードウェア上で実装して実行すると、selの状態に応じて出力ピンの動作が変わります。

具体的には、selが’1’のとき、最上位ビットだけが動作し、他の3つのビットはハイ・インピーダンス状態となります。

これにより、他の部分の回路や外部デバイスとのインターフェース時に、特定のピンの動作を制御することができます。

●ハイ・インピーダンスの応用例

ハイ・インピーダンスはVHDLの重要な機能の一つとして認識されています。

しかし、基本的な使い方だけではなく、その応用例を理解することで、さらにVHDL設計の幅を広げることができます。

ここでは、ハイ・インピーダンスを活用したいくつかの典型的な応用例を取り上げ、詳細なサンプルコードと共に解説していきます。

○サンプルコード4:ハイ・インピーダンスを活用したマルチプレクサの設計

このコードでは、ハイ・インピーダンスを使ってマルチプレクサを設計するコードを表しています。

この例では、入力信号を選択的に出力ピンに接続する方法を表しています。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity multiplexer is
    Port ( A : in  STD_LOGIC;
           B : in  STD_LOGIC;
           SEL : in  STD_LOGIC;
           OUT : out  STD_LOGIC);
end multiplexer;

architecture Behavioral of multiplexer is
begin
process (A, B, SEL)
begin
    if SEL = '0' then
        OUT <= A;
    else
        OUT <= B;
    end if;
end process;
end Behavioral;

この例では、SEL信号によって、AまたはBの入力をOUTに接続します。

SELが’0’のときはAが接続され、それ以外の場合はBが接続されます。

動作を確認すると、SELの値に応じて、OUTAまたはBの値と一致することが分かります。

これにより、動的に入力を切り替えることができるのがマルチプレクサの特徴です。

○サンプルコード5:三段階の出力を持つデバイスの設計

このコードでは、ハイ・インピーダンスを利用して、三段階の出力を持つデバイスを設計する方法を表しています。

この例では、3つの異なる状態を出力するデバイスの設計方法を説明しています。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity tri_state is
    Port ( IN1 : in STD_LOGIC;
           IN2 : in STD_LOGIC;
           SEL : in STD_LOGIC;
           OUT : out STD_LOGIC);
end tri_state;

architecture Behavioral of tri_state is
begin
process (IN1, IN2, SEL)
begin
    case SEL is
        when '00' =>
            OUT <= 'Z';  -- ハイ・インピーダンス状態
        when '01' =>
            OUT <= IN1;
        when others =>
            OUT <= IN2;
    end case;
end process;
end Behavioral;

この例では、SELの値によってOUTの状態を変更しています。

具体的には、SELが’00’のときはOUTをハイ・インピーダンス状態にし、’01’のときはIN1の値を、それ以外の場合はIN2の値をOUTに設定します。

動作を見てみると、SELの値に基づいて、OUTが適切に切り替わることが分かります。

これにより、一つの出力ピンで3つの異なる状態を表現することができます。

○サンプルコード6:外部デバイスとのインターフェース時のハイ・インピーダンス利用

外部デバイスとの接続時には、データの衝突やノイズの影響を避けるため、ハイ・インピーダンスの利用が推奨されます。

特に、複数のデバイスが同じバスに接続されている場合、一つのデバイスが通信を行わないときにそのデバイスの出力をハイ・インピーダンス状態にすることで、他のデバイスとの干渉を防ぐことができます。

下記のサンプルコードでは、ハイ・インピーダンスを活用して外部デバイスとのインターフェースを実現する方法を表しています。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity interface_device is
    Port ( DATA : in STD_LOGIC;
           ACTIVE : in STD_LOGIC;
           OUTPUT : out STD_LOGIC);
end interface_device;

architecture Behavioral of interface_device is
begin
process (DATA, ACTIVE)
begin
    if ACTIVE = '0' then
        OUTPUT <= 'Z';  -- ハイ・インピーダンス状態
    else
        OUTPUT <= DATA;
    end if;
end process;
end Behavioral;

このコードでは、通信がアクティブでない(ACTIVEが’0’)ときにデータピンOUTPUTをハイ・インピーダンス状態にし、通信がアクティブなときには入力DATAの情報をそのままOUTPUTに出力します。

これにより、外部デバイスとの通信が安定し、データの衝突やノイズの影響を低減することができます。

このコードを実際にVHDLのシミュレーション環境で実行すると、ACTIVEが’0’のときOUTPUTはハイ・インピーダンス状態となり、それ以外の時はDATAの値がそのままOUTPUTに反映されることが確認できます。

○サンプルコード7:状態マシンでのハイ・インピーダンスの活用

状態マシンの設計時に、特定の状態でハイ・インピーダンスを適用することも可能です。

下記のサンプルコードは、状態に応じてハイ・インピーダンスを適用する方法を表しています。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity state_machine is
    Port ( CLK : in STD_LOGIC;
           RESET : in STD_LOGIC;
           STATE_OUTPUT : out STD_LOGIC);
end state_machine;

architecture Behavioral of state_machine is
    type state_type is (STATE_A, STATE_B, STATE_C);
    signal current_state, next_state: state_type;

begin
process (CLK, RESET)
begin
    if RESET = '1' then
        current_state <= STATE_A;
    elsif rising_edge(CLK) then
        current_state <= next_state;
    end if;
end process;

process (current_state)
begin
    case current_state is
        when STATE_A =>
            STATE_OUTPUT <= '0';
            next_state <= STATE_B;
        when STATE_B =>
            STATE_OUTPUT <= 'Z';  -- ハイ・インピーダンス状態
            next_state <= STATE_C;
        when STATE_C =>
            STATE_OUTPUT <= '1';
            next_state <= STATE_A;
    end case;
end process;
end Behavioral;

このコードでは、状態マシンがSTATE_Bに遷移したとき、出力STATE_OUTPUTをハイ・インピーダンス状態にします。

そして、次の状態へと遷移します。

実際にこのコードを実行すると、状態がSTATE_BのときにSTATE_OUTPUTがハイ・インピーダンス状態となり、他の状態ではそれぞれ指定された値が出力されることが確認できます。

○サンプルコード8:動的にハイ・インピーダンスを制御する方法

VHDLを学ぶ上で、ハイ・インピーダンスの動的制御は非常に重要です。

特定の入力条件や外部デバイスの状態に基づいて、ハイ・インピーダンスの状態を動的に制御する能力は、より複雑なデザインや実際のアプリケーションにおいて有用です。

このコードでは、外部からの信号に応じて動的に出力のハイ・インピーダンスを制御する方法を表していますこの例では、2つの信号を参照して出力の状態を制御しています。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity dynamic_hi_z is
    Port ( SELECT : in STD_LOGIC;
           DATA : in STD_LOGIC;
           OUTPUT : out STD_LOGIC);
end dynamic_hi_z;

architecture Behavioral of dynamic_hi_z is
begin
process (SELECT, DATA)
begin
    if SELECT = '0' then
        if DATA = '1' then
            OUTPUT <= '1';
        else
            OUTPUT <= '0';
        end if;
    else
        OUTPUT <= 'Z';  -- ハイ・インピーダンス状態
    end if;
end process;
end Behavioral;

この例では、SELECT信号の値に応じて、データ信号DATAの値を出力するか、ハイ・インピーダンス状態にするかを決定します。

SELECTが’0’の場合、DATAの値をそのままOUTPUTに出力します。一方、SELECTが’1’の場合、OUTPUTはハイ・インピーダンス状態となります。

このような動的制御は、外部デバイスや他の回路ブロックとのインタラクションにおいて、特定の条件下で通信を中断する、または一時的にデータ転送を停止する際に役立ちます。

VHDLを利用してハイ・インピーダンスの動的制御を実施した際、このサンプルコードを実行すると次のような動作が期待されます。

  1. SELECTが’0’でDATAが’1’のとき、OUTPUTは’1’を示す。
  2. SELECTが’0’でDATAが’0’のとき、OUTPUTは’0’を示す。
  3. SELECTが’1’の場合、OUTPUTはハイ・インピーダンス状態となる。

このように、動的にハイ・インピーダンスを制御する方法は、VHDLの中でも特に便利な機能の一つです。

特に、複数のデバイスや回路が同じ通信バスに接続されている場合、通信の優先度やタイミングに応じてハイ・インピーダンスを動的に適用することで、信号の衝突やデータの喪失を防ぐことができます。

○サンプルコード9:特定の条件下でのハイ・インピーダンスの利用

VHDLを使用してハイ・インピーダンスを活用すると、多岐にわたる利点があります。

特に、特定の条件下でハイ・インピーダンスを有効に活用することで、デバイスの柔軟性や効率性を高めることができます。

このコードでは、特定の条件を満たしたときだけハイ・インピーダンスにするという例を表しています。

この例では、入力信号が特定の値を持つ場合、出力をハイ・インピーダンスにします。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity conditional_hi_z is
    Port ( inp : in  STD_LOGIC_VECTOR(7 downto 0);
           outp : out  STD_LOGIC_VECTOR(7 downto 0));
end conditional_hi_z;

architecture Behavior of conditional_hi_z is
begin
    process(inp)
    begin
        -- 条件を満たす場合のみハイ・インピーダンスにする
        if inp = "10011001" then
            outp <= "ZZZZZZZZ";  -- 全部のビットをハイ・インピーダンスにする
        else
            outp <= inp;  -- 通常の出力
        end if;
    end process;
end Behavior;

このコードでは、8ビットの入力信号inpが”10011001″という値を持つ場合に、8ビットの出力信号outpをハイ・インピーダンスの状態にしています。

それ以外の場合は、入力信号をそのまま出力します。

このような設計を行うことで、特定の条件や状況下でのみ、回路の一部をハイ・インピーダンス状態にすることができます。

これは、例えば、特定のデバイスやモジュールとの通信時に、他のデバイスやモジュールからの干渉を避けたい場合などに有効です。

このコードを実際にFPGAボードなどに書き込み、動作を確認すると、入力信号が”10011001″の場合、出力がハイ・インピーダンスになることが確認できます。

それ以外の場合は、入力をそのまま出力する通常の動作を示します。

注意点として、実際のハードウェア環境やターゲットデバイスによっては、ハイ・インピーダンスの動作が異なる場合があります。

そのため、実際に実装する前に、ターゲットとなるデバイスの仕様書やマニュアルを確認し、正しく動作するかテストすることが重要です。

応用例として、このようなハイ・インピーダンスの動作を利用して、特定の条件下でデバイスの一部の機能を停止させたり、省電力モードに切り替えるといった動作を実現することも考えられます。

-- 省電力モードの例
process(inp)
begin
    -- 入力が低い場合、省電力モードに移行
    if inp < "00100000" then
        outp <= "ZZZZZZZZ";  -- 全部のビットをハイ・インピーダンスにする
    else
        outp <= inp;  -- 通常の出力
    end if;
end process;

上記のコードでは、入力が低い値を持つ場合に省電力モードとしてハイ・インピーダンスに切り替えることができます。

これにより、不要な消費電力を削減することが期待できます。

○サンプルコード10:デバッグ用にハイ・インピーダンスを利用するテクニック

VHDLにおいて、デバッグは非常に重要なステップです。

回路設計の過程で、一部の機能やモジュールが正常に動作しているかどうかを確認するために、デバッグ用のテクニックが必要になります。

ハイ・インピーダンスを利用したデバッグ用のテクニックは、特にマルチドライバの状況などで非常に役立ちます。

このコードでは、ハイ・インピーダンスを活用して、特定の条件下でデバッグ情報を出力する方法を表しています。

この例では、デバッグモードが有効の時だけ、特定の出力をハイ・インピーダンスにすることで、デバッグ情報を別のポートに出力する仕組みを表しています。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity debug_hi_z is
    Port ( inp : in  STD_LOGIC_VECTOR(7 downto 0);
           debug_mode : in STD_LOGIC;
           outp : out  STD_LOGIC_VECTOR(7 downto 0);
           debug_out : out STD_LOGIC_VECTOR(7 downto 0));
end debug_hi_z;

architecture Behavior of debug_hi_z is
begin
    process(inp, debug_mode)
    begin
        if debug_mode = '1' then
            outp <= "ZZZZZZZZ";  -- デバッグモード時に主出力をハイ・インピーダンスにする
            debug_out <= inp;   -- 入力をデバッグ出力にそのまま転送
        else
            outp <= inp;        -- 通常の出力
            debug_out <= "ZZZZZZZZ"; -- デバッグ出力をハイ・インピーダンスにする
        end if;
    end process;
end Behavior;

この設計を使用することで、debug_modeが有効(‘1’)の場合、主出力outpはハイ・インピーダンスとなり、デバッグ情報がdebug_outから出力されます。

デバッグモードが無効の場合、通常の出力が行われ、デバッグ出力はハイ・インピーダンスとなります。

デバッグモードを有効にすると、ハイ・インピーダンスの出力outpに接続されている他のモジュールやデバイスへの影響を避けつつ、デバッグ情報を専用のポートから確認することができます。

このように、ハイ・インピーダンスをデバッグ用のテクニックとして活用することで、柔軟なデバッグ環境を構築することができます。

VHDL初心者の方々には、このような応用的なデバッグ方法も知っておくと、複雑なデザインや大規模なプロジェクトでも効率的にデバッグを進めることができます。

実際にFPGAボードなどにこのコードを書き込み、debug_modeを変更して動作を確認すると、デバッグモード時にoutpがハイ・インピーダンスとなり、デバッグ情報がdebug_outから出力されることが確認できます。

逆に、デバッグモードが無効な場合には、inpがそのままoutpに出力される一方、debug_outはハイ・インピーダンスとなります。

また、このデバッグ手法をさらに発展させると、複数のデバッグ情報を切り替えて出力する仕組みや、特定のエラーコードを出力する仕組みなど、さまざまなカスタマイズが考えられます。

例えば、入力データの範囲に応じて異なるデバッグ情報を出力するような設計も可能です。

-- カスタマイズ例:入力データの範囲に応じてデバッグ情報を出力する
process(inp, debug_mode)
begin
    if debug_mode = '1' then
        outp <= "ZZZZZZZZ";
        if inp < "00100000" then
            debug_out <= "00000001"; -- エラーコード1
        elsif inp > "11000000" then
            debug_out <= "00000010"; -- エラーコード2
        else
            debug_out <= "00000000"; -- エラーなし
        end if;
    else
        outp <= inp;
        debug_out <= "ZZZZZZZZ";
    end if;
end process;

このカスタマイズ例では、入力データが特定の範囲にない場合に、エラーコードをデバッグ出力として提供します。

このような応用的なデバッグ手法を駆使することで、より緻密なデバッグやエラーチェックを実現することができます。

●注意点と対処法

VHDLにおいて、ハイ・インピーダンスを適切に利用することは、高品質なデザインを実現するための鍵となります。

しかし、使用する際にはいくつかの注意点が存在します。これらの注意点と、それらを適切に対処するための方法を詳しく解説します。

①複数のドライバからの同時出力

複数のドライバからの同時出力があると、出力の競合が生じる可能性があります。

例えば、あるドライバが’1’を出力し、もう一つのドライバが’0’を出力する場合、どの値が有効であるかが不明確になります。これは、予期しない動作を引き起こす原因となります。

対処法:

出力の競合を避けるためには、複数のドライバが同時に異なる値を出力しないように設計することが必要です。

ハイ・インピーダンスの利用を検討する場合、競合が生じないように注意深く設計を行うことが求められます。

②ハイ・インピーダンス状態の持続時間

ハイ・インピーダンスの状態が長く持続すると、接続されている回路やデバイスの動作が不安定になる可能性があります。

対処法:

必要な期間だけハイ・インピーダンスを維持し、それ以外の期間は定義された論理値を出力するように設計します。

③未接続の入力

VHDLの設計中に、入力が意図的に未接続とされた場合、その入力はハイ・インピーダンス状態となります。

しかし、これが原因で回路の動作が不安定になることがあります。

対処法:

未接続の入力には、明示的に適切なデフォルト値を割り当てることで、不安定な動作を避けることができます。

下記のサンプルコードでは、複数のドライバからの出力競合を避けるための方法を表しています。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity avoid_conflict is
    Port ( sel : in  STD_LOGIC;
           outp : out STD_LOGIC);
end avoid_conflict;

architecture Behavior of avoid_conflict is
begin
    process(sel)
    begin
        if sel = '1' then
            outp <= '1'; 
        else
            outp <= 'Z';  -- ハイ・インピーダンスを出力
        end if;
    end process;
end Behavior;

このコードでは、selの値に応じて、outpに’1’を出力するかハイ・インピーダンス状態にするかを選択しています。

これにより、複数のドライバからの競合を避けることができます。

このコードを動かした場合、selが’1’の時にはoutpは’1’になり、それ以外の場合にはoutpはハイ・インピーダンス状態となります。

●カスタマイズ方法

VHDLにおけるハイ・インピーダンスの利用は、回路の動作や性能を最適化するためのカスタマイズが可能です。

特定の要件や状況に応じて、ハイ・インピーダンスの動作を調整することで、より高品質な設計を実現することができます。

ここでは、ハイ・インピーダンスのカスタマイズ方法について、詳細なサンプルコードを交えながら説明します。

○動的にハイ・インピーダンス状態を制御

システムの動作中に、動的にハイ・インピーダンス状態を制御することが求められる場合があります。

例えば、特定の条件下でのみハイ・インピーダンスを有効にしたいという要件が考えられます。

下記のサンプルコードは、特定の条件下でのみハイ・インピーダンスを出力する方法を表しています。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity dynamic_hi_z is
    Port ( condition : in  STD_LOGIC;
           outp : out STD_LOGIC);
end dynamic_hi_z;

architecture Behavior of dynamic_hi_z is
begin
    process(condition)
    begin
        if condition = '1' then
            outp <= 'Z';  -- ハイ・インピーダンスを出力
        else
            outp <= '0'; 
        end if;
    end process;
end Behavior;

このコードでは、conditionの値が’1’の時にのみ、outpにハイ・インピーダンスを出力しています。

それ以外の場合には、outpに’0’を出力しています。

このコードを実行すると、conditionが’1’の場合、outpはハイ・インピーダンス状態となります。

それ以外の場合には、outpは’0’となります。

まとめ

VHDLにおけるハイ・インピーダンスの利用は、デザインの高品質化や、特定のシステム要件を満たすための強力なツールとなることができます。

適切な設計や注意点を考慮して利用することで、効果的なハードウェアの設計が可能となります。

この記事が参考にんされば幸いです。