【问题标题】:Verilog Falling Edge DetectionVerilog 下降沿检测
【发布时间】:2018-02-20 13:42:16
【问题描述】:

我正在为要在 FPGA 上实现的 UART 编写 Verilog 代码,但在第一个字节之后同步到字节的 START 位时遇到了一些问题。

我的经理建议同步我收到的信号并使用某种中断作为与我的 FSM 通信的一种方式,即已识别出开始。

我已经阅读了有关上升沿检测的技术,我觉得我可以这样做:

module StartDetectionUnit (
    input clk, state, signal_in,
    output trigger
    );   

    reg signal_d;

    always @(posedge clk)
        begin
            signal_d <= signal_in;
        end
    assign trigger = signal_in & (!signal_d);

endmodule    

在我的理解中,这样的描述检测的是上升沿,而不是下降沿,但“START”是 RS-232 通信中的逻辑“0”。

另外,我想在 IDLE 状态 [硬编码为 000] 时实际分配标志,但对最终分配进行疯狂的门控对我来说听起来不是硬件。

tldr,两个问题

  1. 检测异步输入信号的一般下降沿
  2. 在 FSM 的单个特定状态下这样做

非常感谢,我是 Verilog 的新手,对 HDL'ing 还是有点陌生​​

【问题讨论】:

    标签: synchronization verilog clock hdl


    【解决方案1】:

    如果您的信号 signal_in 来自您的设计之外,则它不会正确同步。在您的设计中,您只使用了一个 d-latch,需要两个。

    reg signal_d;
    always @(posedge clk)
        begin
            signal_d <= signal_in;
        end
    

    这将只合成一个 d-latch。要正确同步信号,您必须为两个 d-latch 实例声明第二个信号:

    reg signal_d;
    reg signal_sync;
    always @(posedge clk)
        begin
            signal_d <= signal_in;
            signal_sync <= signal_d;
        end
    

    并且 signal_d 不应在您的设计中使用。然后要进行边缘检测,您必须声明第三个类似的信号:

    reg signal_d;
    reg signal_sync;
    reg signal_sync_old;
    always @(posedge clk)
        begin
            signal_d <= signal_in;
            signal_sync <= signal_d;
            signal_sync_old <= signal_sync;
        end
    

    对于下降沿检测:

    assign trigger = signal_sync_old & (!signal_sync);
    

    关于同步的更多信息的好网站: https://www.doulos.com/knowhow/fpga/synchronisation/

    据我了解,您的信号“状态”以 3 位编码,那么您可以这样做:

    assign trigger = (state == 3'b000) ? (signal_sync_old & (!signal_sync)):0;
    

    【讨论】:

    • 澄清一下:“Signal_in”是我在仿真过程中从我的 USB-To-UART 桥接器或测试台收到的位。模块 StartDetectionUnit ( 输入 clk, state, signal_in, output trigger );注册信号_d;总是@(posedge clk) 开始 signal_d
    • 无法模拟异步外部输入信号。它将始终在模拟中工作。
    • 即使通过测试台?
    • 对不起,如果我听起来毫无头绪,但我主要有学术经验,我的主管并没有严格遵守我在这个问题上的工作。
    【解决方案2】:

    我也有同样的问题。我认为当您的主时钟采样率很高时,基本的下降沿检测会失败。输入波特率信号从高电平变为低电平需要时间。一旦检测到高低转换(在下降波特信号的中间),您就冒着在它实际达到最终低值之前再次尝试检测它的风险。在这种情况下,您将进行低到低检测,因此会丢失下降转换。我要解决这个问题的方法是在检测到下降沿时立即锁定检测器,以便必须手动重启才能检测到第二次。

    【讨论】:

      【解决方案3】:

      对于同步设计,可以通过这种方式进行下降沿检测。

      module StartDetectionUnit (
          input clk, state, signal_in,
          output trigger
          );   
      
          reg signal_d;
      
          always @(posedge clk)
              begin
                  signal_d <= !signal_in;
              end
          assign trigger = !(signal_in | signal_d);
      endmodule    
      

      这是上述逻辑的状态图和计算。

      下降沿检测可以通过以下方式进行。

      assign sout = !(sin | (!sin));
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-13
        • 2021-06-20
        • 1970-01-01
        • 2014-01-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多