Vhdlでの「downto」と「to」の違いが理解できません。
オンラインの説明をいくつか見ましたが、それでも理解できません。誰かが私のためにそれをレイアウトできますか?
1つは上昇し、もう1つは下降します。
-- gives 0, 1, 2, 3:
for i in 0 to 3 loop
-- gives 3, 2, 1, 0:
for i in 3 downto 0 loop
プロセッサを使用する場合、リトルエンディアンシステムの場合は「downto」を使用でき、ビッグエンディアンシステムの場合は「to」を使用します。
例えば、
signal t1 : std_logic_vector(7 downto 0); --7th bit is MSB and 0th bit is LSB here.
そして、
signal t2 : std_logic_vector(0 to 7); --0th bit is MSB and 7th bit is LSB here.
両方のタイプの表現を自由に使用できます。デザインの他の部分が適切に記述されていることを確認する必要があります。
これは post が別のことを言っています:
「ビッグエンディアン(またはリトルエンディアン)という用語は、バイト指向のプロセッサでのバイトオーダーを示し、VHDLビットベクトルには適合しません。専門用語は、昇順および降順の配列範囲です。符号付きや符号なしなどの定義済みの数値型は、降順の範囲に制限されます。慣例により。"
したがって、この答えは混乱する可能性があります...
私が見つけた興味深いオンラインリファレンスは here です。ここで、「配列の割り当て」セクションで、次のように読むことができます。
2つの配列オブジェクトは、同じタイプで同じサイズである限り、互いに割り当てることができます。割り当てはインデックス番号ではなく、位置によって行われることに注意してください。言語内で定義される最上位ビットの概念はありません。これは、配列を使用するユーザーによってひどく解釈されます。配列の割り当ての例を次に示します。
次の宣言で:
....
SIGNAL z_bus: BIT_VECTOR (3 DOWNTO 0);
SIGNAL a_bus: BIT_VECTOR (1 TO 4);
....
z_bus <= a_bus;
と同じです:
z_bus(3) <= a_bus(1);
z_bus(2) <= a_bus(2);
z_bus(1) <= a_bus(3);
z_bus(0) <= a_bus(4);
観察:
1)「downto」と「to」の違いは、ビットの配列を表すためだけでなく、各ビットが独立した振る舞いを持つだけでなく、整数を表すためにビットベクトルを使用したいときに現れます。次に、加算器、乗算器などの回路で数値が処理される方法のために、ビットの有意性に違いがあります。
この間違いなく特殊なケースでは、0 <x <yと仮定しますこれは通常の規則ですx to y
を使用する場合、xは最上位ビット(MSB)であり、yは最下位ビットです(LSB)。逆に、y downto x
を使用する場合、yはMSB、xはLSBです。整数を表すビットベクトルの違いは、「to」または「downto」のどちらを使用しても、MSBのインデックスが最初に来るという事実に由来します(「to」を使用する場合、最初のインデックスは2番目のインデックスより小さい) 「downto」を使用する場合はさらに大きくなります)。
2)y downto x
はyがMSBを意味し、逆にx to y
はxがMSBであることを意味する既知の規則であり、通常は実装されているIPコアで使用されており、無料で使用できます。また、ビットベクトルと整数の間で変換するときに、IEEE VHDLライブラリで使用される規則だと思います。しかし、たとえば、y downto x
形式の入力ビットベクトルを使用してLSBとしてyを使用する、またはxが使用されるx to y
形式の入力ビットベクトルを使用する32ビット加算器の構造モデリングについては、何も難しいことはありません。 LSBとして...
それでも、ビット位置は2の累乗に数字を乗算して数値を合計したものに相当するため、負でない整数にはx downto 0
の表記を使用するのが妥当です。これは、整数を含む他のほとんどのプラクティスでも拡張されているようです。
3)ビットオーダーには何もないエンディアンネスと関係があります。エンディアンはバイト順を指します(まあ、バイト順はビット順の形式です...)。エンディアンネスは、命令セットアーキテクチャ(ISA)レベルで公開されている問題です。つまり、異なるオペランドサイズ(ワード、バイト、ダブルワードなど)で同じメモリアドレスにアクセスする可能性があるプログラマに見えます。 (質問のように)実装のビット順序はISAレベルでは決して公開されません。相対ビット位置のセマンティクスのみがプログラマーに見えます(例えば、左シフト論理は実際に実装できます)レジスタを右にシフトすることで、ビットの意味が実装で逆になります。
(これについて言及している回答が投票されたのは驚くべきことです!)
ベクトル型では、左端のビットが最も重要です。したがって、0 to n
の範囲の場合、ビット0
はmsbであり、n downto 0
の範囲のビットn
はmsbです。
これは、ビッグエンディアンとリトルエンディアンの両方のビット順序を使用して頭をまっすぐに保つIPを組み合わせるときに便利です。
たとえば、Microblazeはビッグエンディアンで、0
をmsbとして使用します。私はリトルエンディアンの外部デバイスに1つを接続したので、外部ピンで15 downto 0
を使用し、それらをインターフェイスコアのマイクロブレーズエンドの16 to 31
に再マップしました。
VHDLでは、これについて明示する必要があるため、le_vec <= be_vec;
を直接実行することはできません。
ほとんどの場合、コンポーネントをインスタンス化するときにビット順序を混同しないようにします。 LSBをX(0)
に格納し、X(0)
にMSBが含まれることを期待するコンポーネントに渡したいとは思わないでしょう。
実際には、ビットのベクトル(STD_LOGIC_VECTOR(7 DOWNTO 0)
またはUNSIGNED(31 DOWNTO 0)
)にはDOWNTO
を使用し、RAM(TYPE data_ram IS ARRAY(RANGE NATURAL<>) OF UNSIGNED(15 DOWNTO 0); SIGNAL r : data_ram(0 TO 1023);
)にはTO
を使用する傾向があります。積分カウンター(SIGNAL counter : NATURAL RANGE 0 TO max_delay;
)。
@ KerrekSBの答え を拡張するには、プライオリティエンコーダーを検討してください。
ENTITY prio
PORT (
a : IN STD_LOGIC_VECTOR(7 DOWNTO 1);
y : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
);
END ENTITY;
ARCHITECTURE seq OF prio IS
BEGIN
PROCESS (a)
BEGIN
y <= "000";
FOR i IN a'LOW TO a'HIGH LOOP
IF a(i) = '1' THEN
y <= STD_LOGIC_VECTOR(TO_UNSIGNED(i, y'LENGTH));
END IF;
END LOOP;
END PROCESS;
END ENTITY;
ループの方向(TO
またはDOWNTO
)は、複数の入力がアサートされたときに何が起こるかを制御します(例:a := "0010100"
)。 TO
を使用すると、最も大きい番号の入力が優先されます(y <= "100"
)。 DOWNTO
を使用すると、最も小さい番号の入力が優先されます(y <= "010"
)。これは、プロセスの最後の割り当てが優先されるためです。ただし、EXIT FOR
で優先度を決定します。
バイナリの順序を維持することが重要な場合(たとえば、文字を保持する8ビットの信号)には「downto」を使用し、信号が必ずしも必要でない場合に「to」を使用するのが良いルールであると教えられました相互接続たとえば、信号の各ビットがオン/オフするLEDを表す場合。
4ビットの「to」と4ビットの「to」を接続すると、次のようになります。
sig1(3から0まで)<= sig2(0から3)
------- 3 -------------------- 0
------- 2 -------------------- 1
------- 1 -------------------- 2
------- 0 -------------------- 3
代わりに信号の一部をとるsig1(2 downto 1)<= sig2(0 to 1)
------- 2 -------------------- 0
------- 1 -------------------- 1
上記の答えには何も問題はありませんが、私は常に両方の提供が2つのパラダイムをサポートすることであると信じてきました。
最初は数値表現です。私が7249と書いた場合、あなたはすぐにそれを7000と解釈します。最上位の桁が左側にある、左から右に読む数字。これは「下へ」の場合です。
2つ目は時間表現であり、常に左から右に進む時間を考えます。クロックでは、時間の経過とともに数値が増加し、2は常に1に従います。ここでは、ビットの表現に関係なく、ビットの順序を左から右に時間の昇順で自然に書き込みます。たとえばRS232では、スタートビットで始まり、その後に8データビット(LSBが最初)、ストップビットが続きます。ここでは、MSBが右側にあります。 「to」の場合。
前述のとおり、最も重要なことは、それらを任意に混合しないことです。 RS232ストリームをデコードする際に、時間順に受信したビットをMSBファーストのバイトに変換するだけですが、これはルールというよりも例外です。