百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 热门文章 > 正文

在Verilog/SystemVerilog中使用fork/join的注意事项

bigegpt 2024-08-10 12:11 4 浏览

fork/join是Verilog中常用的语句。该语法在SystemVerilog中添加了join_any和join_none两个关键字,使fork的行为发生了变化。本文将比较全面的介绍fork的用法,其中不使用join_any和join_none关键字的时候,其用法和Verilog中一致。根据仿真平台的不同,结果可能会有差异,本文使用Vivado自带的仿真工具。

1. fork块中的begin/end块

在fork块中,begin和end之间的语句会顺序执行,如果没有begin和end,则各条语句会并发执行。看下面的例子。在fork块中有A、B两个任务,由于fork中么有begin/end块,这两个任务是并发执行的,我们看看打印结果。

module tb(
    );
 
reg 			sigout=0;
 
initial begin
	fork 
		A();
		B();
	join
 
	// $display("Started!!");
	// $display("Finished!!");
end 
 
task A;
	integer i=0;
	repeat (2) begin
		#10;
		$display("Number %d.", i);
		i+=2;
	end 
endtask : A
 
task B;
	integer j=1;
	#5;
	repeat (4) begin
		#10;
		$display("Number %d.", j);
		j+=2;
	end 
endtask : B
 
endmodule

打印结果如下,输出是从0 1 2 3 5 7。A任务和B任务的前两次repeat输出了0 1 2 3,此时A任务结束,B任务继续输出最后两次repeat的值,即5 7。

如果将A和B任务用begin/end块包含起来,这两个任务将会顺序执行,输出就会变成0 2 1 3 5 7,即A任务执行并输出完毕后,B任务才开始执行。如下图。


2. join/join_any/join_none

先看看SystemVerilog 3.1a版对于上述关键字的描述。

使用join时,该fork块将阻塞进程,直到所有在fork中所有的语句都执行完毕;使用join_any时,该fork块将阻塞进程,直到fork块中任意一个进程结束;使用join_none时,该fork块不会阻塞,并会和其他进程一起并发执行。但是这些并发的进程将在遇到第一个阻塞语句时才开始执行。

使用join时的用法和Verilog是一致的,不再赘述。

2.1 join_any

为了测试join_any,把上文的代码修改一下。在fork外加了两个打印语句。

module tb(
 
    );
 
reg 			sigout=0;
 
initial begin
	fork 
		A();
		B();
	join_any
 
	$display("Started!!");
	$display("Finished!!");
end 
 
task A;
	integer i=0;
	repeat (2) begin
		#10;
		$display("Number %d.", i);
		i+=2;
	end 
endtask : A
 
task B;
	integer j=1;
	#5;
	repeat (4) begin
		#10;
		$display("Number %d.", j);
		j+=2;
	end 
endtask : B
 
endmodule

以下是打印输出。可以看到,fork阻塞了进程,任务A首先完成,输出了0和2。此时由于A任务结束,fork不再阻塞进程,所以可以看到2输出后,紧接着输出了fork外面的两条打印语句。然后任务B接着输出3 5 7。

2.2 join_none

首先把用于测试join_any的代码中的join_any修改为join_none,其输出如下。

两条打印语句Started和Finished首先输出,有点出乎意料。这是由于fork块后面没有任何阻塞语句,而join_none不会阻塞下一条阻塞语句之前的所有进程。由于任务A和B中都添加了延时,所以Started和Finished被首先打印,然后才轮到任务A和B输出。为了更清晰的理解join_none,将测试程序进行修改,添加一个阻塞赋值语句,同时增加输出信号。

module tb(
 
    );
 
reg 			sigout=0;
reg 			a_end, b_end;
 
initial begin
	a_end = 0;
	b_end = 0;
	fork 
		A();
		B();
	join_none
	
	$display("Started!!");
	#20 sigout = 1;
	$display("Finished!!");
end 
 
task A;
	integer i=0;
	repeat (2) begin
		#10;
		$display("Number %d.", i);
		i+=2;
	end 
	a_end = 1;
endtask : A
 
task B;
	integer j=1;
	#5;
	repeat (4) begin
		#10;
		$display("Number %d.", j);
		j+=2;
	end 
	b_end = 1;
endtask : B
 
endmodule

首先在Started和Finished两条打印语句之间插入了一个赋值语句,同时定义了三个新信号:a_end、b_end、sigout。该程序打印输入如下。fork内部的语句将和#20 sigout = 1之前的语句同时开始并发执行,但是该执行被挂起,直到遇到了#20 sigout = 1之后,才会执行。所以我们看到,Started的打印是0延时的,所以首先输出。接着是输出0和1,然后是20ns之后的sigout有效和Finished打印语句。

