System Verilog中fork...join、join_none和join_none的用法和解析

标准的Verilog对语句有两种分组方式——使用begin…end或fork…join,begin…end中的语句以顺序方式执行,而fork…join中的语句则以并发方式执行。后者的不足是必须等fork…join内的所有语句都执行完以后才能继续块内后续的处理。因此,在Verilog的测试平台中很少用到它。
System Verilog引入了两种新的创建线程的方法——使用fork…join_none和fork…join_any语句

1.join:The parent process blocks until all the processes spawned by this fork complete.
简单来说:fork…join内的所有语句都是并发执行(对于begin…end内部是顺序执行)
2.join_any:The parent process blocks until any one of the processes spawned by this fork completes.
简单来说:一旦fork…join_any内任何一个线程完成,父线程就会继续运行
3.join_none:The parent process continues to execute concurrently with all the processes spawned by the fork. The spawned processes do not start executing until the parent thread executes a blocking statement or terminates.
简单来说:子线程和父线程会同时执行

下面看一下代码简单分析:

fork…join

//---------fork...join-------------
initial begin
	$display("@ %0t: start fork...join example", $time);
    #10 $display("@ %0t: sequential after # 10", $time);
	fork
		$display("@ %0t: parallel start", $time);
		#50 $display("@ %0t: parallel start # 50", $time);
		#10 $display("@ %0t: parallel after #10", $time);
		begin
			#30 $display("@ %0t: sequential after # 30", $time);
			#10 $display("@ %0t: sequential after # 10", $time);
		end	
	join
	$display("@ %0t: after join", $time);
	#80 $display("@ %0t: finish after # 80", $time);
end

程序运行结果:

@ 0: start fork...join example
@ 10: sequential after # 10
@ 10: parallel start
@ 20: parallel after #10
@ 40: sequential after # 30
@ 50: sequential after # 10
@ 60: parallel start # 50
@ 60: after join
@ 140: finish after # 80

fork…join_none

fork…join_none块在调度其块语句时,父线程继续执行。下面的代码与上面代码除了join被换成了join_none以外,其余均相同。

//---------fork...join_none-------------
initial begin
	$display("@ %0t: start fork...join_none example", $time);
    #10 $display("@ %0t: sequential after # 10", $time);
	fork
		$display("@ %0t: parallel start", $time);
		#50 $display("@ %0t: parallel start # 50", $time);
		#10 $display("@ %0t: parallel after #10", $time);
		begin
			#30 $display("@ %0t: sequential after # 30", $time);
			#10 $display("@ %0t: sequential after # 10", $time);
		end	
	join_none
	$display("@ %0t: after join_none", $time);
	#80 $display("@ %0t: finish after # 80", $time);
end

程序运行结果:

@ 0: start fork...join_none example
@ 10: sequential after # 10
@ 10: after join_none
@ 10: parallel start
@ 20: parallel after #10
@ 40: sequential after # 30
@ 50: sequential after # 10
@ 60: parallel start # 50
@ 90: finish after # 80

fork…join_any

fork…join_any块对块内语句进行调度,当第一个语句完成后,父线程才继续执行,其他停顿的线程也得以继续。代码如下:

//---------fork...join_any-------------
initial begin
	$display("@ %0t: start fork...join_any example", $time);
    #10 $display("@ %0t: sequential after # 10", $time);
	fork
		$display("@ %0t: parallel start", $time);
		#50 $display("@ %0t: parallel start # 50", $time);
		#10 $display("@ %0t: parallel after #10", $time);
		begin
			#30 $display("@ %0t: sequential after # 30", $time);
			#10 $display("@ %0t: sequential after # 10", $time);
		end	
	join_any
	$display("@ %0t: after join_any", $time);
	#80 $display("@ %0t: finish after # 80", $time);
end

运行结果如下:

@ 0: start fork...join_any example
@ 10: sequential after # 10
@ 10: parallel start
@ 10: after join_any
@ 20: parallel after #10
@ 40: sequential after # 30
@ 50: sequential after # 10
@ 60: parallel start # 50
@ 90: finish after # 80
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值