You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SystemVerilog设计延迟2个时钟周期输出的触发器?

正确实现2个时钟周期同步延迟的SystemVerilog方法

首先得指出你原来代码的核心问题:用#60这种固定时间延迟的写法完全不适合同步逻辑设计。从你的时钟生成代码clk=0; forever #10 clk = ~clk;能看出来,时钟周期是20ns(高低电平各10ns),#60确实是3个完整周期,但这种硬编码延迟完全脱离时钟同步——一旦你调整了时钟周期,延迟就不再对应预期的时钟数,而且在仿真中这种写法很容易导致时序混乱,这就是你达不到预期效果的根本原因。

同步逻辑里要实现精确的N个时钟周期延迟,最规范、可靠的做法是用寄存器打拍——把输入数据依次存入多级寄存器,每一级寄存器对应一个时钟周期的延迟。要实现2个时钟周期的延迟,我们只需要两级寄存器即可。

正确的代码实现

module sync_delay_2cycles (
    input  logic clk,
    input  logic rst_n,  // 同步低电平复位,可根据需求改为高电平复位
    input  logic d,
    output logic q
);

// 定义中间寄存器,存储第一级延迟的数据
logic d_delay1;

// 同步逻辑块:所有赋值都在时钟上升沿触发,严格同步
always @(posedge clk) begin
    if (!rst_n) begin
        // 复位时将所有寄存器置0
        d_delay1 <= 1'b0;
        q        <= 1'b0;
    end else begin
        // 第一级延迟:输入d在时钟上升沿存入d_delay1(延迟1个周期)
        d_delay1 <= d;
        // 第二级延迟:d_delay1在时钟上升沿存入q(再延迟1个周期,总共2个周期)
        q        <= d_delay1;
    end
end

endmodule

工作原理说明

假设在第N个时钟上升沿,输入d变为某个有效值:

  1. 第N个时钟上升沿:d_delay1被更新为当前d的值(此时q还是之前的旧值,延迟1个周期)
  2. 第N+1个时钟上升沿:q被更新为d_delay1的值(也就是第N个周期的d,此时刚好延迟了2个时钟周期)

这种方法完全跟时钟同步,不管你后续怎么调整时钟周期,延迟始终是精确的2个时钟周期,而且符合同步设计的规范,不管是仿真还是综合实现都能正常工作。

为什么你原来的写法不行?

你在always @(posedge clk)块里用#60 q<=d,会导致:

  • 时钟上升沿触发后,等待60ns再执行赋值,但这个赋值是异步的(不在时钟事件里),会打破同步逻辑的时序规则
  • 如果后续修改时钟周期(比如把#10改成#5,周期变成10ns),#60就变成了6个周期,完全不符合你的延迟需求
  • 综合工具根本无法识别这种固定延迟写法,实际硬件实现时会出错

内容的提问来源于stack exchange,提问作者Ansuman Mishra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 17:43:11