SV精通2 数据的采样和驱动

4 篇文章 0 订阅

竞争问题

race1

对模块race1进行编译仿真
race1代码

问题:通过查看打印信息,clk1和clk2在45ns上升沿采样到的d1的数值分别为多少?
答案:clk1:1; clk2:2
打印结果:
display

波形

45ns+0
45ns+1
为什么波形的数据和打印的数据不一致呢?

原因分析

  • 默认情况下,时钟对于组合电路的驱动会添加一个无限最小时间Δcycle的延迟,Δcycle比仿真的时间精度还小
  • 在一个时间片time-slot中可以发生很多事情,run 0ns即是让仿真器运行一个Δcycle的时间
    显示出Δcycle
    先后点击上面两个按钮即可看到真实硬件变量之间准确的时序先后关系:
    clk2是用一个组合逻辑跟着clk1跳转的,所以clk2要比clk1晚一个Δcycle(45ns+0→45ns+1,"1"代表一个Δcycle),d1同理,所以clk2与d1是同步的。
    clk1采对了,clk2没采对,要在d1稳定前采样,即clk1到45ns的上升沿之前采样(产生Δcycle之前)。

如何避免采样的竞争问题?

clk与被采样数据之间如果有若干个Δcycle的延迟,那么采样可能会存在问题,例如上例中clk1与clk2在同一时刻(仿真器认为的同一时刻)对d1的采样不同,因此应当消除竞争问题来提高采样准确性:

  1. 采样:对于采样时存在Δcycle延迟的信号,在采样事件前的某段时刻(如1ps)进行采样,来模拟建立时间的采样要求
  2. 驱动:在驱动时添加人为延迟(如1ps),通过放大clk与变量之间的延迟来模拟真实的延迟行为

时钟块

SV中主要通过接口中的clocking对信号做采样和驱动
定义时钟块
以上代码为clocking时钟块的声明:

  1. 声明一个名为bus的clocking,敏感事件为clock1上升沿
  2. 默认在clock1上升沿前10ns进行采样,clock1上升沿后2ns做驱动
  3. 变量data ready enable为采样信号
  4. 自定义驱动事件(clock1下降沿后2ns),覆盖原有的默认时间(clock1上升沿后2ns)
  5. 自定义采样事件,为clock1上升沿前1step(1step为最小时间单位),采样到的是上个周期的数据

利用时钟块采样和驱动波形图
bus采样和驱动行为如上波形图所示

利用clocking块做采样

clocking1代码
clocking可以定义在interface module program中
clocking1波形
第一个forever语句:利用clk直接对vld采样
第二个forever语句:利用clk和clocking1联合对vld采样
(@ck==@clk posedge)
clocking1输出结果

将采样偏移量抽象为物理中的建立时间,要求在时钟上升沿前一段时间数据不能有变化;
上图中的“采样vld"和“采样ck_cld"中,值的变化均发生在时钟上升沿,但采样点不同

利用clocking块做驱动

clocking2代码
clocking2输出结果
clocking2仿真波形

clocking通过类似于物理保持时间的驱动方式来实现时钟沿叠加偏移量的延迟驱动效果;
时钟沿上升沿触发赋值,但是数据真正生效是在上升沿叠加偏移量的时间点

总结

为了从根本上消除采样竞争问题(也更能体现时钟和信号间的时序关系):

**

  1. 采样环节模拟建立时间,提前采样
  2. 驱动环节添加固定延迟,驱动延迟生效(时钟沿叠加延迟后生效)

**

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值