求余数的Verilog代码

Verilog code to find remainder

我编写了 Verilog 代码来求两个数相除时的余数。但我面临一个问题。我有 q(股息)和 m(除数),rem 是余数。我的算法是:

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

我写了这个 Verilog 代码,但是 if-statement 只运行一次。在下一个时钟周期中,它取值 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

你的算法有误。应该是这样的

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 中。由于模块找到余数所需的时间并不总是相同的,因此当 rem.

中有有效输出时,信号 finish 被置位。

快速测试平台:

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