【问题标题】:Proper way for signal edge detection in VerilogVerilog中信号边缘检测的正确方法
【发布时间】:2011-12-07 10:15:49
【问题描述】:

我想检测信号的上升沿从触发器AABB

                    +----+
  A ----------------|    |----- OUT
        +----+      | BB |
  B ----|    |------|>   |
        | AA |      +----+
clk ----|>   |
        +----+

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

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

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

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

【问题讨论】:

    标签: synchronization verilog


    【解决方案1】:

    出于各种原因,人们倾向于不赞成将数据用作时钟。

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

    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 ----|>   |
            +----+                  +----+
    

    但行为有点不同。

    【讨论】:

    • enA = not BB &amp;&amp; B; 等价于enA = !BB &amp;&amp; B;if (enA) { ... } 等价于verilog 中的if (enA) begin ... end。无论如何,你能说出它的优势吗?感谢您的快速答复。 =)
    • 是的,我在写入编辑器时会出现 VHDL/Verilog 溢出。
    • 主要优点是您不必处理派生时钟,这可能会导致综合和布局程序头痛。各种工具往往以特殊的方式处理时钟,因此大多数时候不鼓励将逻辑纳入时钟生成。
    • 这些有时被称为“单次”或单稳态多谐振荡器。
    【解决方案2】:

    如果您想在 Verilog 中检测上升沿或下降沿,只需将信号流水线或延迟 1 个时钟脉冲即可。在数字环境中,边缘可以被认为是 0 到 1 的转换或 1 到 0 的转换。 因此,您可以检查信号是否转换到任一状态,然后仅在该条件下断言您的输出为高电平。

    例如:

    output out_flag; 
    reg temp;    
    reg temp_d;   
    always@(posedge clk)
    temp_d <= temp;    
    always@(posedge clk)
    begin
     if (temp && ~temp_d)
       out_flag<= 1'b1;
     else
       out_flag<= 1'b0;
    end
    

    【讨论】:

      猜你喜欢
      • 2014-03-30
      • 2023-03-09
      • 1970-01-01
      • 2011-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-21
      • 1970-01-01
      相关资源
      最近更新 更多