我正在尝试在 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
伊卡洛斯 Verilog 输出
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.
EDAPlayground 输出
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上进行测试。