VHDL で定数とジェネリック マップを使用する方法
モジュールを作成することは、コードを再利用する優れた方法ですが、多くの場合、設計全体でより小さなバリエーションを持つ同じモジュールが必要になります。これがジェネリックとジェネリック マップの目的です。これにより、モジュールの特定の部分をコンパイル時に構成可能にすることができます。
定数は、同じ値を何度も入力することを避けたい場合に使用されます。これらは、コンパイル時に信号ベクトルのビット幅を定義するために使用でき、一般的な定数にもマッピングできます。定数は、コード内の任意の場所で信号と変数の代わりに使用できますが、それらの値はコンパイル後に変更できません。
このブログ投稿は、基本的な VHDL チュートリアル シリーズの一部です。
前のチュートリアルでは、バス幅が 8 ビットの 4 入力マルチプレクサ モジュールを作成しました。しかし、バス幅が異なる同様の MUX も必要な場合はどうでしょうか?コードをコピーして新しいモジュールに貼り付け、番号を変更する唯一の解決策はありますか?
幸いなことに、いいえ。
次の構文を使用して、VHDL で定数を作成できます。constant <constant_name> : <type> := <value>;
定数は、VHDL ファイルの宣言部分で信号と共に宣言するか、プロセスで変数と共に宣言できます。
generic を使用して、エンティティを介して定数をモジュールに渡すことができます。 キーワード。汎用定数を受け入れるモジュールのエンティティを作成するための構文は次のとおりです。entity <entity_name> is
generic(
<entity_constant_name> : <type> [:= default_value];
...
);
port(
<entity_signal_name> : in|out|inout <type>;
...
);
end entity;
別の VHDL ファイルでジェネリック モジュールをインスタンス化するための構文は次のとおりです。<label> : entity <library_name>.<entity_name>(<architecture_name>)
generic map(
<entity_constant_name> => <value_or_constant>,
...
)
port map(
<entity_signal_name> => <local_signal_name>,
...
);
エクササイズ
このビデオ チュートリアルでは、VHDL でジェネリック定数を使用してモジュールを作成およびインスタンス化する方法を学習します。
汎用 MUX テストベンチの最終的なコード :
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity T16_GenericMapTb is
end entity;
architecture sim of T16_GenericMapTb is
constant DataWidth : integer := 8;
signal Sig1 : signed(DataWidth-1 downto 0) := x"AA";
signal Sig2 : signed(DataWidth-1 downto 0) := x"BB";
signal Sig3 : signed(DataWidth-1 downto 0) := x"CC";
signal Sig4 : signed(DataWidth-1 downto 0) := x"DD";
signal Sel : signed(1 downto 0) := (others => '0');
signal Output : signed(DataWidth-1 downto 0);
begin
-- An Instance of T16_GenericMux with architecture rtl
i_Mux1 : entity work.T16_GenericMux(rtl)
generic map(DataWidth => DataWidth)
port map(
Sel => Sel,
Sig1 => Sig1,
Sig2 => Sig2,
Sig3 => Sig3,
Sig4 => Sig4,
Output => Output);
-- Testbench process
process is
begin
wait for 10 ns;
Sel <= Sel + 1;
wait for 10 ns;
Sel <= Sel + 1;
wait for 10 ns;
Sel <= Sel + 1;
wait for 10 ns;
Sel <= Sel + 1;
wait for 10 ns;
Sel <= "UU";
wait;
end process;
end architecture;
汎用 MUX モジュールの最終的なコード :
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity T16_GenericMux is
generic(DataWidth : integer);
port(
-- Inputs
Sig1 : in signed(DataWidth-1 downto 0);
Sig2 : in signed(DataWidth-1 downto 0);
Sig3 : in signed(DataWidth-1 downto 0);
Sig4 : in signed(DataWidth-1 downto 0);
Sel : in signed(1 downto 0);
-- Outputs
Output : out signed(DataWidth-1 downto 0));
end entity;
architecture rtl of T16_GenericMux is
begin
process(Sel, Sig1, Sig2, Sig3, Sig4) is
begin
case Sel is
when "00" =>
Output <= Sig1;
when "01" =>
Output <= Sig2;
when "10" =>
Output <= Sig3;
when "11" =>
Output <= Sig4;
when others => -- 'U', 'X', '-', etc.
Output <= (others => 'X');
end case;
end process;
end architecture;
[実行] を押してタイムラインを拡大した後の ModelSim の波形ウィンドウ:
分析
バス幅を設定可能な MUX モジュールを作成しました。現在、バス幅はテストベンチ ファイル内の 1 か所でのみ指定されています。これを簡単に変更して、異なるバス幅の MUX を作成できます。
波形を前のチュートリアルの波形と比較すると、動作が同じであることがわかります。これは、コードの動作をまったく変更していないためです。
テイクアウト
- 定数を使用して、複数の場所で値をハードコーディングすることを回避できます
- ジェネリックを使用してモジュールの適応性を高める
次のチュートリアルに進む »
VHDL