我试图在verilog中实施nand2tetris项目,并使用icarus verilog进行攻击。在书中,他们实现了DFF,q(t) = d(t-1)
。当前时间的输出是前一个posedge clk
的输入。这是我意识到的DFF
。
module Dff (
output reg q,
input data, clk
);
reg p;
reg o;
always @(posedge clk) begin
o <= data;
q <= p;
end
always @(negedge clk) begin
p <= o;
end
endmodule
当我直接测试时,这个DFF似乎工作得很好。但是当我重新使用它创建一个Bit(一个内存单元)时,它就变得疯狂了。有趣的是,使用Icarus Verilog或EDAPlayground(使用VCS),疯狂程度不同。
module Mux (out, a, b, sel);
input a, b;
input sel;
output reg out;
assign out = ~sel ? a : b;
endmodule
module Bit (
output out,
input data, load, clk
);
Mux m0(in, out, data, load);
Dff d0(out, in, clk);
endmodule
data | load | clk | out
------+------+-----+-----
0 | 1 | 1 | x
0 | 1 | 0 | x
1 | 1 | 1 | x
1 | 1 | 0 | x
0 | 1 | 1 | 1
0 | 1 | 0 | 1
0 | 0 | 1 | 0
0 | 0 | 0 | 0
1 | 1 | 1 | 0
1 | 1 | 0 | 0
0 | 0 | 1 | 0 # !?!?!
0 | 0 | 0 | 0 # it should be 1 here.
data | load | clk | out
------+------+-----+-----
0 | 1 | 1 | x
0 | 1 | 0 | x
1 | 1 | 1 | x
1 | 1 | 0 | x
0 | 1 | 1 | 1
0 | 1 | 0 | 1
0 | 0 | 1 | 0
0 | 0 | 0 | 0
1 | 1 | 1 | 1 # !?!?!
1 | 1 | 0 | 1 # it should be 0 here.
0 | 0 | 1 | 1
0 | 0 | 0 | 1
代码可在EDAPlayground上测试。
答案 0 :(得分:0)
感谢Uun和Greg,以下是我解决问题的方法。 code is on EDA
DFF可以更简单。
module Dff (
output reg q,
input data, clk
);
always @(posedge clk) begin
q <= data;
end
endmodule
然后测试就是罪魁祸首。阻止分配导致混淆。解决这个问题的一种简单方法是将所有=
改为<=
,如下所示:
module Bit_tb;
reg clk = 0;
reg data = 0;
reg load = 1;
wire out;
initial begin
#2
data <= 1;
#2
load <= 0; // load = 0; /!\ would be blocking before
data <= 0; // data = 0; doing this line. /!\
#2
$finish;
end
end module