问题描述
我为行为类型的 Rabin Miller 算法设计了素性测试.我使用函数来创建我的模块.不幸的是,当我尝试通过 Quartus 用我的 Altera 套件合成它时,我意识到该函数没有合成.在这里,我将编写我的整个程序,我真的需要您帮助至少给我一些提示以将其更改为结构性,因为它是我的高级设计项目.这是我的程序:
I designed a primality testing for Rabin Miller algorithm in behavioral type. I used functions to create my modules. Unfortunately, when I tried to synthesize it by my Altera Kit via Quartus, I realized that function are not synthesize. Here I will write my whole program, and I really need you help to give me at least some hints to change it to structural as it is my senior design project. Here is my program:
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 的新手,这让我很困惑,因为我的项目没有任何进展.拜托,我需要该程序为结构类型(端口映射).
I am new to VHDL and this is really confusing me where I have no progress in my project. Please, I need that program to be in structural type (port mapping).
推荐答案
你要求了一些提示,所以我只写一些看你的代码时想到的东西,希望对你有所帮助.
You asked for some hints, so I'll just write some things that come to mind from looking at your code, hoping it will be helpful.
- 使用函数没有问题;它们是组织设计的好方法.它们是可综合的,只要您在函数体中使用的语句也是可综合的.
- 不要重新发明轮子.您编写的大多数函数已经在标准库中预定义.在实现之前做一些研究,并尝试考虑它是否是一个通用的子程序,一个对大多数设计人员有用的子程序.如果是这种情况,则可能有现成的解决方案,尤其是在涉及类型转换或数学时.
- 正如 Brian Drummond 所说,尽量避免
while
循环,因为它们更难让编译器猜测总迭代次数.for
具有恒定限制的循环在合成器上更容易.忘记带有可变范围的嵌套循环. - Jerry Coffin 也说得对,他说在硬件和软件中实现算法的方式之间可能存在一些混淆.大多数情况下,在编写任何代码之前绘制硬件图有助于解决问题.很多时候,它至少表明设计者对在硬件中实现算法需要什么不是很清楚.
- 您希望从软件过渡到硬件.其中很大一部分是决定您需要立即执行的操作(在单个时钟周期内),以及您想要按顺序执行的操作(分布在多个时钟周期内).因此,假设您有一些使用循环计算某些内容的行为(不可综合)代码,并且您希望在硬件中进行此计算.
- 如果您需要在一个同步时钟周期内计算它,编译器将为所有循环迭代复制硬件,这可能是巨大的.
- 如果您可以将计算扩展到多个时钟周期,那么最好的办法是为该计算设计一个有限状态机 (FSM).同样,在编写代码之前绘制图表,这对您的情况会有很大帮助.
- There is no problem in using functions; they are a good way to organize your design. They are synthesizable, as long as the statements you use in the function body are synthesizable as well.
- Don't reinvent the wheel. Most of the functions you wrote are already predefined in the standard libraries. Do some research before implementing, and try to think whether it is a common subprogram, one that would be useful to most designers. If this is the case, there is probably a ready solution, especially if it involves type conversions or math.
- As Brian Drummond said, try to avoid
while
loops because they are harder for the compiler to guess the total number of iterations.for
loops with constant limits are easier on the synthesizer. And forget about nested loops with variable ranges. - Jerry Coffin is also right when he says that there may be some confusion between how you implement an algorithm in hardware vs. in software. Most of the times, drawing a hardware diagram before writing any code helps sort things out. Many times, it at least reveals that the designer does not have a very good idea of what it takes to implement the algorithm in hardware.
- You want to make the transition from software to hardware. A big part of it is to decide what you need to do instantly (within a single clock cycle), and what you want to do sequentially (spread over several clock cycles). So, suppose you have some behavioral (non-synthesizable) code that calculates something using a loop, and you want to make this calculation in hardware.
- If you need to calculate it in a syngle clock cycle, the compiler will have replicate the hardware for all loop iterations, which might be huge.
- If you can spread the calculation over several clock cycles, your best bet is to design a finite state machine (FSM) for this calculation. Again, draw a diagram before writing the code, this will help a lot in your case.
希望这有助于为您指明正确的方向.
Hope this helps point you in the right direction.
这篇关于行为到结构转换问题 VHDL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!