再看输出的波形,sigout和a_end都在20ns时输出,b_end在45ns时输出,符合预期。

————————————————

版权声明:本文为CSDN博主「小苍蝇别闹」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/yinyeyy/article/details/106620597

相关推荐

5分钟搭建公网https网页文件服务器,免费权威TLS证书

请关注本头条号,每天坚持更新原创干货技术文章。如需学习视频,请在微信搜索公众号“智传网优”直接开始自助视频学习前言本文主要讲解如何快速搭建一个https网页文件服务器,并免费申请权威机构颁发的tls证...

nginx负载均衡配置(nginx负载均衡配置两个程序副本)

Nginx是什么没有听过Nginx?那么一定听过它的“同行”Apache吧!Nginx同Apache一样都是一种WEB服务器。基于REST架构风格,以统一资源描述符(UniformResources...

19《Nginx 入门教程》Nginx综合实践

今天我们将基于Nginx完成两个比较有用的场景,但是用到的Nginx的配置非常简单。内部Yum源搭建内部Pip源搭建1.实验环境ceph1centos7.6内网ip:172.16....

Nginx性能调优与优化指南(nginx优化配置大全)

Nginx性能调优需要结合服务器硬件资源、业务场景和负载特征进行针对性优化。以下是一些关键优化方向和具体配置示例:一、Nginx配置优化1.进程与连接数优化nginxworker_process...

C++后端开发必须彻底搞懂Nginx,从原理到实战(高级篇)

本文为Nginx实操高级篇。通过配置Nginx配置文件,实现正向代理、反向代理、负载均衡、Nginx缓存、动静分离和高可用Nginx6种功能,并对Nginx的原理作进一步的解析。当需...

【Nginx】史上最全的Nginx配置详解

Nginx服务器配置中最频繁的部分,代理、缓存和日志定义等绝大多数功能和第三方模块的配置都在这里,http块又包括http全局块和server块。Nginx是非常重要的负载均衡中间件,被广泛应用于大型...

【Nginx】Nginx 4种常见配置实例(nginx基本配置与参数说明)

本文主要介绍nginx4种常见的配置实例。Nginx实现反向代理;Nginx实现负载均衡;Nginx实现动静分离;Nginx实现高可用集群;Nginx4种常见配置实例如下:一、Nginx反向代理配...

使用nginx+allure管理自动化测试报告

allure在自动化测试中经常用来生成漂亮的报告,但是网上及官网上给出的例子都仅仅是针对单个测试用例文件的形式介绍的,实际使用中,自动化测试往往需要包含不止一个产品或项目,本文介绍如何使用nginx+...

nginx配置文件详解(nginx配置文件详解高清版)

Nginx是一个强大的免费开源的HTTP服务器和反向代理服务器。在Web开发项目中,nginx常用作为静态文件服务器处理静态文件,并负责将动态请求转发至应用服务器(如Django,Flask,et...

SpringCloud Eureka-服务注册与发现

1.Eureka介绍1.1学习Eureka前的说明目前主流的服务注册&发现的组件是Nacos,但是Eureka作为老牌经典的服务注册&发现技术还是有必要学习一下,原因:(1)一些早期的分布式微服...

微服务 Spring Cloud 实战 Eureka+Gateway+Feign+Hystrix

前言我所在项目组刚接到一个微服务改造需求,技术选型为SpringCloud,具体需求是把部分项目使用SpringCloud技术进行重构。本篇文章中介绍了Eureka、Gateway、Fe...

深度剖析 Spring Cloud Eureka 底层实现原理

你作为一名互联网大厂后端技术开发人员,在构建分布式系统时,是不是常常为服务的注册与发现而头疼?你是否好奇,像SpringCloudEureka这样被广泛使用的组件,它的底层实现原理到底是怎样的...

热爱生活,喜欢折腾。(很热爱生活)

原文是stackoverflow的一则高票回答,原文链接可能之前也有人翻译过,但是刚好自己也有疑惑,所以搬运一下,个人水平有限所以可能翻译存在误差,欢迎指正(如侵删)。尽管classmethod和st...

GDB调试的高级技巧(详细描述gdb调试程序的全过程)

GDB是我们平时调试c/c++程序的利器,查起复杂的bug问题,比打印大法要好得多,但是也不得不说,gdb在默认情况下用起来并不是很好用,最近学习到几个高级点的技巧,分享下:一美化打印先上个例子...

Arduino 实例(二十三)Arduino 给Python 编译器发送信息

1首先Python需要安装Pyserial库,在命令提示符中输入pipintallpyserial若是遇到提示‘pip‘不是内部或外部命令,也不是可运行的程序或批处理文件,则需要设置环境变...