一、SystemVerilog中的采样和数据驱动问题?
首先我们要明白在采样和数据驱动的过程中会具体会出现什么问题
1)采样过程:原本是想在时钟上升沿采集数据的,结果采样的值却是上升沿之后的数据。
2)数据驱动:不清楚数据是在上升沿之后驱动数据还是之前。
造成以上问题的本质是竞争问题,那如何解决竞争问题呢?
1)首先加入适当的延迟,明确驱动与时钟,采样信号与时钟的先后关系,避免竞争问题的产生,但这并不是一个好的选择。
2)在接口中使用clocking块。(以下将主要介绍clocking块)
首先又一个问题我们在RTL仿真时,为什么clk的上升沿与驱动信号的变化时刻一样呢?如何辨别两者的先后关系?
因为在RTL仿真时是理想的仿真没有加入门延迟与组合逻辑延迟,并不是后仿真,因此在理想中clk与驱动信号变化的时刻是一样的,但实际上当然是不一样的。
那如何在RTL前仿真中看见clk信号与驱动信号的先后关系呢?
可以使用delta-cycle模式,在默认情况下,时钟对于组合电路的驱动会提加一个最小的时间(delta_cycle)的延迟,即先后时钟信号变化再延迟一个delta_cycle后才会有驱动信号。
那么什么是delta_cycle呢?
delta_cycle是一个无限小的时间单位,比最小的时间单位精度还小,无法用绝对时间单位来描述,在仿真中敲入run 0;即是让仿真器运行一个delta_cycle。
那么知道delta_cycle有上面作用呢?
根据上面的分析我们可以知道其实delta_cycle可以帮助我们理解在“同一时刻”的采样或者驱动的先后逻辑关系!!!
所以由于各种可能性,clk于被采样数据之间如果存在delta-cycle的延迟,那么采样的数据可能会存在问题,会造成在同样的时刻对同一数据进行采样,却会得到不同的采样结果(比如都在45ns但有45ns+ 0 delta_cycle 与 45ns+ 1 delta_cycle),因此采样数据中的竞争问题会成为潜在困扰仿真采样准确性的问题。
那如何避免采样的竞争问题?
1)在驱动时、添加相应的人为延迟,模拟真实的延迟行为,同时加代clk与变量之间的延迟,一次提高DUT使用信号时的准确性和TB采样信号时的可靠性!
2)对于一些采样时刻依然存在delta_cycle延迟的信号,我们还可以依靠在采样时间前的某段时刻中进行采样来模拟建立时间。
具体方法?
在接口中引入了clocking块,clocking块会模拟信号的建立与保持时间,合适的建立与保持时间将有效地避免竞争与冒险现象。
clocking bus @(posedge clock1);
default input #10ns output #2ns; //input 后面的延迟代表的是负值 --采样,output--驱动模拟建立保持时间,后面的延迟代表的是正指 input后的延时代表时钟沿的前时刻,output后的延时代表时钟沿的后时刻。
input data,ready,enable; //声明采样信号,采样上述定义的默认时钟上升沿之前10ns采样
outout negedge ack;//声明驱动信号,在时钟下降沿完成驱动,覆盖前面默认的驱动时刻
input #1step addr;//声明采样信号,在时钟上升沿的前一个时间片采样,保证采样到的数据是上一个时钟的数据,会覆盖默认的采样时刻
endclocking
使用时钟块需要注意的点!!!
1)clocking块不仅可以定义在interface中,也可以定义在module和program中。
2)clocking中列举的信号不是自己定义的,而是由interface或者其他模块定义的,所以说clocking块中的信号是声明而不是定义。
3)clocking声明时钟块的名字之后 与触发条件,需要加上默认的采样与驱动时刻,即 default input #delay output #delay;如果不加上则默认采样时刻是#1step即时钟沿的前一个时钟片采样,然后在采样时候#0进行驱动。
4)处理定义默认的采样和驱动事件,也可以在定义信号方向时,用新的采样或者驱动事件对默认事件进行覆盖.