2

左右のシフト機能を備えた 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;
4

3 に答える 3

1

コードにはいくつかの問題があります。

  • whenシーケンシャル ステートメントとして使用できず (処理中、VHDL-2008 より前)、そのelse部分もステートメントのように見えますが、これは正しい構文ではありません。

  • signal手続き中に宣言することはできません

  • の新しい値は、signal利用可能になる前にデルタ サイクルを取るs*ため、値が波及するためには感度リストにある必要があります。

  • VHDL は、ホーム ビルドの代わりに使用する必要がある標準のシフト関数を提供します (これは間違っているようにも見えます)。VHDL シフトインフィックス演算子 (VHDL-2008 より前) は予期しない結果をもたらすことが知られているため、代わりに関数を使用してください。詳しくはこちらをご覧 ください

したがって、これに基づいて、プロセスを含むコードを次のように更新できます。

library ieee;
use ieee.numeric_bit.all;

architecture behavior of eds_shifter is
begin
  process(a, pos, opc)                                                   -- input vectors
  begin
    if opc = "0000" then  -- Shift left
      y <= bit_vector(shift_left(unsigned(a), to_integer(unsigned(pos))));
    else  -- Assuming shift right
      y <= bit_vector(shift_right(unsigned(a), to_integer(unsigned(pos))));
    end if;
  end process;
end architecture behavior;

または parallel を使用するとwhen、 process を次のように置き換えることができます。

y <= bit_vector(shift_left(unsigned(a), to_integer(unsigned(pos)))) when opc = "0000" else
     bit_vector(shift_right(unsigned(a), to_integer(unsigned(pos))));

Notebit_vectorは広く使用されていないため、 std_logic_vector代わりに使用するように更新することを検討してください。これにより、コードは次のようになります。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity eds_shifter is
  port (a   : in  std_logic_vector(15 downto 0);  --input
        pos : in  std_logic_vector(3 downto 0);   -- position
        opc : in  std_logic_vector(3 downto 0);   -- opcode
        y   : out std_logic_vector(15 downto 0)   --output
        );
end entity eds_shifter;

architecture behavior of eds_shifter is
begin

  y <= std_logic_vector(shift_left(unsigned(a), to_integer(unsigned(pos)))) when (opc = "0000") else
       std_logic_vector(shift_right(unsigned(a), to_integer(unsigned(pos))));

end architecture behavior;
于 2014-05-27T14:52:37.880 に答える