14

再利用可能なバレル シフターを作成しようとしています。ビットの入力配列を受け取り、それらを特定の数の位置 (別の入力によって決定される) だけシフトします。モジュールをパラメータ化して、任意のn.

必要な選択行の数はn--> によって決定されます。つまり、SHIFT_CNT = log2(NUMBITS-1)+1以下のコードです。std_logic_vectorまたは以外のポートを持つことは、私の組織では (全体的に考えても) 悪い形式と考えられているため、選択行の数にstd_logica を使用しました。入力ジェネリックに基づいてstd_logic_vectorの長さを調整する必要があります。std_logic_vector2 番目のジェネリックを使用せずにこれを行う方法はありますか? この投稿を見たことがありますが、ジェネリックを扱っていません。この投稿では、ジェネリックを完全に排除するか、ログ値をジェネリックとして使用します。これは、将来のユーザーにとって直感的ではありません (またINPUT、2 の累乗でない場合に問題が発生する可能性があります)。

以下の宣言SHIFT_CNTは間違いなく間違っています。2 番目のジェネリックを使用せずにエンティティ宣言で長さを自動的に生成する方法はありますか?

entity BarrelShifter is

generic ( NUMBITS : integer :=8);                                                   
Port    ( INPUT     : in   std_logic_vector (NUMBITS-1 downto 0);                
          OUTPUT    : out  std_logic_vector (NUMBITS-1 downto 0);                
          SHIFT_CNT : in   std_logic_vector ((NUMBITS-1)'length downto 0)                 
        );                                                               
end BarrelShifter;
4

5 に答える 5

21

数学ライブラリを使用して、対数結果の log2 と ceil を計算し、SHIFT_CNT のサイズを宣言できます。

use IEEE.math_real.all;

または特定の機能

use IEEE.math_real."ceil";
use IEEE.math_real."log2";

たとえば、値aのclog2を計算したい

result := integer(ceil(log2(real(a))));

これらの関数を使用して paramater を計算するだけの場合、コードは合成可能です (私はそれを行いました)

エンティティで使用したくない場合は、これらの関数を使用してライブラリまたはジェネリックで宣言できます。

于 2012-10-06T07:18:38.397 に答える
9

次のように、ライブラリに log2 関数を作成できます。

   function f_log2 (x : positive) return natural is
      variable i : natural;
   begin
      i := 0;  
      while (2**i < x) and i < 31 loop
         i := i + 1;
      end loop;
      return i;
   end function;

ライブラリがインポートされている場合は、次のようにポートを指定できます。

shift_cnt : in std_logic_vector(f_log2(NUMBITS)-1 downto 0)

これはやや醜いソリューションですが、リソースを使用しません (関数が純粋で、コンパイル時にすべての入力が既知であるため)。

私は通常これを行いますが、言及しているようにログ値をジェネリックとして指定することを好むかもしれません。

于 2012-10-05T17:38:45.153 に答える
5

2 つの代替アプローチ:

逆方向に作業してgenericasshift_bitsを取得し、そこから入力ベクトルと出力ベクトルの幅を計算できます。

generic ( shift_bits: integer :=3);                                                   
Port    ( INPUT     : in   std_logic_vector ((2**shift_bits)-1 downto 0);                
          OUTPUT    : out  std_logic_vector ((2**shift_bits)-1 downto 0);                
          SHIFT_CNT : in   std_logic_vector (shift_bits-1 downto 0)                 
        ); 

または、カウントを数値として扱います。

generic ( NUMBITS : integer :=8);                                                   
Port    ( INPUT     : in   std_logic_vector (NUMBITS-1 downto 0);                
          OUTPUT    : out  std_logic_vector (NUMBITS-1 downto 0);                
          SHIFT_CNT : in   integer range 0 to numbits-1                 
        );  

そして、ツールにそれを理解させます。

于 2012-10-08T12:51:33.367 に答える