左右のシフト機能を備えた 16 ビット バレル シフターを構築しようとしています。私がやりたいと思うことを実行するようにコードを構成する方法に問題があります。
方向を決定するオペコード入力、シフトする入力ベクトル、出力ベクトル、および 4 ビットの位置ベクトルがあります。
位置ベクトルを使用して、シフトの「レベル」を設定しています。位置(0)を確認したいのですが、1に設定されていれば1つずらします。次に、position(1) を確認し、2 ポジション、position(3) 4 ポジション、position(3) 8 ポジションをシフトします。
位置ベクトルのすべての位置を実行し、ビットを順次シフトすると、最終的にすべてのオプションが取得されるはずです。この方向が適切に機能する場合、他のオペコードを追加します。
アーキテクチャの中間ベクトルの割り当てに行き詰まっています。適切な方法がどうあるべきかわからず、グーグルで何も見つかりません。おそらくケースシステムの方がうまくいくでしょう。
entity eds_shifter is
port ( a : in bit_vector(15 downto 0) ; --input
pos : in bit_vector(3 downto 0); -- position
opc : in bit_vector(3 downto 0); -- opcode
y : out bit_vector(15 downto 0) --output
);
end entity eds_shifter ;
architecture behavior of eds_shifter is
begin
process(a,pos,opc) -- input vectors
signal s1,s2,s3,s4 : bit_vector(15 downto 0); -- intermediate steps
begin
s1 <= a(14 downto 0) & '0' when pos(0) = '1' and opc = "0000" else -- shifting left by one
s1 <= a when pos(0) = '0' and opc = "0000" else -- carryover vector to next shift position
s2 <= s1(13 downto 0) & '0' when pos(1) = '1' and opc = "0000" else -- shift previous vector by 2
s2 <= s1 when pos(1) = '0' and opc = "0000" else
s3 <= s2(12 downto 0) & '0' when pos(2) = '1' and opc = "0000" else -- shift another 4 places
s3 <= s2 when pos(2) = '0' and opc = "0000" else
s4 <= s3(7 downto 0) & '0' when pos(3) = '1' and opc = "0000" else -- shift another 8 places
s4 <= s3 when pos(3) = '0' and opc = "0000" else
y <= s4 when opc = "0000";
end process;
end architecture behavior;
エラーメッセージ
** Error: */02/eds_shifter.vhd(14): Illegal sequential statement.
** Error: */02/eds_shifter.vhd(15): Type error resolving infix expression "<=" as type std.standard.bit_vector.
編集
詳細な回答ありがとうございます。一般的なシフト関数が組み込まれていることは理解していますが、それを自分で実装する方法を理解しようとしています。
bit_vector についてのヒントをありがとう。私が理解していることから、ビット型は、入力がマルチソースでないことが確実な場合にのみ使用できます。この場合はおそらく問題ないはずですが、先に進んで将来のために心に留めておきます。
やってみたいコンセプトは健全だと思います。1 の位置の各ビットをチェックし、最後に適切な量だけシフトすると、シフトされたビット数は位置ベクトルの値に等しくなります。
a = "1111 1111 1111 1111" および pos = "1010" なので、小数点以下 10 桁シフトする必要があります。したがって、最初の反復を実行しても変化はありません。2 回目は 2 ビットシフトし、3 回目は 0 ビットだけシフトし、4 回目は 8 ビットシフトして合計 10 ビットシフトし、a="1111 1100 0000 0000" を取得します。 .
私の問題は、特定のシフト操作に関するものではありません (おそらく間違っているので、別の方法を使用する場合は、現在、自分のアイデアを実装する方法に興味があります)、ベクトルを更新してチェックするコードを書くことが問題です。位置ベクトルの次の位置。デルタサイクルと感度リストについてあなたが投稿したものを見ていました。VHDL は、プロセッサを介して波及する操作の観点から現実世界を記述しなければならないため、混乱を招く可能性があります。また、標準的なプログラミングとは異なる考え方が必要です。
以下のコードを試してみましたが、テスト ベンチで 1 回だけ変更およびシフトされます。位置のすべての組み合わせを実行するテストベンチをセットアップしましたが、次のコードでは pos = 1000 でのみシフトし、その後 8 桁シフトします。最後の if ステートメントだけでなく、各 if ステートメントでコードを強制的にチェックすることはありますか?
entity eds_shifter is
port ( a : in bit_vector(15 downto 0) ; --input
pos : in bit_vector(3 downto 0); -- position
opc : in bit_vector(3 downto 0); -- opcode
y : out bit_vector(15 downto 0) --output
);
end entity eds_shifter ;
architecture behavior of eds_shifter is
begin
process(a,pos,opc) -- input vectors
begin
if pos(0) = '1' and opc = "0000" then -- shifting left by one
y <= a(14 downto 0) & "0";
else
y <= a;
end if;
if pos(1) = '1' and opc = "0000" then -- shifting left by two
y <= a(13 downto 0) & "00";
else
y <= a;
end if;
if pos(2) = '1' and opc = "0000" then -- shifting left by four
y <= a(11 downto 0) & "0000";
else
y <= a;
end if;
if pos(3) = '1' and opc = "0000" then -- shifting left by eight
y <= a(7 downto 0) & "00000000";
else
y <= a;
end if;
end process;
アーキテクチャの動作を終了します。
テストベンチ
entity eds_shifter_tb is
end eds_shifter_tb;
architecture behavior of eds_shifter_tb is
signal opc: bit_vector(3 downto 0);
signal pos: bit_vector(3 downto 0);
signal Y : bit_vector (15 downto 0);
signal a: bit_vector (15 downto 0);
begin
dut: entity work.eds_shifter(behavior)
port map(opc => opc,
pos => pos,
Y => Y,
a => a); -- assigns all ports to entity spec
a <= (others => '1'),
(others => '1') after 30 ns;
opc <= "0000",
"0001" after 30 ns;
pos <= "0000",
"0001" after 2 ns,
"0010" after 4 ns,
"0011" after 6 ns,
"0100" after 8 ns,
"0101" after 10 ns,
"0110" after 12 ns,
"0111" after 14 ns,
"1000" after 16 ns,
"1001" after 18 ns,
"1010" after 20 ns,
"1011" after 22 ns,
"1100" after 24 ns,
"1101" after 26 ns,
"1110" after 28 ns,
"1111" after 30 ns,
"0000" after 32 ns,
"0001" after 34 ns,
"0010" after 36 ns,
"0011" after 38 ns,
"0100" after 40 ns,
"0101" after 42 ns,
"0110" after 44 ns,
"0111" after 46 ns,
"1000" after 48 ns,
"1001" after 50 ns,
"1010" after 52 ns,
"1011" after 54 ns,
"1100" after 56 ns,
"1101" after 58 ns,
"1110" after 60 ns,
"1111" after 62 ns;
end behavior;