質問
ユニバーサルシフト算術演算子を設計しています。 32ビットマルチプレクサ(デコーダー)を使用する以外に、それを達成するためのより良い方法はありますか?
ENTITY isra IS
PORT (
clk: in std_logic;
rst: in std_logic;
di: in std_logic_vector (31 downto 0);
sel: in std_logic_vector (31 downto 0);
res: out std_logic_vector (31 downto 0) := (others => '0')
);
END isra;
PROCESS
BEGIN
WAIT UNTIL clk'EVENT AND clk = '1';
IF rst = '1' THEN
res <= (others => '0');
ELSE
CASE sel IS
when X"00000001" => res <= to_stdlogicvector(to_bitvector(a) sra 1);
when X"00000002" => res <= to_stdlogicvector(to_bitvector(a) sra 2);
...
when X"0000001F" => res <= to_stdlogicvector(to_bitvector(a) sra 31);
when others => res <= (others => '0');
END CASE;
END IF;
END PROCESS;
解決
インデックスを使用しますか?
PROCESS
VARIABLE shift_count : INTEGER RANGE 0 TO 31;
BEGIN
IF rst = '1' THEN
res <= (others => '0');
ELSIF RISING_EDGE(clk) THEN
shift_count := to_integer(sel);
FOR I IN 0 TO 31 LOOP
IF I + shift_count < 32 THEN
res(I) <= din(I + shift_count);
ELSE
res(I) <= din(31); -- for logical shift right, use '0' instead
END IF;
END LOOP;
END IF;
END PROCESS;
このバージョンは、ジェネリックにパラメーター化するのがはるかに簡単です。
VHDLは行動の説明であり、MUXを指定していないことを忘れないでください。コンパイラは、サイズ、速度、パイプラインなどを最適化するかどうかに応じて、さまざまなデザインを生成できます。
5 2:1 Muxesは、これを単一の32:1 Muxよりもはるかに小さな領域に実装できることに注意してください。これがあなたの時計レートを制限するブロックでない場合、それは望ましいかもしれません。
また、あなたに注意してください sel
入力は広すぎるため、5ビットである必要があります。
他のヒント
ループやケースステートメントなしでSRA関数を使用できます。
res <= to_stdlogicvector(to_bitvector(di) sra to_integer(sel));
SELをSTD_LOGIC_VECTORではなく、SELにする必要があることに注意してください。
sel: in unsigned (31 downto 0);
あなたがそれを望まない場合でも、あなたはまだSELを署名しないものにキャストすることができます。また、numeric_bit:
use ieee.numeric_bit.all;
ハードウェアの観点からは、単一のクロックで可変数の位置を右に移動することは、各ビットは、選択に基づいて32の可能な値のいずれかを持つ単一のフリップフロップです。ですから、その観点から、これがあなたがそれをする方法です。
ただし、SEL == 0をケースにして、パススルーにします。論理的には、それはすべてをゼロに設定するよりも理にかなっています。
所属していません StackOverflow