1

我正在尝试使用 4 个 D-FF 在 Verilog 中制作一个 mod-12 计数器。我实际上提出了两种实现方式,其中一种按预期工作(但 IRL 的做法确实很糟糕),而另一种则没有按预期工作。以下是我的“坏”实现产生的理想(正确)输出。

正确的输出

以下是我遇到问题的模块生成的内容。

输出错误

这是生成顶部图像的模块:

module Mod12Counter(q, clk, rstIn0);
    output [3:0] q;
    input  clk, rstIn0;

    DF DF0(q[0], qBar0, qBar0, clk, rst),
       DF1(q[1], qBar1, qBar1, qBar0, rst),
       DF2(q[2], qBar2, qBar2, qBar1, rst),
       DF3(q[3], qBar3, qBar3, qBar2, rst);

    and and0(test, q[2], q[3]);
    or  or0 (rst, rstIn0, test);

endmodule

这是生成底部图像的模块:

module Mod12Counter(q, clk, rst); 
    output [3:0] q;
    input  clk, rst;

    and and0(d1In0, q[1], qBar0),
        and1(d1In1, qBar1, q[0]),
        and2(d2In0, q[2], qBar1),
        and3(d2In1, qBar3, qBar2, q[1], q[0]),
        and4(d2In2, q[2], qBar0),
        and5(d3In0, q[3], qBar1),
        and6(d3In1, q[2], q[1], q[0]),
        and7(d3In2, q[3], qBar0);

    or or0(d1, d1In0, d1In1),
       or1(d2, d2In0, d2In1, d2In2),
       or2(d3, d3In0, d3In1, d3In2);

    DF DF0(q[0], qBar0, qBar0, clk, rst),
       DF1(q[1], qBar1, d1, qBar0, rst),
       DF2(q[2], qBar2, d2, qBar1, rst),
       DF3(q[3], qBar3, d3, qBar2, rst);
endmodule

真正奇怪的是这两个模块的行为方式完全相同。唯一的区别是一个只是使用我的直觉做出的,另一个是通过从状态表中推导出方程生成的。据我所知,底部模块更适合使用 IRL。

到目前为止,我看到的问题是q[2] 和 q[3]在底部模块中根本没有被触发。正如你现在所看到的,我已经尝试使用 BUS 分配,并且我也尝试过不使用 BUS 分配。

我在这方面花了很多时间,如果你能帮助我调试模块、指出正确的方向或告诉我一个更好的地方来做这样的事情,我将不胜感激。

4

1 回答 1

2

如果 q[2] 永远不会变高,那么您应该首先了解为什么 DF2 的输入在时钟上升时永远不会变高。

查看输入以查看驱动器d2,我看到以下三行:

    and2(d2In0, q[2], qBar1),
    and3(d2In1, qBar3, qBar2, q[1], q[0]),
    and4(d2In2, q[2], qBar0),

显然and2and4在这里无法帮助您,因为它们要求 q[2] 为真才能为真,因此我们可以将它们扔掉,只留下以下几行来查看:

    and3(d2In1, qBar3, qBar2, q[1], q[0]),
    or1(d2, d2In0, d2In1, d2In2),
    DF2(q[2], qBar2, d2, qBar1, rst),

d2In1q当等于时应该为高0011,这意味着 d2 将同时为高。但是,您在 的上升沿触发 DF2 的时钟qBar1,这意味着无论何时qBar1变高,都会变q[1]低,从而d2In1也导致变低。所以你有一个竞争条件,触发器的输入在时钟边沿上升的同时下降,这是不好的!

与其在触发器的输出上为触发器计时(这会给您带来令人讨厌的竞争条件),不如让所有触发器仅基于一个时钟,并根据触发器的先前值生成下一个状态.

或者,这是一个非常简单的解决方案(您不必总是自己设计门!):

reg [3:0] q;
always @(posedge clk) begin
    q <= (q == 4'd11 || rst) ? 0 : q + 1;
end
于 2013-11-05T04:04:45.237 回答