2014-02-26 52 views
0

我爲行爲類型的拉賓米勒算法設計了一個素性測試。我使用函數來創建我的模塊。不幸的是,當我試圖通過我的Altera套件通過Quartus進行綜合時,我意識到這個功能並不合成。在這裏,我將編寫我的整個程序,我真的需要你幫忙給我至少一些提示,將它改爲結構,因爲它是我的高級設計項目。這裏是我的程序:行爲到結構轉換問題VHDL

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的新手,這真讓我困惑,因爲我在我的項目中沒有任何進展。請,我需要該程序是在結構類型(端口映射)。

+0

IMO,你的問題更根本。你在思考和編寫軟件,但綜合你需要編寫硬件。例如,軟件中的「while」循環通常會變成硬件中的狀態機。鑑於軟件中的拉賓米勒是常見的,你很*非常*要求有人爲你做你的項目。 –

+0

沒有兄弟我不這樣做。我的項目比這要重得多。這是一個RSA密碼系統。所以,這是我的計劃的一小部分,我相信如果你幫助我,我會處理它。我只是想了解如何玩結構。然後我可以做我自己的程序並完成我的項目。謝謝^ _^ – user3300910

+2

大多數綜合工具的功能當然是可以合成的,如果它們是在考慮硬件生成限制的情況下編寫的話。一條規則:避免while循環;對於具有固定邊界的循環應該是可以的。 –

回答

1

你問了一些提示,所以我只會寫一些你想到的代碼,希望它會有幫助。

  • 使用函數沒有問題;他們是組織設計的好方法。它們是可綜合的,只要你在函數體中使用的語句也可以合成。
  • 不要重新發明輪子。您編寫的大部分功能已經在標準庫中預定義。在實施之前做一些研究,並設法考慮它是否是一個常見的子程序,對大多數設計人員都有用。如果是這種情況,則可能有一個現成的解決方案,尤其是涉及類型轉換或數學運算的情況。
  • 正如Brian Drummond所說,儘量避免while循環,因爲編譯器難以猜測迭代的總次數。具有恆定限制的for循環在合成器上更容易。並忘記了可變範圍的嵌套循環。
  • Jerry Coffin也說得對,他說在硬件和軟件中實現算法的方式可能存在一些混淆。大多數情況下,在編寫任何代碼之前繪製硬件圖表有助於理清問題。很多時候,它至少表明設計人員對於在硬件中實現算法需要什麼不甚瞭解。
  • 您想從軟件轉換到硬件。其中很大一部分是決定你需要立即做什麼(在一個時鐘週期內)以及你想要做什麼(分散在幾個時鐘週期內)。所以,假設你有一些行爲(不可綜合)的代碼可以用循環來計算某些東西,並且你想用硬件進行計算。
    • 如果你需要在syngle時鐘週期內計算它,編譯器將複製所有循環迭代的硬件,這可能是巨大的。
    • 如果你可以在幾個時鐘週期內分散計算,最好的辦法是爲這個計算設計一個有限狀態機(FSM)。再次,在編寫代碼之前繪製圖表,這對您的案例會有很大的幫助。

希望這有助於你指出正確的方向。

+0

我非常感謝您的幫助,但您的幫助不是將我的代碼轉換爲結構。我需要處理它): – user3300910

+1

您是否願意更詳細地解釋您稱之爲「結構代碼」?如果從結構上來說,你的意思是「只使用組件實例化的代碼」,那麼它作爲一項需求並沒有多大意義,特別是對於高級設計項目。也許討論的內容應該是關於可合成和不可合成的代碼。 – rick