Verilog代码找到余数

时间:2015-03-27 05:31:35

标签: verilog fpga system-verilog

我写了Verilog代码,以便在分割两个数字时找到余数。但我面临一个问题。我有q(被除名)和m(除数),rem是余数。我的算法是:

if(q>m)
  q=q-m 
otherwise 
  rem=q

我写了这个Verilog代码,但是if - 语句只运行一次。在下一个时钟周期,它取值p=q,这是我不想要的。我希望p中的价值来自p=p-m

我的代码是:

module div(q,clk,rem,p,count);

  parameter m=13'd840;
  input [12:0] q;
  input clk;
  output reg [12:0] rem;
  output reg [3:0] count;
  output reg [12:0] p;
  initial
    begin
      count=4'b0;
      //+ rem=9'b0;
      //p=13'b0;
    end

  always@(posedge clk)
    begin
      p=q;
      if (p>m)
      begin
        p=p-m;
        count=count+1;
        rem=p;
      end else 
        rem=9'b0;
    end 
endmodule

1 个答案:

答案 0 :(得分:0)

你的算法错了。它应该是这样的

while(q>=m)
  q=q-m 
rem=q

然后,您的Verilog模块是这样的:

module div #(parameter m=13'd840) (
  input wire clk,
  input wire [12:0] q,
  input wire load,
  output reg [12:0] rem,
  output reg finish
  );

  reg [12:0] p;

  always@(posedge clk) begin
    if (load) begin
      finish <= 1'b0;
      p <= m;
    end
    else if (p>=q)
      p <= p - q;
    else begin
      rem <= p;
      finish <= 1'b1;
    end
  end 
endmodule

我添加了两个信号:loadfinish。必须声明load以将新除数存储到q中。由于模块查找余数所需的时间并不总是相同,因此当finish中存在有效输出时,信号rem将被置位。

快速测试平台:

module tb;
  reg clk,load;
  reg [12:0] q;
  wire [12:0] rem;
  wire finish;

  div uut (clk, q, load, rem, finish);

  initial begin
    clk = 1'b1;
    for (q=1; q<840; q=q+1) begin
      load = 1;
      @(posedge clk); // allow settle load
      load = 0;
      @(posedge finish); // wait until finish is asserted
      @(posedge clk); // allow settle rem
      if (rem!=840%q) begin  // assert rem
        $display ("840 %% %d = %d , %d\n", q, rem, 840%q);        
        $finish;
      end
    end
    $display ("PASSED\n");
  end

  always begin
    clk = #5 ~clk;
  end
endmodule