You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在结构化Verilog中引入延迟?含ADDR与WR时序约束实现问询

嗨,咱们一步步拆解你关于结构化Verilog中引入延迟,以及实现特定建立时间需求的这两个问题:

1. 结构化Verilog中引入延迟的常用方法

结构化Verilog主要基于门级原语、模块实例化和数据流描述搭建电路,引入延迟的方式主要有以下几种,需要注意的是:这些延迟主要用于仿真验证,大部分综合工具会忽略它们——实际硬件的延迟由工艺、布局布线决定,不能依赖代码延迟实现硬件功能:

  • 门级原语自带延迟:在实例化与门、或门、触发器等基础门原语时,直接添加延迟参数。比如:

    // 定义时间尺度:1ns为单位,1ps为精度
    `timescale 1ns/1ps
    // 与门实例,信号从输入到输出延迟2ns
    and #(2) and_inst(output_wire, input1, input2);
    // 也可以分别指定上升、下降、关断延迟:#(上升延迟, 下降延迟, 关断延迟)
    nand #(1, 2, 3) nand_inst(out, a, b);
    
  • 线网延迟:直接给线网类型变量定义延迟,信号在这条线上传播时会延迟指定时间:

    // data_wire上的信号变化会延迟3ns才传递到连接的模块/门
    wire #(3) data_wire;
    
  • 数据流延迟(assign语句):在assign的数据流描述中添加延迟,属于结构化Verilog的范畴,适合组合逻辑的延迟建模:

    // input信号经过1ns延迟后赋值给output
    assign #1 output_wire = input1 & input2;
    

2. 实现ADDR相对于WR上升沿1ns的建立时间需求

根据你的需求:时钟周期10ns,每个周期内先给ADDR赋值,1ns后将WR从0置为1,同时满足ADDR在WR上升沿前1ns稳定的建立时间约束。以下是两种可行的实现方式:

方式1:结合时钟的行为建模(符合结构化设计逻辑)

这种方式用时钟触发的always块控制时序,清晰贴合需求:

`timescale 1ns/1ps

module addr_wr_controller(
    input         clk,
    input  [7:0]  addr_in,
    output reg [7:0] ADDR,
    output reg    WR
);

// 每个时钟上升沿触发,对应10ns的周期
always @(posedge clk) begin
    // 时钟上升沿立即为ADDR赋值,保证信号稳定
    ADDR <= addr_in;
    // 延迟1ns后将WR从0置为1,刚好满足ADDR的建立时间要求
    #1 WR <= 1'b1;
    // 为了让WR在下一个周期可以重新触发,在周期结束前(第9ns时)拉低WR
    #8 WR <= 1'b0;
end

endmodule

解释:时钟上升沿(周期起点)时ADDR先完成赋值,1ns后WR触发上升沿,此时ADDR已经稳定了1ns,完美满足建立时间约束。之后再过8ns(离下一个时钟上升沿还有1ns)将WR拉回0,确保下一个周期的时序可以正常触发。

方式2:门级延迟组合实现

如果更偏向纯结构化门级设计,可以用延迟线和触发器组合:

`timescale 1ns/1ps

module addr_wr_controller(
    input         clk,
    input  [7:0]  addr_in,
    output [7:0]  ADDR,
    output        WR
);

// 用D触发器(结构化原语)实现ADDR的时钟同步赋值
dff addr_dff(
    .clk(clk),
    .d(addr_in),
    .q(ADDR)
);

// 生成WR信号:时钟上升沿延迟1ns后输出高电平
wire clk_delayed;
assign #1 clk_delayed = clk;

// 用与门和寄存器控制WR的电平,确保每个周期内WR只在1ns后变高并保持
reg wr_reg;
always @(posedge clk) begin
    wr_reg <= 1'b1;
end
always @(negedge clk_delayed) begin
    wr_reg <= 1'b0;
end
assign WR = wr_reg;

// 简单D触发器原语定义(如果工具自带可以不用写)
module dff(input clk, input d, output reg q);
    always @(posedge clk) begin
        q <= d;
    end
endmodule

注意:代码中的延迟是为了在仿真中复现这个时序关系,实际硬件项目中,建立时间约束需要通过综合工具的时序约束命令(比如set_setup)来指定,由工具自动布局布线保证时序合规。

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

火山引擎 最新活动