我想在verilog中获得素数。为此,我使用了计数器,它依赖于每个时钟的上升沿。使用计数器的值,我必须得到素数。我的问题是如何检查计数值是否为素数。我可以使用for循环来检查素数,但是知道在verilog for循环中不是一个好方法,因为它需要很多时钟周期来完成循环。我必须在没有for循环的情况下检查素数。任何人都可以帮我检查计数是否为无主循环。
module prime_clk ( input clk, input reset)
parameter N =1000; // size of array
reg [31:0] prime_number[0:N-1]; // memory array for product
integer k=0 ; // counter variable
integer result_done =1; // controller
integer count =0;
always @(posedge clk )
begin
count = count+1 ;
if (count%2 !=0 || count%3 !=0 )
begin
prime_number[k] <= count;
k <= k + 1;
end
end
endmodule
答案 0 :(得分:1)
你还没有描述你如何计划检查每个数字的素数,我假设你打算采用它下面每个数字的模数来测试它是否可以设想。
当检查素数时,你只需检查下面的素数是不可设想的,因为所有其他数字都由素数的倍数组成。
有低于1000的168个素数。为了检查1到1000的质数,您需要168个并行模运算,或者您可以重新设计以重复使用相同的硬件。必须在相同的时间内为最坏的情况设计或者允许时间改变,为更大的数字提供越来越多的时钟周期。
我认为在这个阶段值得一提的是,实际将素数放入ROM或查找表将比生成它们的硬件小得多。
使用多个时钟周期检查素数的示例:
integer test ;
integer check ; //Counts 1 to k
localparam S_INC = 2'b01;
localparam S_CHECK = 2'b10;
reg [1:0] state;
initial begin
prime_number[0] = 'd2;
state = S_CHECK; //Check set count first
count = 'd3;
k = 'd1; //0 preloaded
check = 'd0;
test = 'd1;
end
always @(posedge clk ) begin
if (state == S_INC) begin
$display("State: Incrementing Number to check %d", count+1);
count <= count+1 ;
state <= S_CHECK ;
check <= 'd0;
test <= 'd1; // Safe default
end
else if (state == S_CHECK) begin
if (test == 0) begin
// Failed Prime test (exact divisor found)
$display("Reject %3d", count);
state <= S_INC ;
end
else if (check == k) begin
//Passed Prime check
//Use k+1 so that 2 is number 1, 3 is 2nd etc
$display("Found the %1d th Prime, it is %1d", k+1, count);
prime_number[k] <= count;
k <= k + 1;
state <= S_INC ;
end
else begin
$display("Check");
test <= count % prime_number[check] ;
check <= check + 1;
end
end
end
EDA playground上的工作示例;