代码已正确合成,但是当我尝试对其进行仿真时,只有lda从0变为1。其余控制信号保持不变。 eqz信号从x不变。其余信号保持为0状态。 我已经尽力了。有人能告诉我我哪里出问题了吗?
module multiplier(input clk, start, [15:0]datain , output done);
wire eqz, lda, ldb, ldp, clrp, decb;
mul_datapath D(eqz, clk, lda, ldb, ldp, clrp, decb, datain);
mul_control C(done, lda, ldb, ldp, clrp, decb, clk, start, eqz, datain);
endmodule
module mul_datapath(eqz, clk, lda, ldb, ldp, clrp, decb, datain);
input clk, lda, ldb, ldp, clrp, decb;
input [15:0] datain;
wire [15:0]x, y, z, bout;
output eqz;
PIPO1 P1(x, clk, lda, datain);
PIPO2 P2(y, clk, ldp, clrp, z);
ADD A(z, x, y);
COUNT CNT(bout, clk, ldb, decb, datain);
COMP com(eqz, bout);
endmodule
module PIPO1(x, clk, lda, datain);
input clk, lda;
input [15:0] datain;
output reg [15:0] x;
always @(posedge clk)
if(lda) x<= datain;
endmodule
module PIPO2(y, clk, ldp, clrp, z);
input clk, ldp, clrp;
input [15:0] z;
output reg [15:0]y;
always @(posedge clk)
begin
if(clrp) y<= 16'b0;
else if(ldp) y<= z;
end
endmodule
module ADD(z, x, y);
input [15:0]x, y;
output reg [15:0]z;
always @(*)
z = x + y;
endmodule
module COUNT(bout, clk, ldb, decb, datain);
input clk, ldb, decb;
input [15:0] datain;
output reg [15:0]bout;
always @(posedge clk)
begin
if(ldb) bout <= datain;
else if(decb)
bout <= bout -1;
end
endmodule
module COMP(eqz, bout);
input [15:0] bout;
output eqz;
assign eqz = (bout==0);
endmodule
module mul_control(done, lda, ldb, ldp, clrp, decb, clk, start, eqz, datain);
input clk, start, eqz;
input[15:0] datain;
output reg lda, ldb, ldp, clrp, decb, done;
reg [2:0]state;
parameter S0=000, S1=001, S2=010, S3=011, S4=100;
always @(posedge clk)
begin
case(state)
S0 : if(start) state<= S1;
S1 : state<=S2;
S2 : state<= S3;
S3 : begin if(eqz) state<=S4; else state<=S3; end
S4 : state<= S4;
default : state<= S0;
endcase
end
always @(state)
begin
case(state)
S0: begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
S1: begin lda = 1; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
S2: begin lda = 0; ldb = 1; ldp = 0; clrp = 0; decb = 0; done = 0; end
S3: begin lda = 0; ldb = 0; ldp = 1; clrp =0; decb = 1; done = 0; end
S4: begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 1; end
default : begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
endcase
end
endmodule
答案 0 :(得分:0)
您的基本错误是在乘法器和mul_control模块中。
对于乘法器模块,您错误地声明了端口。
据我了解,您的意思是将其用作测试平台。这样就不需要输入或输出端口。也不需要接线声明。 刚好碰上前两行。 这应该做
module multiplier;
reg [15:0] datain;
reg clk, start;
wire done;
mul_datapath D(eqz, clk, lda, ldb, ldp, clrp, decb, datain);
mul_control C(done, lda, ldb, ldp, clrp, decb, clk, start, eqz, datain);
endmodule
但是我建议您添加一些代码以实际为测试台增加含义,以便您可以测试所有模块。
此外,您不需要mul_control.v中的数据。删除datain还需要对测试台中的调用进行相同的更改。 此外,在mul_control.v中,您还应该在有条件的状态更改处添加延迟。 同样,您忘记在mul_control.v中为状态2设置clrp
最严重的是,默认情况下,保存为000、001、0010的状态参数全部取为十进制。由于您需要从0到5的5个状态,因此将状态值分配为二进制符号,如3'b000、3'b001、3'b010等。
所以现在
module mul_control(done, lda, ldb, ldp, clrp, decb, clk, start, eqz);
input clk, start, eqz;
output reg lda, ldb, ldp, clrp, decb, done;
reg [2:0]state;
parameter S0=3'b000, S1=3'b001, S2=3'b010, S3=3'b011, S4=3'b100;
always @(posedge clk)
begin
case(state)
S0 : if(start) state<= S1;
S1 : state<=S2;
S2 : state<= S3;
S3 : #2 if(eqz) state<=S4;
S4 : state<= S4;
default : state<= S0;
endcase
end
always @(state)
begin
case(state)
S0: begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
S1: begin lda = 1; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
S2: begin lda = 0; ldb = 1; ldp = 0; clrp = 1; decb = 0; done = 0; end
S3: begin lda = 0; ldb = 0; ldp = 1; clrp =0; decb = 1; done = 0; end
S4: begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 1; end
default : begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
endcase
end
endmodule
module multiplier;
reg [15:0] datain;
reg clk, start;
wire done;
mul_datapath D(eqz, clk, lda, ldb, ldp, clrp, decb, datain);
mul_control C(done, lda, ldb, ldp, clrp, decb, clk, start, eqz);
initial
begin
clk = 1'b0;
#3 start = 1'b1;
#500 $finish;
end
always #5 clk = ~clk;
initial
begin
#17 datain = 5;
#10 datain = 6;
end
initial
begin
$monitor($time, " %d %b", D.y, done);
$dumpfile("mul.vcd"); $dumpvars(0, multiplier);
end
endmodule
运行此命令,我得到以下输出:
$ iverilog add.v count.v PIPO2.v mul_datapath.v COMP.v PIPO1.v mul_control.v multiplier.v
$ vvp a.out
VCD info: dumpfile mul.vcd opened for output.
0 x x
5 x 0
35 0 0
45 5 0
55 10 0
65 15 0
75 20 0
85 25 0
95 30 0
97 30 1
这里的答案(y的值)是30,因为我们给了5和6作为数据。
在测试台中,我还保存了一个波形转储文件名称mul.vcd,可以使用gtkwave将其打开为
gtkwave mul.vcd &
注意:我正在使用iverilog和gtkwave进行编译,运行和模拟。有关它们的更多详细信息,请参见:http://axayjha.github.io/pages/iverilog.html