for ループで発生する可能性のあるエラーは、普遍的な整数の境界が数値リテラルまたは属性でなければならないということを伝えているはずです。2008 年版の VHDL で緩和されたルール。
ポート定義を使用して、合成に適した記述を生成することはそれほど難しくありません。din'reverse_range を使用するか、ループに必要な範囲で配列サブタイプを作成するか、暗黙のループ変数の型を整数として指定できます。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity demux is
generic ( size: positive := 3);
port (
din: in std_logic_vector (2**size-1 downto 0);
sel: in std_logic_vector (size-1 downto 0);
y: out std_logic_vector (2**(size*2)-1 downto 0)
);
end entity;
architecture foo of demux is
begin
PROC:
process(sel, din)
-- subtype sel_range is std_logic_vector (0 to 2**size-1);
begin
SLCT:
-- for i in sel_range'range loop
for i in integer range 0 to 2**size-1 loop
if i = to_integer(unsigned(sel)) then
y(i*din'length+din'length-1 downto i*din'length) <= din;
else
y(i*din'length+din'length-1 downto i*din'length) <= (others => '0');
end if;
end loop;
end process ;
end architecture;
このコードは、VHDL-93 ライブラリの numeric_std と unsigned への型変換を使用して と比較i
しsel
ます。シノプシス ライブラリを簡単に使用できます。ループを使用し、y
インデックス範囲に値を割り当てると、合成が可能になります。
for ループの反復は、ハードウェアで (並列に) 複製されます。の割り当てられたスライスは、静的であるおよびにy
依存しています。i
din'length
この例では、分析、詳細化、およびシミュレーションを行います。

'y' 値をラッチし、 にy
基づいてスライスを順次更新するつもりだった場合sel
、単純din
にプロセス機密リストを除外するだけでは十分ではありません。これは合成に適した構造ではなく、 の任意のイベントで動作しますsel
。din
プロセス機密リストに追加したことに注意してください。アドレス可能なラッチまたはレジスタを使用する場合は、ゲートを介してイネーブルを生成する必要がある場合、要素の立ち上がり時間と立ち下がり時間sel
が必ずしも等しくないため、クロックまたは個別のラッチ イネーブルが必要です。実際のハードウェア実装でグリッチが発生する可能性があります。(あなたの言語「...その場所に保存されている値に正しい出力を調整する」は不明です)。
ポート宣言は、演算子の優先順位に基づいて実際に必要な数よりも多くの括弧の良い例です。
また、長さが不必要にビットdin
数に結び付けられていることに気付くかもしれません。これが機能する理由です。はい、長さと長さの間に関係がある必要があり、長さは に関連しています。 そうでなければそうなるでしょう。これは、 のサイズの 2 番目のジェネリックを意味します。また、for ループ ステートメントの代入スライス境界の計算も変更されます。sel
din'reverse_length
din
y
y
size
y'LEFT
2**size*din'LENGTH-1
din
y