0

我正在尝试在 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上进行测试。

4

1 回答 1

1

感谢 Uun 和 Greg,这是我解决问题的方法。代码在 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
endmodule
于 2015-08-20T10:54:28.663 回答