Systemverilog Scheduling semantics

前言

基于《IEEE Standard for SystemVerilog — Unified Hardware Design, Specification, and Verification Language》4章的学习和自己的理解。有不对的地方希望大家补充。 编译工具 Cadence的Xcelium.
实际是主要是《Systemverilog Event Regions Race Avoidance & Guidelines》的学习,
参考资料:
http://www.sunburst-design.com/papers/CummingsSNUG2006Boston_SystemVerilog_Events.pdf
https://blog.csdn.net/kevindas/article/details/103449360

正文

Verilog/Systemverilog 语言是由一系列离散的事件模型组成,通过执行这些离散的事件来推进仿真。这些事件如何在仿真器中进行调度来模拟实际硬件电路中的并发行为就是本章想介绍的,通过理解这些调度可以在coding时规避可能的race condition。

time slot

Processes(进程): systemverilog中并发执行的element,如:initial 块,always块等。
Systemverilog 定义了两类事件(event)。
update event: net、veriable的值的更新。
evaluation event: 当有update event被执行时,所有对update event敏感的进程(Processes) 的执行同样是一个event。

	#1ns a = 1;    //a的值更新为1 就是一个update event
	always@(a or b) begin  
	// a的值发生了更新,a在敏感列表中,从而触发了always块,这个always块就是 evaluation event
		c = a+b;  // c的值的更新是一个update event
	end

time slot: 在这个time slot中这个时间片的所有事件都会在这里被执行,当所有的事件都执行完成后,然后时间推进到下一个time slot。一个time slot 被细分为多个event region。

Race conditions

一个time slot包含了多个event region,首先需要说清为什么要引入event region。
什么是Race(竞争): 就是结果依赖于事件执行的相对时间和相对顺序。Verilog/Systemverilog需要面对两种常见的Race是Hardware Race和simulation race。
Hardware race是芯片工程师最熟悉的概念,这里不做介绍。
什么是simulation race?
仿真引入的race的是由于Verilog/SV采用的event-driven仿真算法产生的,由于仿真器一次只能处理一个event,因此必然会将同一个time slot的event进行排序。但在实际硬件中这些事件是同时发生的,这种仿真与实际硬件的偏差会引起额外Race,但在实际的design中并不存在,因此可能导致仿真与实际design的mismatch。正是因为这个原因Verilog中规定了一个特定的event region必须以任意的顺序来处理,但每个实现都有固定的顺序。

Systemverilog Scheduling semantics_第1张图片

event region

这是Verilog-2001的定义event region
Systemverilog Scheduling semantics_第2张图片
Systemverilog定义的event region, 一共17个region。9个执行SV语句,8个执行PLI的,不考虑PLI,简化图:
Systemverilog Scheduling semantics_第3张图片
其中RTL-desgin相关的region :
Active regions Active, Inactive and NBA regions,避免在Inactvie执行
验证相关的region:
Preponed, Reactive regions (Reactive, Re-Inactive, Re-NBA) and Postponed regions,当然verification的code也可以在Active region中运行
Assertion相关的region:
Preponed, Observed, and Reactive regions

Preponed event region

在Preponed event region,系统对assertion所需的值进行采集,这个region在一个time slot中只执行一次,在一个仿真时间向前推进后立即执行。在实际仿真过程中,工具也可能在上一个time slot的postponed event region进行采样,因为preponed和postponed都是只读region,区别仅仅是仿真时间不同。

Active region集合

首先说明: Active region集合包括:Active、Inactive、NBA 三个region。
在Active region集合中,Module中的阻塞/非阻塞赋值,及module中task/function都在这里执行,Active region集合是为了安排rtl的执行,验证的code也可以写到module中。但为了避免冲突,建议用户将testbench的code写到program中,来隔离rtl与verfiication code的执行

Active events region

在Active中执行和安排RTL中的所有event。
在Active region中用于执行以下的module中的event(不存在顺序):
1. 所有module中的阻塞赋值
2. 计算所有非阻塞赋值的RHS,在NBA region,将计算后的值进行更新到RHS侧。
3. 所有module的连续赋值
4. 针对primitive,计算input的值,更新output的值
5. 执行所有的 d i s p a l y 和 dispaly和 dispalyfinish 命令
在Active region安排以下event:(只是放入到该region,并不是在该region中执行)
1. #0 delay的event到Inactive中
2. 非阻塞赋值LHS的更新

Inactive events region

如果在Active region中event的执行过程中遇到了带有#0的,那么将给event 暂停,并规划在Inactive region中
但实际使用中要避免使用#0。
==============为什么不推荐使用#0 delay? ===============
参考自https://stackoverflow.com/questions/22070608/why-using-zero-timing-0in-verilog-is-not-good-practice
a. designer通常使用#0来避免两个过程块之间存在竞争,#0 会使进程暂停,并在其他的block结束后,在Inactive region开始执行,这样带有#0的block就是最后执行的,但如果有多个block都加了#0,那么谁是最后执行的呢?多个带有#0的block之间就会存在竞争,具体执行顺序就可能与当前程序的运行、编译器等其他因素相关,导致结果不可预测。
b. 带由#0的code可读性非常差,并且无法综合。SV中由其他机制可以解决这种问题:如使用event来控制事件发生的顺序。

