0

ビヘイビア タイプのラビン ミラー アルゴリズムの素数性テストを設計しました。関数を使用してモジュールを作成しました。残念ながら、Quartus を介して Altera Kit で合成しようとしたときに、関数が合成されていないことに気付きました。ここでプログラム全体を書きますが、これは私の上級設計プロジェクトであるため、構造化に変更するためのヒントをいくつか教えてください。これが私のプログラムです:

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

 entity PrimeTest is
 port( N: in integer;
 Test1 : out std_logic);
 end PrimeTest;  

  Architecture Behavior1 of PrimeTest is


  function integer_binary (b1:std_logic_vector(31 downto 0)) return integer is
  variable a: integer:=0;
  variable i: integer;
   begin
    i:=0;

     while (i<32) loop
if b1(i) = '1' then
a:=a+2**i; 
end if;
i:=i+1;   
end loop;
     return a;
    end integer_binary;

       function integer_binary1 (b1:std_logic) return integer is
        variable a: integer;

       begin
if b1 = '1' then
a:= 1; 
else
  a:=0;
end if;
     return a;
     end integer_binary1;

     function binary1 (int1:integer) return std_logic_vector is
     variable int2: integer;
     variable a:std_logic_vector(31 downto 0);
  variable i: integer;

   begin
   int2:=int1;
  i:=0;
 while (i<32) loop    
  if (int2 mod 2 = 0) then
    a(i):='0';
  else
    a(i):='1';
  end if;
  i:=i+1;
    int2:=int2/2;
  end loop;
  return a;
  end binary1;

 function mul_mod (x1,y1,m1: std_logic_vector (31 downto 0)) return std_logic_vector is
variable p1: std_logic_vector (31 downto 0);
variable k: integer;
variable n: integer;
variable i: integer;
 variable j: std_logic_vector (31 downto 0);
 begin
n:=32;
i:=31;
p1:="00000000000000000000000000000000";
while(i>=0) loop

  p1:=binary1((integer_binary(p1))*2);

j:=binary1((integer_binary(y1))*((integer_binary1 (x1(i)))));

p1:=binary1((integer_binary(p1))+((integer_binary (j))));

if (p1 >= m1) then
  p1:=binary1(((integer_binary(p1))-(integer_binary (m1))));
end if;

    if (p1 >= m1) then
  p1:=binary1(((integer_binary(p1))-(integer_binary (m1))));
end if;
i:=i-1; 

end loop;
return p1;
end mul_mod;



 FUNCTION modexp3 (exp_m,exp_n: integer; 
                      exp_e: std_logic_vector(31 downto 0)) return integer is 
                 variable s:integer; 
                  variable result: integer:=1;
                        begin
    S := exp_m;

   L1: for I in 0 to 31 loop

    I2:    if (exp_e(I) = '1') then
        result := integer_binary(mul_mod(binary1(result),binary1(s),binary1(exp_n)));
       S := integer_binary(mul_mod(binary1(s),binary1(s),binary1(exp_n)));
   else
       S := integer_binary(mul_mod(binary1(s),binary1(s),binary1(exp_n)));
   end if I2;

    end loop L1 ;
    return result; 
  end modexp3;


 FUNCTION park1 (in_seed1,max1: integer) return integer is 
                 variable hi:integer;
                 variable lo:integer; 
                  variable out_seed:integer;
                  variable test:integer;
                  variable random1: integer;
                   variable rejected: integer;
                   variable a:integer:=16807;
                  variable m:integer:=2147483647;
                  variable q: integer:=127773;
                  variable r: integer:=2836;
                  variable seed:integer;

                        begin
                          seed:=in_seed1;

              for en in 0 to 1 loop
                if (en = 0) then
                  hi:=in_seed1 / q;
                 else
                  hi:=out_seed / q;
               end if;

lo:=in_seed1 mod q;
test:=((a*lo) - (r*hi));

if test > 0 then
Out_seed:= test;

else
Out_seed:= test + m;

    end if;
  end loop;
 random1:=out_seed mod max1;
 if random1 = 0 then
   seed:=(seed-1)**2;
   random1:= park1(seed,max1);
 end if;
    return random1; 
  end park1;

