Verilog 延时模型

关于Verilog 延时模型的学习笔记。

1 连续赋值延时

给连续赋值的延时值指定了 赋值运算符右侧操作数数值改变 到 左侧操作数完成赋值 需要的时间。
变为上升沿、下降沿、高阻态的延时可以配置为不同值。

需要区分两种延时赋值:

  1. 为连续赋值语句指定延时值。延时是连续赋值的一部分。
  2. 在net声明时指定的Net delay,然后对net进行连续赋值。

1.1 Net类型声明中的定义延迟(Net delay)

IEEE Verilog 2005标准的 Net 类型定义语法:

在这里插入图片描述

每个net最多可以指定3个延时值,对于gate和net来说,当没有给定延时值,默认值default delay为0。其他情况:

  • 当给定一个延时值,这个延时指定所有传播延时。
  • 当给定两个延时值,第一个值指定上升沿延时,第二个值指定下降沿延时。信号变为高阻抗或未知时的延迟应为两个延迟值中较小的一个。
  • 当给定三个延时值:
    • 第一个延时值用于转变为1的情况(上升沿延时)
    • 第二个延时值用于转变为0的情况(下降沿延时)
    • 第三个延时值用于转变为高阻态的情况。

例子:

and #(10) a1 (out, in1, in2); // only one delay
and #(10,12) a2 (out, in1, in2); // rise and fall delays
bufif0 #(10,12,11) b3 (out, in, ctrl);// rise, fall, and turn-off delays

延时值可以指定为 min:typ:max 格式。最小延迟、典型延迟和最大延迟的表达式之间没有必要的关系(例如,min≤typ≤max)。它们可以是任意三个表达式。

例子:

module iobuf (io1, io2, dir);
. . .
bufif0 #(5:7:9, 8:10:12, 15:18:21) b1 (io1, io2, dir);
bufif1 #(6:8:10, 5:7:9, 13:17:19) b2 (io2, io1, dir);
. . .
endmodule

例子:

// 声明
wire #(5, 1) wireA;  

assign wireA = b; 的仿真结果(时间单位:1ns):

Net delay 值为(5, 1),意味着无论wireA改变为1有一个5单元的延时,改变为0有一个1单元的延时。

在这里插入图片描述

1.2 连续赋值过程定义延迟

这种延时是连续赋值的一部分,不会影响其他语句的赋值。

连续赋值语法:

在这里插入图片描述

如果在前一个操作数的更改传播到左操作数之前,右操作数发生了更改,则需要执行以下步骤:

  1. 计算右侧表达式的值。
  2. 如果右侧的值与当前计划传播到左侧的值不同,则取消当前计划的传播事件。
  3. 如果新的右侧值等于当前左侧值,则不计划任何事件。
  4. 如果新的右侧值与当前左侧值不同,则使用左侧的当前值、右侧的新计算值和语句上指示的延迟,以标准方式计算延迟;然后,计划在未来的延迟时间单位内发生新的传播事件。

例子:

assign #5 a = b;

仿真结果(时间单位:1ns):
在这里插入图片描述

0ns:新的右侧值(0)与当前左侧值(x)不同,计划5ns后延时赋值为0。
5ns:右侧值赋给左侧值。
6ns:新的右侧值(1)与当前左侧值(0)不同,计划5ns后延时赋值为0。
11ns:右侧值赋给左侧值。
12ns:前一个操作数的更改(0)传播到左操作数之前,右操作数发生了更改(1),取消将0传播过去,并计划5ns后延时赋值为1。13,14,15,16,17ns进行相同的操作。
17ns:计划5ns后延时赋值为0。
22ns:17ns-22ns右侧数值没有改变,成功赋值为0。

右侧更新数据后等待期间如果发生了数据改变,则刷新等待时间,即只有持续延时时间的信号会被延时赋值给左侧。

2 过程赋值延时

2.1 延时结构 位于语句之前

过程赋值延时 作为 过程性时序控制的一种。

过程性时序控制语法:
在这里插入图片描述

延迟控制后的程序性声明的执行相对于延迟控制前延迟规定的延迟值。如果延迟表达式的计算结果为未知或高阻抗值,则应将其解释为零延迟(转变为0的延时)。如果延迟表达式的计算结果为负值,则应将其解释为与时间变量大小相同的二进制补码无符号整数。在延迟表达式中允许指定参数。参数可以被SDF注释覆盖,在这种情况下,将重新计算表达式。

例子1:将赋值的执行延迟10个时间单位:

#10 rega = regb;

例子2:提供了一个数字符号(#)后面的表达式。赋值的执行延时表达式的值所指定的延迟值。

#d rega = regb; // d is defined as a parameter
#((d+e)/2) rega = regb; // delay is average of d and e
#regr regr = regr + 1; // delay is the value in regr

#5 rega = regb; 的仿真结果:

在这里插入图片描述

2.2 延时结构位于语句中

赋值语句内(intra-assignment)的延时和事件控制 包含在一个赋值语句中,并以与上述不同的方式修改活动流。

一个赋值内部延迟或事件控制会延迟将新值赋值到左边,但是右边的表达式应该在延迟之前赋值,而不是在延迟之后。

也就是说:

  • 赋值语句内的延时提前计算好值,然后在延时后赋值。
  • 位于语句之前的延时在延时值后计算然后赋值。

语法:
在这里插入图片描述

赋值内部延迟和事件控制可应用于阻塞赋值和非阻塞赋值。repeat事件控制应指定指定事件发生次数的赋值内延迟。

下表说明了赋值内部时序控制的原理,展示了在不使用赋值内部的情况下等效代码。

在这里插入图片描述

intra-assignment 延时控制的例子:防止竞争
统一时刻给a,b赋值,会产生竞争:

fork
    #5 a = b;
    #5 b = a;
join

使用 intra-assignment 延时控制防止竞争:

fork // data swap
    a = #5 b;
    b = #5 a;
join

b与a当前时刻的值会临时存储,然后在延时值后将临时值赋值。

在这里插入图片描述

3 总结

  • wire #(5, 1) wireA; :这种定义被称为 Net delay ,当这个网表值发生改变就需要延时赋值。
  • assign #5 a = b;:右侧更新数据后等待期间如果发生了数据改变,则刷新等待时间,即只有持续延时时间的信号会被延时赋值给左侧。
  • #5 rega = regb;:延时值计算右侧值然后赋给左侧。也可用于非阻塞赋值。
  • rega = #5 regb;:先计算出右侧值,延时后将结果赋给左侧。也可用于非阻塞赋值。

注意assign a = #5 b;是语法错误。

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lu-ming.xyz

觉得有用的话点个赞吧 :)

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值