ビッグエンディアンをリトルエンディアンに変換する小さなプログラムを書きたいと思います。したがって、forループを使用する必要があります。8ビット(1バイト)ごとに切り替えを行いたいので、ある種のモジュロを使用する必要があります。私は事前定義されたメソッドを使用するのが好きではないので、できるだけハードウェアとして記述したいと思います。したがって、イテレータ変数にアクセスして、最後の3ビットがゼロかどうかを確認したいと思いました。したがって、8回の反復が行われることがわかります。サディ、私はエラーメッセージを受け取ります:
インデックス名プレフィックスタイプnaturalは配列タイプではありません
私のコードは次のとおりです。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity TOP is
Port ( INPUT : in STD_LOGIC_VECTOR (32 downto 0);
CLK : in STD_LOGIC;
OUTPUT : out STD_LOGIC_VECTOR (32 downto 0));
end TOP;
architecture Behavioral of TOP is
begin
S: process(CLK)
begin
if rising_edge(CLK) then
for I in INPUT' range loop
--every 8 bit
if I(3 downto 0) = "000" then
OUTPUT(OUTPUT'left -I*8 downto OUTPUT'left - (I+1)*8) <= INPUT((I+1)*7 downto I*7);
end if;
end loop;
end if;
end process S;
end Behavioral;
明らかな答えは次のようになりますif I mod 8 = 0 then
が、あなたはそれをしたくありません。
この行で行っているのif I(3 downto 0) = "000" then
は、抽象化のレベル(整数)と、ビットのバッグとしての整数の低レベル表現を混合することです。または厳密に言えば、インデックス可能な型、つまり配列です。
皮肉なことに、エンディアンを含め、有効な場合と無効な場合がある整数の表現についての仮定を行うため、これは悪い考えです。したがって、VHDLではそれができません。
できることは、整数の表現に明示的に「変換」することです。ここで、どのビットが何に対応するかを確認し、抽象ではなく、その具象表現に対して低レベルの操作を実行できInteger
ます。(使用しているコンピューターがとにかくその表現を持っていると仮定すると、「変換」には時間やハードウェアリソースのペナルティはありません)。
そのような表現には2つの標準があります。でnumeric_std
、ライブラリと呼ばれるsigned
と、unsigned
それぞれ。「符号付き」のものは明示的に2の補数であり、unsigned
単純です。どちらもstd_logic型の配列であるため、インデックス付けが可能です。
use IEEE.numeric_std.all;
そして、あなたはこのパッケージのソースを読むことができるので、作る仮定はありません。(または、代わりに必要な規則を具体化した別のパッケージを作成することもできます。しかし、誰もそれを行いません...)
したがって、ループ変数を5ビットに変換し、unsigned
それにインデックスを付けることができます...
if to_unsigned(I,5)(2 downto 0) = "000" then
配列の長さが一致しないため、元の比較では常にFalseが返されることに注意してください。
最後に、合成ツールは愚かではありません。mod
とにかく、2の累乗で明らかに最適化を安全に行います。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加