NBA events region

对Active region set中的非阻塞赋值的LHS的值进行更新。

active region集合的多次迭代

我们能看到在Active region set中,还有inactive->active, NBA->active 的迭代,为什么会存在?
参考自 https://verificationacademy.com/forums/systemverilog/how-does-forever-get-scheduled-sv-event-region
参考了Dave的答案,试着理解了一下: 所有的event的执行与规划都是在Active region中,比如在Active region中将#0 event安排在Inactive上,在首先执行Active region中的event,然后当目前已有的所有event都被执行过后,开始执行Inactive,将目前Inactive中的#0 event全部push到一次新的Active region,然后在新的Active region中执行之前带有#0的event,而执行#0 event时,可能会出发新的event产生(比如这个更新的值是一个组合逻辑的条件之一),在Active,Reactive中没有新的event后然后执行NBA region,因此整个Active region set会迭代多次。这个在标准中的算法描述也支持了这一点(参考4.5)。Reactive region set 的迭代同样如此。当然这个只是猜测,是不是这样子实际不重要,我们只要知道这三个region干啥的,执行顺序式什么就足够工作的了。
Systemverilog Scheduling semantics_第4张图片

Observed Region

使用preponed的采样值来计算并发断言,但断言最后结果的判定是在Reactive region,这是因为断言结果的判定是一个montior的行为,不允许它去修改desgin的状态。而从Observed->Active的反馈路径是为了 Assertion的expect语句使用,实际使用中这种场景非常少。

Reactive region集合

在Reactive region集合中,Procedural中的阻塞赋值,#0阻塞/非阻塞赋值,及program中task/function都在这里执行。加入Reactive region集合的目的是为了规划驱动testbench的激励,在同一个time slot检查rtl code。

Reactive events region

Reactive与Active region是镜像对称的,Reactive是执行Program中的:
1. 所有program中的阻塞赋值
2. 执行并发断言的pass/fail code
3. 计算所有非阻塞赋值的RHS,在Re-NBA region,将计算后的值进行更新到RHS侧
4. 所有program的连续赋值
5. 执行所有的$exit

Re-inactive events region

Re-Inactive与In-active region是镜像对称的, 为了program中的#0 delay 进行设置的,但为了解决testbench中的race condition风险,举例:在使用fork join来创建并行进程时,可以使用#0来控制执行的顺序。在program中会有一些RTL event执行,这些event 会被安排在NBA region中,这些event很可能会出发RTL中的一些组合逻辑,从而产生新的event,从而在Active region中进行执行,当然这情况只会出现在testbench中使用#0 来trigger RTL的信号。

Re-NBA events region

Re-NBA与NBA region是镜像对称的,执行在program中的更新非阻塞赋值的LHS。

Postponed Region

在这个region执行 s t r o b e 和 strobe和 strobemonitor命令。

function coverage的采样点

function coverage 中有一个option: strobe 用于控制采样时刻:
Systemverilog Scheduling semantics_第5张图片

reg xclk;			|	always @(posedge xclk)begin |	covergroup test1_cg @(posedge xclk);
reg [3:0] 	a=0;	|		a <= 3;					|		coverpoint a;
reg	[3:0]	b=0;	|	end							|		coverpoint b;
initial begin		|	always @(posedge xclk)begin	|		type_option.strobe = 1;
	xclk = 0;		|		b = 3;					|	endgroup
	#10 xclk = 1;	|	end							|	covergroup test2_cg @(posedge xclk;
end					|								|		....//strobe = 0;
					|								|	endgroup

采样结果: test1_cg 采样到a=3, b=3; test2_cg 采样到 a=0, b=3;
test1_cg的结果容易解释,在postponed region 采样,ab值发生了变化。
test2_cg的结果:猜测在clocking event trigger时,此时a 是非阻塞赋值,在NBA region 才更新值,因此a=0,b是阻塞赋值,此时的b=3和采样是两个并行的进程,顺序在active region是任意的,因此可能采到0,可能采到3。所以在module中如果定义了covergroup,sample时需要注意此时的值是否稳定,是否会有race问题。

1step

首先什么是step: 在整个编译文件中使用`timescale或者timeprecision定义时间精度中的最小的就是1step。使用#1step可以在进入当前的timeslot前进行采样,等同于在当前timeslot的prepone上进行采样。
1. 在clocking block(使用clocking, endclocking作为关键字,主要是在interface中使用),input信号默认使用#1step来采样,output信号默认delay为 0。
2. 在并发断言中,断言中的变量的值在prepone进行采样,断言在Observed region进行计算,在Reactive region判断断言成功/失败。如果断言中的变量是clocking block中的输入信号,则必须采样带有#1step的clocking block的输入信号。实际是无论信号是否在clocking block中,断言采样在#1setp和prepone中没有任何区别

如果所有编译文件定义了相同的时间精度,那么#1 = #1step,但如果有新的时间精度文件加入,#1就可能不等于#1step,所以#1是局部时间精度的函数,#1step是全局的。 注意2个time slot之间并不是只有1个step,可能是多个。
Systemverilog Scheduling semantics_第6张图片

你可能感兴趣的:(systemverilog)