-- Primality Test Function
Function IS_Prime(number: integer) return STD_Logic is
Variable d: integer;
Variable d_binary: std_logic_vector(31 downto 0);
Variable s_1: integer :=0;
Variable iteration: integer :=1;
Variable x: integer;
Variable a: integer;
variable two:std_logic_vector(31 downto 0):="00000000000000000000000000000010";
Variable fake: integer;


Begin
d:= number -1; 
if ( number < 2) then
Return '0';
end if;  
if ( number = 2) then
Return '1';
end if;
if ( number /= 2 and number mod 2 = 0) then
 return '0';
end if;
while ( d mod 2 = 0 ) loop 
d:=d/2;
s_1:=s_1+1;
end loop;
d_binary:=binary1(d);
ii_loop: for ii in 0 to iteration-1 loop
a:=park1((ii+(s_1*100000))+number,(number-2));
x:=modexp3 (a,number,d_binary);
z4: if ((x /= 1) and (x /= number -1)) then 
 R_LOOP:         for r in 0 to s_1-1 loop
        fake:=0;
        x:=modexp3(x,number,two);
            z0: if (x = number -1) then
                fake:=1;
                 exit R_LOOP when fake = 1;
            end if z0;
            z1: if (x = 1) then 
                    return '0';
                end if z1;
    end loop R_LOOP;

        z2: if (fake/=1) then
            return '0'; 
        end if z2;

end if z4;
end loop ii_loop;
return '1';
End IS_Prime;
Begin

Test1 <= IS_Prime(N);


end Behavior1;

私は VHDL に慣れていないので、プロジェクトの進捗状況がまったくわからないので、本当に混乱しています。そのプログラムを構造型 (ポート マッピング) にする必要があります。

4

1 に答える 1

1

ヒントを求められたので、参考になればと思い、コードを見て思いついたことをいくつか書きます。

  • 関数の使用に問題はありません。これらは、デザインを整理するのに適した方法です。関数本体で使用するステートメントも合成可能である限り、それらは合成可能です。
  • 車輪を再発明しないでください。作成した関数のほとんどは、標準ライブラリで既に定義済みです。実装する前にいくつかの調査を行い、それが一般的なサブプログラムであるかどうか、ほとんどの設計者にとって役立つものであるかどうかを考えてみてください。この場合、特に型変換や計算が必要な場合は、すぐに解決できる可能性があります。
  • ブライアン・ドラモンドが言ったようwhileに、コンパイラーが反復の総数を推測するのが難しいため、ループを避けるようにしてください。forシンセサイザーでは、制限が一定のループの方が簡単です。また、可変範囲を持つネストされたループは忘れてください。
  • Jerry Coffin は、アルゴリズムをハードウェアで実装する方法とソフトウェアで実装する方法との間に混乱があるかもしれないという彼の発言も正しいです。ほとんどの場合、コードを記述する前にハードウェア図を描くと、物事を整理するのに役立ちます。多くの場合、ハードウェアにアルゴリズムを実装するために何が必要かについて、設計者があまり良い考えを持っていないことが少なくとも明らかになります。
  • ソフトウェアからハードウェアに移行したい。その大部分は、何を即座に (1 クロック サイクル内で) 実行する必要があるか、何を順次実行するか (複数のクロック サイクルにまたがって) を決定することです。したがって、ループを使用して何かを計算するビヘイビアー (合成不可能) コードがあり、この計算をハードウェアで行いたいとします。
    • 単一のクロックサイクルで計算する必要がある場合、コンパイラはすべてのループ反復に対してハードウェアを複製しますが、これは巨大になる可能性があります。
    • 計算を数クロック サイクルに分散できる場合、最善の策は、この計算用に有限ステート マシン (FSM) を設計することです。繰り返しますが、コードを書く前に図を描いてください。これはあなたの場合に大いに役立ちます。

これがあなたを正しい方向に向けるのに役立つことを願っています。

于 2014-02-27T03:10:43.130 に答える