IC验证学霸笔记3——SV 过程块和方法

1.过程语句

1.1 initial

initial 过程块在进行仿真时从模拟0时刻开始,在仿真过程中只执行一次,执行完一次后该initial语句块被挂起,不再执行。如果一个模块中存在多个initial语句块,则每个initial语句块都是从0时刻开始执行;initial语句块内部的多条执行语句可以顺序执行,也可以并行执行。

initial从其执行路径的属性来看,他不应该存在与硬件设计代码中,它本身不可综合,对于电路的描述没有任何帮助。

在Verilog中,所有测试语句都可以放在initial中,为了便于管理测试顺序,建议将有关测试语句都放置在同一个initial过程中。

initial 过程块可以在module,interface 和 program中使用。

1.2.always

从语法描述角度而言,相对于initial过程语句,always过程语句的触发状态是一直存在的,只要满足always后边的敏感事件列表,就执行语句块。
敏感事件为触发条件,当满足时,语句块开始执行。所以敏感列表中应该列出影响块内赋值的所有信号,对于两个或以上,用 or 或者 “," 连接。
所以说,always过程块是用来描述硬件时序电路和组合电路的正确打开方式,因此只可以在module或者interface中使用。

always语句块可以被细分为:

always_comb:组合逻辑语句块

always_latch:锁存逻辑语句块

always_ff: 时序逻辑语句块

1.2.1 always_comb
1.always_comb 语句块会在仿真0时刻开始自动执行一次,不管执行敏感列表语句是否有被触发。
2.always_comb 自动嵌入敏感列表;

3.always_comb 禁止变量共享,即赋值左侧的变量无法被同一个过程块赋值;

4.系统会在仿真时时自动检查该语句块,如果其所表示的不是组合逻辑,系统会发出警告。


1.2.2 always_latch

1.always_latch表示锁存逻辑,且自动插入敏感列表;

2.系统会在仿真时时自动检查该语句块,如果其所表示的不是锁存逻辑,系统会发出警告。

注意:在一般的同步设计中是不允许(或至少不推荐)使用latch式设计.

1.2.3 always_ff
1.always_ff用来表示时序逻辑

2.敏感列表必须指明posedge 或negedge,才能使得EDA工具实现同步或者异步复位逻辑。

3. EDA工具会验证always_ff语句块是否实现了时序逻辑。

2.语句块

2.1 串行语句块

串行语句块采用的关键字”begin...end",其中的语句按串行方式顺序执行,可以用于可综合电路和仿真测试程序。

1.串行语句块中的每条语句依据块中的排列次序逐条执行。块中每条语句给出的延迟时间都是相对于前一条语句执行结束的相对时间。

2.串行语句块的起始执行时间就是串行语句块中第一条语句开始执行的时间;串行语句块的结束时间就是块中最后一条语句执行结束的时间。

2.2 并行语句块

并行语句块采用的关键字”fork...join",其中的语句按并行方式执行,只能用于仿真测试程序,不可用于可综合电路设计。

1.并行语句块中的每条语句同时执行。即程序流程控制已进入到该并行语句块,块内语句则同时开始执行。

2.块内每条语句的延迟时间是相对于程序流程控制进入到块内的仿真时间。

在SV中,经常用到 fork...join_none 和 fork...join_any

fork...join : 等待所有fork中的线程结束再退出
fork...join_any: 只要有一个fork中的线程结束程序就可以退出,执行外边的其他语句,但是fork中未执行完成的线程还可以继续执行。
fork...join_none: 程序开始就可以退出,执行外边的其他语句,但是fork中未执行完成的线程还可以继续执行。

在使用了fork...join_any 或 fork...join_none以后,可以使用disable来指定需要停止的线程。

3.方法和函数

二者区别最重要的一点是,任务task可以消耗时间而函数function不能。也就是说在函数里边不能出现带有诸如#100的时延语句或诸如@(posedge colock),wait(ready)的阻塞语句,当然也不能调用任务。另外,Verilog中函数必须要有返回值,且返回值必须被使用。

3.1 function

在SV 中,function可以在参数列表中指定参数传输方向(input输入参数,output输出参数,inout输入输出参数,ref引用参数),默认为input,可以返回数值(return)或者不返回数值(void)。
除此之外,function还有一下属性:

1.默认的数据类型为logic;

2.数组可以作为形式参数传递;

3.只有数组变量可以在形式参数列表中声明为ref类型,线网类型不能声明为ref类型;

4.在使用ref时,有时候为了保护数据对象只被读取不被写入,可以通过const的方式限定ref声明的参数。  

3.2 task

task无法通过return返回结果,只能通过output、inout或者ref的参数返回。

task内部可以置入耗时语句,如@event、wait event、# delay;

4 子程序参数

缺省的类型和方向是:logic input

V对参数的处理方式很简单:在子程序的开头把input和inout的值复制给本地变量,在子程序退出时则复制output和inout的值。

SV中,参数的传递方式可以指定为引用而不是复制,ref参数类型比input,output,inout更好用。

ref参数:

只能被用于带自动存储的系统中,ref在任务里可以修改变量而且修改结果对调用它的函数随时可见。如:
一旦bus.enable有效,初始化块中的thread2马上就可以获得储存器的数据,而不用等到bus_read任务完成总线上的数据处理后返回,这可能需要等待若干个周期。由于参数data是以ref方式传递的,所以只要任务里的data一有变化,@data语句就会触发。如果把data声明换成output,则@data语句就要等到总线处理完成后才能触发。


注:优秀验证学员随堂笔记,已经征求到学生的同意,会持续给牛友们分享!
大家看完记得 一键三连!多多支持

#深度学习##做项目##转行转岗经验分享##芯片IC验证工程师##你为什么选择硬件行业#
全部评论
学到了,非常感谢楼主的细心整理
点赞 回复 分享
发布于 2022-08-30 20:55 陕西

相关推荐

评论
2
3
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务