module bin_mult(
output reg [7:0]mult,reg1,reg2,
output reg [2:0]count,
input [3:0]a,b,
input load,clk);
//reg [7:0]reg1,reg2;
//reg [2:0]count;
reg [3:0]m[3:0];
integer i,j;
// Partial product generation
always@(*) begin
for(i=0;i<4;i=i+1) begin
for(j=0;j<4;j=j+1) begin
m[i][j]=b[i]&a[j];
end
end
end
always@(posedge clk) begin
if(load) begin
reg1<=0;
count<=0;
reg2<={4'd0,m[0]};
end
else if(count==4'd3) count<=0;
else begin
count<=count+1;
if(b[count+1]==1'b1) begin
reg1<={4'd0,m[count+1]}<<(count+1);
mult<=reg1+reg2;
reg2<=mult;
end
else if(b[count+1]==1'b0) reg2<=reg2;
end
end
endmodule
module tb;
wire [7:0]mult,reg1,reg2;
wire [2:0]count;
reg [3:0]a,b;
reg load,clk;
bin_mult DUT(mult,reg1,reg2,count,a,b,load,clk);
always #5 clk=~clk;
initial begin
$dumpfile("tb.vcd");
$dumpvars(0,tb);
$monitor("clk=%b load=%b a=%d b=%d count=%d reg1=%b reg2=%b mult=%d",clk,load,a,b,count,reg1,reg2,mult);
{clk,load}=0;
@(negedge clk) a=4'd15;b=4'd15;
@(negedge clk) load=1'b1;
@(negedge clk) load=1'b0;
#100 $finish;
end
endmodule
这是模拟结果:-
VCD info: dumpfile tb.vcd opened for output.
clk=0 load=0 a= x b= x count=x reg1=xxxxxxxx reg2=xxxxxxxx mult= x
clk=1 load=0 a= x b= x count=x reg1=xxxxxxxx reg2=xxxxxxxx mult= x
clk=0 load=0 a=15 b=15 count=x reg1=xxxxxxxx reg2=xxxxxxxx mult= x
clk=1 load=0 a=15 b=15 count=x reg1=xxxxxxxx reg2=xxxxxxxx mult= x
clk=0 load=1 a=15 b=15 count=x reg1=xxxxxxxx reg2=xxxxxxxx mult= x
clk=1 load=1 a=15 b=15 count=0 reg1=00000000 reg2=00001111 mult= x
clk=0 load=0 a=15 b=15 count=0 reg1=00000000 reg2=00001111 mult= x
clk=1 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult= 15
clk=0 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult= 15
clk=1 load=0 a=15 b=15 count=2 reg1=00111100 reg2=00001111 mult= x
clk=0 load=0 a=15 b=15 count=2 reg1=00111100 reg2=00001111 mult= x
clk=1 load=0 a=15 b=15 count=3 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=0 load=0 a=15 b=15 count=3 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=1 load=0 a=15 b=15 count=0 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=0 load=0 a=15 b=15 count=0 reg1=01111000 reg2=xxxxxxxx mult= 75
clk=1 load=0 a=15 b=15 count=1 reg1=00011110 reg2=01001011 mult= x
clk=0 load=0 a=15 b=15 count=1 reg1=00011110 reg2=01001011 mult= x
clk=1 load=0 a=15 b=15 count=2 reg1=00111100 reg2=xxxxxxxx mult=105
clk=0 load=0 a=15 b=15 count=2 reg1=00111100 reg2=xxxxxxxx mult=105
clk=1 load=0 a=15 b=15 count=3 reg1=01111000 reg2=01101001 mult= x
clk=0 load=0 a=15 b=15 count=3 reg1=01111000 reg2=01101001 mult= x
clk=1 load=0 a=15 b=15 count=0 reg1=01111000 reg2=01101001 mult= x
clk=0 load=0 a=15 b=15 count=0 reg1=01111000 reg2=01101001 mult= x
clk=1 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult=225
clk=0 load=0 a=15 b=15 count=1 reg1=00011110 reg2=xxxxxxxx mult=225
clk=1 load=0 a=15 b=15 count=2 reg1=00111100 reg2=11100001 mult= x
test.v:56: $finish called at 130 (1s)
clk=0 load=0 a=15 b=15 count=2 reg1=00111100 reg2=11100001 mult= x
我使用了两个寄存器
reg1
来存储部分乘积项,使用 reg2
来存储中间结果(使用第一个部分乘积项数组 m[0]
对其进行初始化),但我得到了 reg2
的未知状态。
当
count
变为 1 时,reg2 必须保持其先前的值,即 00001111,但它会得到 x。之后在很多地方 reg2 都得到了 x。我找不到原因。
reg2
未知,因为 mult
未知。
解决未知数的一种方法是当
mult
为 1 时将 load
设置为 0,就像其他信号一样:
always@(posedge clk) begin
if(load) begin
reg1<=0;
count<=0;
reg2<={4'd0,m[0]};
mult <= 0;
end