行为到结构转换问题VHDL

行为到结构转换问题VHDL,vhdl,hdl,modelsim,intel-fpga,Vhdl,Hdl,Modelsim,Intel Fpga,我为行为类型的Rabin-Miller算法设计了一个素性测试。我使用函数来创建模块。不幸的是,当我试图通过我的Altera工具包通过Quartus合成它时,我意识到函数不是合成的。在这里,我将写我的整个程序,我真的需要你的帮助,至少给我一些提示,以改变它的结构,因为这是我的高级设计项目。这是我的节目: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity PrimeTest is por

我为行为类型的Rabin-Miller算法设计了一个素性测试。我使用函数来创建模块。不幸的是,当我试图通过我的Altera工具包通过Quartus合成它时,我意识到函数不是合成的。在这里,我将写我的整个程序,我真的需要你的帮助,至少给我一些提示,以改变它的结构,因为这是我的高级设计项目。这是我的节目:

 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;
ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
实体测试是
端口(N:整数;
测试1:输出标准(U逻辑);
终末试验;
PrimeTest的架构行为1是
函数integer_binary(b1:std_logic_vector(31到0))返回整数为
变量a:整数:=0;
变量i:整数;
开始
i:=0;
而(i=m1)则
p1:=binary1(((整数二进制(p1))-(整数二进制(m1)));
如果结束;
如果(p1>=m1),则
p1:=binary1(((整数二进制(p1))-(整数二进制(m1)));
如果结束;
i:=i-1;
端环;
返回p1;
末模;
函数模式XP3(exp\u m,exp\u n:整数;
exp_e:std_logic_vector(31到0))返回整数为
变量s:整数;
变量结果:整数:=1;
开始
S:=exp\u m;
L1:对于0到31循环中的I
I2:如果(exp_e(I)='1'),则
结果:=integer_binary(mul_mod(binary1(result)、binary1(s)、binary1(exp_n));
S:=integer_binary(mul_mod(binary1(S)、binary1(S)、binary1(exp_n));
其他的
S:=integer_binary(mul_mod(binary1(S)、binary1(S)、binary1(exp_n));
如果I2结束;
端环L1;
返回结果;
终端模式xp3;
函数park1(在_seed1中,max1:integer)返回整数为
变量hi:整数;
变量lo:整数;
变量out_seed:整数;
变量检验:整数;
变量1:整数;
拒绝变量:整数;
变量a:整数:=16807;
变量m:整数:=2147483647;
变量q:整数:=127773;
变量r:整数:=2836;
变量种子:整数;
开始
种子:=在种子1中;
对于0到1循环中的en
如果(en=0),则
hi:=in_seed1/q;
其他的
hi:=输出种子/q;
如果结束;
lo:=第1种模式q;
测试:=((a*lo)-(r*hi));
如果测试>0,则
出籽:=试验;
其他的
Out_seed:=测试+m;
如果结束;
端环;
random1:=out_seed mod max1;
如果random1=0,则
种子:=(种子-1)**2;
random1:=park1(种子,最大值1);
如果结束;
返回随机数1;
完(一);
--素性检验函数
函数为素数(数字:整数)返回标准逻辑为
变量d:整数;
变量d_二进制:标准逻辑向量(31到0);
变量s_1:整数:=0;
变量迭代:整数=1;
变量x:整数;
变量a:整数;
变量二:标准逻辑向量(31到0):=“00000000000000000000000000000010”;
变量伪:整数;
开始
d:=数字-1;
如果(数字<2),则
返回“0”;
如果结束;
如果(数字=2),则
返回“1”;
如果结束;
如果(数/=2,数模2=0),则
返回“0”;
如果结束;
而(d模2=0)循环
d:=d/2;
s_1:=s_1+1;
端环;
d_binary:=binary1(d);
ii_循环:对于0到迭代1循环中的ii
a:=park1((ii+(s_1*100000))+编号(编号-2));
x:=modexp3(a,数字,d_二进制);
z4:如果((x/=1)和(x/=number-1))那么
R_循环:对于0到s_1-1循环中的R
假:=0;
x:=modexp3(x,数字,2);
z0:如果(x=数字-1),则
假:=1;
当fake=1时退出R_循环;
如果z0,则结束;
z1:如果(x=1),则
返回“0”;
如果z1结束;
端环R_环;
z2:如果(假/=1),那么
返回“0”;
如果z2结束;
如果z4结束;
端环ii_环;
返回“1”;
结束是最好的;
开始

Test1您要求提供一些提示,因此我将编写一些在查看代码时想到的东西,希望它会有所帮助

  • 使用函数没有问题;它们是组织设计的好方法。只要函数体中使用的语句也是可合成的,它们就是可合成的
  • 不要重新发明轮子。您编写的大多数函数已经在标准库中预定义。在实现之前做一些研究,试着想想它是否是一个通用的子程序,一个对大多数设计人员都有用的子程序。如果是这种情况,可能有现成的解决方案,特别是当它涉及类型转换或数学时
  • 正如Brian Drummond所说,尽量避免
    while
    循环,因为编译器很难猜测迭代的总数
    for
    对于合成器来说,具有恒定限制的环路更容易实现。忘记带可变范围的嵌套循环
  • 杰里·科芬(Jerry Coffin)也说得对,他说在硬件和软件中如何实现算法之间可能存在一些混淆。大多数情况下,在编写任何代码之前绘制硬件图有助于解决问题。很多时候,它至少揭示了设计者对于如何在硬件中实现算法并不十分清楚
  • 您希望从软件过渡到硬件。其中很大一部分是决定你需要立即做什么(在一个时钟周期内),以及你想按顺序做什么(分散在几个时钟周期内)。因此,假设您有一些行为(不可合成)代码,可以使用循环计算某些内容,并且您希望在硬件中进行此计算。
    • 如果您需要在一个syngle时钟周期内计算它,编译器将为所有循环迭代复制硬件,这可能会非常巨大
    • 如果可以将计算分散到几个时钟周期,那么最好的选择是des