我写了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
答案 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
我添加了两个信号:load
和finish
。必须声明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