列挙型を使用することもできますが、最良の方法は、整数ではなく列挙型によってインデックス付けされた std_logic の独自のベクトルを宣言することです。
しかし、 vector の代わりに record の方がよいでしょう:
type Control_Signals is record
Clk : std_logic,
En : std_logic,
Foo : std_logic,
Bar : std_logic,
Baz : std_logic
end record;
詳細については、コメントに従って編集してください。
std_logic_vector (および一般的な VHDL の型システム) の想像を絶する使用は、VHDL を妨げています...
これが最上位エンティティの場合、std_logic_vector ポートを使用すると、最上位テストベンチで合成可能なデザインを合成後のネットリストで置き換えることができます。または、 std_logic_vector ポートを主張する時代遅れのコーディング スタイル ガイドラインに準拠する必要がある場合もあります。
しかし、他の状況では、パッケージでレコードを宣言し、設計全体でそのパッケージを使用し、レコード タイプのポートを作成します。パッケージには関数to_slv
とto_control_sigs
、std_logic_vectors が実際に必要な場合 (うまくいけばまれですが) が含まれている必要があります。
同じことが列挙にも当てはまります。
type Controls is (Clk, En, Foo, Bar, Baz);
type Control_Signals is array(Controls) of std_logic;
My_Bus_Ctrl : Control_Signals := (Clk => '1', En => '1', others => '0');
My_External_SLV_Port <= std_logic_vector(My_Bus_Ctrl);
そしてもちろん、列挙は C よりも少し強力です。それらを配列インデックス型として使用するだけでなく、それらをループすることもできます。これにより、列挙を更新するたびにループが整列されます!
列挙によってインデックス付けされたレコードまたは配列はどちらも機能します。オブジェクト指向の実践に沿った、よりクリーンなレコードを好みます。
どちらの場合でも、エンティティ ポートに使用すると、はるかに便利になります。発信バス信号 (アドレスとデータを含む) 用に 1 つのレコード (または配列!) を宣言し、着信信号用に別のレコードを宣言します。これは、1 つのポートで方向を混在させることができないためです... (最近の FPGA には双方向信号はありません。したがって、3 番目のポートは必要ありません)。
これで、デザインはバス構造の変更から保護されました。アドレス幅の変更または割り込み信号の追加は、レコード宣言と実際のユーザーのみを変更します。階層全体に新しい信号を追加する必要はありません...