SystemVerilog验证 测试平台编写指南 第七章 线程以及线程间的通信

7.1 线程的使用
Verilog:begin…end中的语句以顺序方式执行,fork…join中的语句则以并发方式执行。
System Verilog:引入两种新的创建线程的方法——使用fork…join_none和fork…join_any语句。
fork…join_none块在调用其块内语句时,父线程继续执行。
fork…join_any块在调用其块内语句时,当第一个语句完成后,父线程才继续执行,其它停顿的线程也得以继续。
在这里插入图片描述
fork…join:所有语句块都执行完后才能继续块后续的处理。
fork…join_any:当第一个语句(所有进程中运行最快的一个)完成后,父进程才继续执行。
fork…join_none:父进程与其同时执行。
begin…end:顺序执行,通常有嵌套在fork语句当中。

在类中创建线程,使用fork…join_none可以开启一个线程。
线程中的自动变量:在fork…join_none语句中使用自动变量来保存变量的拷贝。
当你使用循环来创建线程时,如果在进入下一轮循环之前没有保存变量值,便会碰到一个常见却又难以被发现的漏洞。通常使用automatic来避免这个问题。自动变量可以在program中声明。
当有多个线程,部分线程运行时间较长时,使用wait fork语句来等待所有的子线程结束。
disable语句可以用于停止System Verilog中的线程。
7.2 停止线程
停止单个线程:disable
==停止多个线程:disable fork ==
通过带有标号的disable来明确指定你想要停止的进程。
7.3 线程间的通信
数据交换和控制的同步被称为线程间的通信(IPC)。在System Verilog中,可使用事件、旗语和信箱来完成。
7.4 事件
在Verilog中,@操作符是边沿敏感的,它总是阻塞着,等待着事件的变化。其他的线程可以通过->操作符来触发事件。
SystemVerilog引入了triggered()函数,可用于查询某个事件是否已经被触发,包括在当前时刻。线程可以等待这个函数的结果,而不用在@操作符上阻塞。
7.5 旗语
旗语有三种操作。=使用new方法可以创建一个带单个或多个钥匙的旗语,使用get可以获取一个或多个钥匙,而put则可以返回一个或多个钥匙。
可以将旗语看成是一把钥匙,谁拥有钥匙谁就对资源具有使用的权利。旗语可以被视为一个互斥体,用于实现对同一资源的访问控制。
一个线程如果请求钥匙而得不到的话,就会一直阻塞。多个阻塞的线程会以先进先出(FIFO)的方式进行排队。
如果只有一把钥匙,第一个线程请求两把,第二个线程请求一把,这时先进先出的原则就会被忽略掉,第二个线程会排在第一个线程前面。
你返回的钥匙可以比你取出来的多。
semaphore sem;创建一个旗语
sem = new(1);分配一把钥匙
sem.get(1);获取一把钥匙
sem.put(1);返回一把钥匙
try_get();获得钥匙而不被阻塞,返回1表示有足够多的钥匙,返回0则表示钥匙不够。
7.6 信箱
SystemVerilog中的信箱,解决两个线程间的传递。从硬件角度理解,可以看成一个具有源端和收端的先进先出FIFO。源端把数据放进信箱,收端把数据取出信箱。
信箱是一种对象,必须调用new函数进行实例化。例化时有一个可选的参数size,用以限制信箱中的条目。如果size是0或者没有指定,则信箱是无限大的,可以容纳任意多的条目。
使用put任务可以把数据放入信箱 ,使用get可以移除数据。如果信箱为满,则put会阻塞;而信箱为空,则get会阻塞。peek任务可以获取对信箱里数据的拷贝而不移除它。
7.7 构筑带线程并可实现线程间间通信的测试程序

发布了38 篇原创文章 · 获赞 29 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_45270982/article/details/95882380