在Verilog中进行信号边缘检测的正确方法

e19*_*001 6 synchronization verilog

我想检测一个来自触发器的信号的上升沿AABB

                    +----+
  A ----------------|    |----- OUT
        +----+      | BB |
  B ----|    |------|>   |
        | AA |      +----+
clk ----|>   |
        +----+
Run Code Online (Sandbox Code Playgroud)

Verilog代码:

    module edge_detect (
        input A,
        input B,
        input clk,
        output OUT
    );

        reg AA;
        reg BB;

        always @(posedge clk) begin
            AA <= B;
        end

        always @(posedge AA)begin
            BB <= A;
        end

        assign OUT = BB;
    endmodule
Run Code Online (Sandbox Code Playgroud)

输出AA用作BB表示AA已完成其工作的时钟,然后BB可以继续其操作.

我很少看到这段代码.这是一个好习惯吗?

如果没有,有没有其他正确的方法来检测信号的边缘?

Pau*_*l S 8

由于各种原因,人们往往不愿意将数据用作时钟.

就个人而言,如果我写这篇文章,我会选择:

module edge_detect (
    input A,
    input B,
    input clk,
    output OUT
);

    reg AA;
    reg BB;
    wire enA;

    always @(posedge clk) begin
        BB <= B;
    end

    assign enA = !BB && B;

    always @(posedge clk)begin
       if (enA) begin
            AA <= A;
      end
    end

    assign OUT = AA;
endmodule

                                +----+
  A ----------------------------|D   |----- OUT
                     +---+      | AA |
      /--------------|   |      |    |
      | +----+       |AND|------|E   |
  B ----|    |------o|   |      |    |
        | BB |       +---+      |    |
clk ----|>   |          clk ----|>   |
        +----+                  +----+
Run Code Online (Sandbox Code Playgroud)

但行为有点不同.

  • 主要优点是您不必处理衍生时钟,这可能会导致合成和布局程序令人头疼.时钟往往通过各种工具以特殊方式处理,因此在大多数情况下不鼓励在时钟生成中加入逻辑. (2认同)
  • 这些有时被称为"一次性"或单稳态多谐振荡器. (2认同)