【问题标题】:Behavioral to Structural Conversion Problems VHDL行为到结构转换问题 VHDL
【发布时间】:2014-02-26 16:19:33
【问题描述】:

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

 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 新手,这让我很困惑,因为我的项目没有任何进展。拜托,我需要该程序为结构类型(端口映射)。

【问题讨论】:

  • IMO,您的问题更为根本。您正在思考和编写软件,但要进行综合,您需要编写硬件。例如,软件中的“while”循环通常会变成硬件中的状态机。鉴于软件中的 Rabin Miller 很常见,您相当要求某人为您完成您的项目。
  • 不,兄弟,我不会那样做。我的项目比这要重得多。它是一个 RSA 密码系统。所以,这是我程序的一小部分,我相信如果你帮助我,我会处理它。我只是想了解如何使用结构。然后我可以做我自己的程序并完成我的项目。谢谢^_^
  • 如果在编写时考虑到硬件生成约束,大多数合成工具肯定可以合成函数。一条规则:避免while循环;具有固定边界的 for 循环应该没问题。

标签: vhdl hdl modelsim intel-fpga


【解决方案1】:

您要求一些提示,所以我将写一些通过查看您的代码想到的东西,希望它会有所帮助。

  • 函数使用没有问题;它们是组织设计的好方法。它们是可综合的,只要您在函数体中使用的语句也是可综合的。
  • 不要重新发明轮子。您编写的大多数函数已经在标准库中预定义。在实施之前做一些研究,并尝试考虑它是否是一个通用的子程序,一个对大多数设计师有用的子程序。如果是这种情况,可能有现成的解决方案,尤其是在涉及类型转换或数学的情况下。
  • 正如 Brian Drummond 所说,尽量避免使用 while 循环,因为编译器更难猜测迭代总数。 for 具有恒定限制的循环在合成器上更容易。并且忘记具有可变范围的嵌套循环。
  • Jerry Coffin 说的也是正确的,他说在硬件和软件中实现算法的方式之间可能存在一些混淆。大多数时候,在编写任何代码之前绘制硬件图有助于解决问题。很多时候,它至少表明设计者对在硬件中实现算法需要什么了解并不十分清楚。
  • 您希望从软件过渡到硬件。其中很大一部分是决定你需要立即做什么(在一个时钟周期内),以及你想按顺序做什么(分散在几个时钟周期内)。因此,假设您有一些行为(不可综合)代码使用循环计算某些内容,并且您希望在硬件中进行此计算。
    • 如果您需要在单时钟周期内计算它,编译器将为所有循环迭代复制硬件,这可能是巨大的。
    • 如果您可以将计算分散到多个时钟周期,最好的办法是为此计算设计一个有限状态机 (FSM)。同样,在编写代码之前先画一张图,这对您的情况很有帮助。

希望这有助于为您指明正确的方向。

【讨论】:

  • 非常感谢您的帮助,但您的帮助并不是将我的代码转换为结构化代码。我需要处理它):
  • 您愿意更详细地解释一下您所说的“结构代码”吗?如果通过结构化您的意思是“只使用组件实例化的代码”,那么它作为需求确实没有多大意义,特别是对于高级设计项目。也许讨论应该是关于可合成与不可合成的代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多