SV多线程通信
1.线程的使用
Verilog中对语句分组使用: begin...end(顺序执行) fork...join(并发执行)
System Verilog中引入两种新的创建线程的方法: fork...join_any fork...join_none
begin...end与fork...join可以相互嵌套。在begin...end内部语句串行执行,在fork...join内部语句并行执行,fork...join_any在其中内部任一语句执行完成后继续执行块外的内容,块内没执行完的继续执行。fork...join_none在其中内部语句执行时同步执行块外的内容。
2.event
事件是静态的同步对象句柄(可以像参数一样在子程序中传递),它用 来同步多个并发的进程,比如某个进程等待着事件,而另一个进程则触发这个事件。 事件的触发和阻塞等待
触发: -> event_handle
等待:@event_handle or wait(event_handle.triggered) @操作符是阻塞的,也就是说过了操作的时间点,如果没有捕捉到,那么就会被阻塞在那里, 直到下一次到来。如果没有下一次,就一直阻塞。 在SV中,引入了triggered属性,该属性可用于查询事件是否已经被触发,而不是只检测当 前时刻,线程只等待该结果,而不是在@处阻塞。
特征:可以被赋值给其它事件;这样两个事件变量(句柄)会指向同一个对象,触发任意一个变量 就触发这个事件
可以传给队列,函数和任务
1 event eve; 2 event tmp; 3 4 initial begin 5 tmp = eve; 6 #10 -> tmp; 7 end 8 9 initial begin 10 wait(eve.triggered); 11 $display("@%0t : event eve receive trigger",$time); 12 end
@10 : event eve receive trigger //执行结果
1 program automatic test(); 2 3 event e1,e2; 4 initial begin 5 $display("@%0d:1:before trigger",$time); 6 -> e1; 7 @e2; 8 $display("@%0d:1:after trigger",$time); 9 end 10 11 initial begin 12 $display("@%0d:2:before trigger",$time); 13 -> e2; 14 @e1; 15 $display("@%0d:2:after trigger",$time); 16 end 17 18 endprogram
因为触发是瞬态的,因此按先后顺序,只有 @e2是可以触发的,另一种就没了,仿真结果 如下: @0:1:before trigger @0:2:before trigger @0:1:after trigger 如果调换两个initial块的顺序,则输出: @0:2:before trigger @0:1:before trigger @0:2:after trigger 由此我们也可以知道timeslot中initial块 是有执行顺序的,顺序为自上而下。
1 program automatic test(); 2 event e1,e2; 3 initial begin 4 $display("@%0d:1:before trigger",$time); 5 -> e1; 6 wait(e2.triggered); 7 $display("@%0d:1:after trigger",$time); 8 end 9 10 initial begin 11 $display("@%0d:2:before trigger",$time); 12 -> e2; 13 wait(e1.triggered); 14 $display("@%0d:2:after trigger",$time); 15 end 16 endprogram
因为e1先触发,因此wait (e1.triggered)先实现,先打印2再 打印1,因此仿真结果如下: @0:1:before trigger @0:2:before trigger @0:2:after trigger @0:1:after trigger
1 module tb; 2 event a, b, c; 3 initial begin 4 #10 -> a; 5 #10 -> b; 6 #10 -> c; 7 end 8 initial begin 9 wait_order (a,b,c) 10 $display ("Events were executed in the correct order"); 11 else 12 $display ("Events were NOT executed in the correct order !"); 13 end 14 endmodule
wait_order阻塞等待多个事件的触发,并且 要求这多个事件按照用户决定顺序触发。 wait_order可以和else一同使用,当多个事件 按顺序触发时,执行wait_order后的语句,否 则执行else后的语句。
Events were executed in the correct order //执行结果
3.mailbox
Mailbox 是一种在进程之间交换消息的机制。数据可以通过一个进程发送到Mailbox, 然后由另一个进程获取。数据可以是任何有效的SystemVerilog数据类型,包括类 class数据类型。

1 class transaction; 2 rand bit valid; 3 rand bit [7:0] data; 4 endclass 5 6 class generator; 7 mailbox #(transaction) gen2drv; 8 transaction tr; 9 function new (input mailbox #(transaction) gen2drv); 10 this.gen2drv=gen2drv; 11 endfunction 12 13 task gen(input int num); 14 for(int i=0;i<num;i++) begin 15 tr=new(); 16 assert(tr.randomize) gen2drv.put(tr); 17 $display(“trans valid =%d”,tr.valid); 18 $display(“trans data =%d”,tr.data); 19 #1ns; 20 end 21 endtask 22 endclass 23 24 class driver; 25 mailbox #(transaction) gen2drv; 26 transaction tr; 27 function new (input mailbox #(transaction) gen2drv); 28 this.gen2drv=gen2drv; 29 endfunction 30 31 task run; 32 tr=new(); 33 while(1) begin 34 gen2drv.get(tr); 35 $display(“trans valid =%d”,tr.valid); 36 $display(“trans data =%d”,tr.data); 37 end 38 endtask 39 endclass 40 41 program test; 42 mailbox #(transaction) gen2drv; 43 driver drv; 44 generator gen; 45 initial begin 46 gen2drv=new(); 47 drv=new(gen2drv); 48 gen=new(gen2drv); 49 fork 50 gen.gen(5); 51 drv.run; 52 join_any 53 end 54 endprogram
可以理解为FIFO,空时读和满时写都会阻塞。try_*表示非阻塞,此外,get为取走,peek为复制走。
如果为空时,去读,会挂起,直到有数据写入。
new时,传参缺省或为0时,表示此mailbox是无边界的。传参表mailbox深度。new返回句柄,传参必须为正,负时会导致不确定后果。
try_put,如果放入了,函数返回1,否则返回0。try_get,拿走了,返回1,数据类型不匹配,返回负1,空的返回0。try_peek类似。
num得到此mailbox内的数据的个数。
申明时,默认的mailbox无类型,可以接收各种数据,也可以申明是指定需要传输的数据类型,方便编译器发现类型不匹配。
4.semaphore
使用旗语可以实现对同一资源的访问控制。当测试平台中存在一个 资源,如一条总线,对应着多个请求方,而实际物理设计中只允许单一驱动时, 便可使用旗语。 在system verilog中一个线程如果请求“钥匙”而得不到,则会一直阻塞,多个阻塞 的线程会以先进先出的方式进行排队
key的概念
new时,传参缺省值为0,传参表示key的个数。
put传参表示放回key的个数,缺省值1.
get传参表示获得key的个数,缺省值1,不存在指定数目key时,进程会阻塞到对应key数量的出现。
try_get无阻塞的获得指定数目的key,存在则返回1,否则返回0。

浙公网安备 33010602011771号