Dskpimc? · 2023年04月21日 · 北京市

Systemverilog中Clocking blocks的记录

1. clocking block的作用

Clocking block可以将timing和synchronization detail从testbench的structural、functional和procedural elements中分离出来,因此sample timming和clocking block信号的驱动会隐含相对于clocking block的clock了,这就使得对一些key operations的操作很方便,不需要显示使用clocks或指定timing。这些操作如下:

  • Synchronous events
  • Input sampling
  • Synchronous drives

Clocking block拥有declaration和instance一体化,也就说在declaration的时候,就已经实例化了,不需要再做一遍了。多个clocking blocks不能嵌套,且clocking block不能声明在function、task、package或compilation unit的所有声明之外。Clocking block只能声明在module、interface、checker或program里。

2. clocking block中signal_identifier的input/output

Clocking block中指定为input方向signal只能被read,不能被write;

Clocking block中指定为output方向signal只能被write,不能被read;

Clocking block中指定为inout方向signal既能被read,也能被write;inout拥有input和output两种属性,它在本质上会同时定义两个相同名字的input和output。

3. clocking skew

Clocking skew决定了一根signal在距离clock event有多少time units后被sampled或driven的。Input skews隐含为负数的,也就意味着总是在clock event之前发生的,output skews总是在clock event之后发生的。

Clocking event可以用edge,而不是一个数字来指定的。

可以采用default来将一个clocking skew应用到整个clocking block。

input指定#0 skew应该在corresponding clocking event时采样,但为了避免冲突,它们会在Observed region采样。相似的,对于output带有#0 skew或没有skew,那它们会在re-NBA region时驱动。

如果input没有显示指定#0,那么采样值会在clocking event之前的postponed region的sample的。这里有个注意点:如果clocking event是在program里的执行程序触发的,那么clocking event和sample value之间存在竞争关系,只有clocking event在module里更新才不会有竞争关系的。

在处理clocking event时,clocking block应先更新自己的sampled values,然后采取trigger与它相关的event事件。event应该在observed region时触发,因此一个正在等clocking block的process可以保证读到updated sampled value。
1.png

4. cycle delay:image.png

image.png可以控制delay特定的clocking event或clock cycle的个数之后,才继续执行。例如:
image.png

5. Synchronous events

显示的同步可以通过event control operator (@) 来控制的,这样会允许一个process等待一个特别信号值的变化或一个clocking event。例如:

@(negedge dom.sig1 or posedge dom.sig2);

@(posedge ram_bus.enable);

@(edge dom.sig1);

@(ram_bus) // ram_bus is clocking bloc

6. Delay control

在赋值语句中有两种delay的控制方法,分别为intra-assigment delay和procedural cycle delay。

intra-assignment delay的形式如下:

bus.data <= #4 r; //等价于:temp = r; #4 bus.data <= temp; 也就是说在#4之前就搞好值了,只不过在#4之后才把赋值的

Procedural cycle delay的形式如下:#2 bus.data <= 2; //也就是说在#2之后,才会计算右边的值,并赋值的

在对clocking block里的signals进行赋值时,intra-assignment只能用cycle delay(##)的,不能用常规的delay(#),如下:
image.png

对于clocking block中信号的赋值可能在非clocking event时被执行到,这样的drive statements应该没有blocking的执行,但drive的值应该是在下一个clocking event到来时才生效的。也就是说右边的值在执行到时马上计算评估出来,但是drive的处理是被delay了,直到下一个clocking event的事件到来时。例如:
image.png
对于clockvar(clocking block中的signal)的写只能用synchronous drive语法,用其他方式会报错。因此,在任何的continuous assignment、force statement、procedural continuous assignment去写clockvar是非法的。

7. Drives and nonblocking assignments

Clocking block里的信号必须用<=这种赋值符号,否则编译会报错,我猜想跟clocking block里drive的值是在re-NBA生效有关的吧。
image.png

尽管clocking block的synchronous drives语法operator和nonblocking variable assignment一样,但它们本质上有点区别的:

区别1:clocking block的赋值不支持intra-assignment的delay syntax,它要求delay syntax必须是cycle delay(##)。

区别2(重要):clocking block的synchronous drives给inout clockvars时不改变clocking block的input,这是因为input总是在最后才会被sampled更新的,而不是在驱动时更新的。例子如下:

image.png

用以上例子来比较下clocking block和regular variable在驱动和采样上的区别:

首先是上述的clocking block,a信号在re-NBA时才会被驱动的,b表达式右边的a在上一time step时已经采样了,在当前step还没有被更新,因此b仍然用的是旧值(看input skew,#0则在observed时,非#0则在更之前采样的(如#1step则是在上一个step的postponed采样))。

然后说下如果是regular variable,a和b没有在clocking block里,因为a和b的驱动是在module里的话,那么a和b会在NBA执行,如果在program里驱动的话,那么a和b会在re-NBA里执行。对于b右边表达式a的值,如果在module里的话,会用active时的值,如果在program,会用reactive的值。

作者:谷公子
文章来源:CSDN

推荐阅读

更多Arm AMBA 协议集技术干货请关注Arm AMBA 协议集技术专栏。
迎添加极术小姐姐微信(id:aijishu20)加入技术交流群,请备注研究方向。
推荐阅读
关注数
19610
内容数
1303
主要交流IC以及SoC设计流程相关的技术和知识
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息