【问题标题】:prime number checking without for loop in verilog在verilog中没有for循环的素数检查
【发布时间】:2014-12-17 21:12:50
【问题描述】:

我想在verilog中获得素数。为此,我使用了计数器,它在每个时钟的上升沿计数。使用计数器的值,我必须得到质数。我的问题是如何检查计数值是否为素数。我可以使用 for 循环来检查素数,但知道在 verilog 中 for 循环不是一个好方法,因为它需要很多时钟周期才能完成 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

【问题讨论】:

  • 使用for-loop,您可以检查一个数字在一个周期内是否为素数,但该模块的最大频率会非常低。如果没有for-loop,您肯定需要超过 1 个(即很多)周期。
  • 好的。我可以使用 for 循环。拜托,你能告诉我使用for循环的有效方法吗
  • 当我使用for循环时,系统变得很慢..所以for循环方法不好

标签: verilog


【解决方案1】:

您还没有描述您计划如何检查每个数字的素数,我假设您计划对其下方的每个数字取模来测试它是否可设计。

在检查素数时,您只需检查它不能被它下面的素数设计,因为所有其他数字都是由素数的倍数组成的。

有 168 个素数低于 1000。因此,要检查 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 上的工作示例;

【讨论】:

  • 感谢摩根先生帮助我。我的计划是每 50 个素数它应该返回第 50 个素数,依此类推。
  • @fame313 没问题,表现出努力的问题应该做得很好。尽管在前 50 个素数之后,您将有越来越多的工作要做。请记住,1000 以下的质数只有 168 个。10,000 以下的质数有 1229 个。
  • 是的,我计算了第 50 个素数,由于计算次数更多,它得到了更多的时钟周期。现在我还有一个问题,那就是如何计算一个素数的模拟时间。这意味着计算一个素数没有时钟周期。我们也知道,一个大素数比一个小的素数获得更多的时钟周期来计算。你能帮助我吗??我非常感谢你
  • @摩根爵士 ,,,, .这种方法不足以计算素数。当我必须从 17 开始素数时,它不能正确计算。它还给出了输出中不是素数的数字
  • @fame313 这种计算素数的方法需要知道它下面的所有素数。这是避免除以小于它的所有数字的优化。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-03
  • 2016-04-01
  • 1970-01-01
相关资源
最近更新 更多