Verilog基础:时序调度中的竞争(一)

相关阅读

Verilog基础icon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12263729.html?spm=1001.2014.3001.5482


        作为一个硬件描述语言,Verilog HDL常常需要使用语句描述并行执行的电路,但其实在仿真器的底层,这些并行执行的语句是有先后顺序的,然而Verilog标准并没有将这些事件调度的顺序定死,而是给予了仿真器厂商一定的自由去实现自己的产品,这就导致了设计者如果不遵循一定的编程习惯,会导致意想不到的仿真结果,下面是一些相关的规则。

1、不要在两个及以上的always或initial结构中对同一个变量赋值

        当两个以上的过程结构同时执行时,它们之间的执行顺序是不一定的,Verilog标准只规定了在一个顺序块(begin end)中的所有语句是按照其先后顺序执行的,但并没有规定同一个时间执行的多个结构的执行顺序,下面举例详细说明。

//例1
`timescale 1ns/1ps
module test();initial $display("The initial_0 execute");initial $display("The initial_1 execute");initial $display("The initial_2 execute");
endmodule

        在上例中,三个initial结构在0ns时同时执行,仿真器执行他们的顺序是不定的,但测试表明,许多仿真器都选择顺序执行这三个initial结构,如下所示。

对于Mentor Modelsim SE,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute对于Aldec Riviera Pro,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute对于Cadence Xcelium,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute对于Mentor Questa,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute对于Synopsys VCS,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute对于Icarus Verilog,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute

         虽然看起来仿真器的行为都是一致的,但其实这只是一个巧合,下面的例子就体现出了各种仿真器对同一段代码之间的不同行为。

//例2
`timescale 1ns/1ps
module test();reg a;initial #5 a = 1;initial @(a) $display("The initial_0 execute");initial @(a) $display("The initial_1 execute");initial @(a) $display("The initial_2 execute");
endmodule

        这段代码的三个initial结构都对事件a敏感,所以在5ns时,三个initial结构同时被触发,而他们的执行顺序是不定的,如下所示。

对于Mentor Modelsim SE,输出结果为
The initial_2 execute
The initial_1 execute
The initial_0 execute对于Aldec Riviera Pro,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute对于Cadence Xcelium,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute对于Mentor Questa,输出结果为
The initial_2 execute
The initial_1 execute
The initial_0 execute对于Synopsys VCS,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execut对于Icarus Verilog,输出结果为
The initial_2 execute
The initial_1 execute
The initial_0 execute

        下面的代码中仍然体现了同一时间的多个结构的执行顺序是不定的,即使触发这些结构的事件在同一时间是有前后关系的。

//例3
`timescale 1ns/1ps
module test();reg a, b, c;initial begin#5;a = 1;b = 1;c = 1;endalways @(a) $display("The initial_0 execute");always @(b) $display("The initial_1 execute");always @(c) $display("The initial_2 execute");
endmodule

        在5ns时,a、b、c先后被赋值为1,Verilog标准保证了begin end块中的赋值顺序从上到下。但由这些赋值语句触发的其他always结构呢?是否也会按照a、b、c的顺序执行呢?

对于Mentor Modelsim SE,输出结果为
The initial_2 execute
The initial_1 execute
The initial_0 execute对于Aldec Riviera Pro,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute对于Cadence Xcelium,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute对于Mentor Questa,输出结果为
The initial_2 execute
The initial_1 execute
The initial_0 execute对于Synopsys VCS,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execut对于Icarus Verilog,输出结果为
The initial_0 execute
The initial_1 execute
The initial_2 execute

        依然可以注意到不同仿真器之间的差异,为什么不都是按照a赋值,always @(a)执行,b赋值,always @(b)执行,c赋值,always @(c)执行的顺序执行呢?还是那句话,Verilog标准只规定了一个顺序块(begin end)中的所有语句是按照其先后顺序执行的,并没有保证其他行为。当a赋值后,always @(a)被调度了,但他不一定会在b赋值之前执行,有可能在执行完b赋值、c赋值之后再来执行always @(a),此时always @(b)和always @(c)也应该在队列中,他们执行的先后顺序是标准没有保证的(但需要注意的是,最基本的调度者和被调度者的先后关系是无法改变的,即always @(a)一定在a赋值后,b、c亦然)。下面是一个经典的两个结构交错执行的例子。

//例4
`timescale 1ns/1ps
module test();reg a;wire b;initial begin#1;a = 1;#1;a = 0;$display("b is %b", b);endassign b = a;endmodule

         当时间来到1ns,a被赋值为1,同时触发assign结构,对b连续赋值为1。1ns后,a被更改为0,紧接着打印b的值,结果是1还是0呢?

对于Mentor Modelsim SE,输出结果为
b is 1对于Aldec Riviera Pro,输出结果为
b is 1对于Cadence Xcelium,输出结果为
b is 1对于Mentor Questa,输出结果为
b is 1对于Synopsys VCS,输出结果为
b is 0对于Icarus Verilog,输出结果为
b is 0

        上面的结果显示,仿真器可能在执行了a=0的赋值后立刻执行被调度的assign连续赋值,再返回initial结构执行显示语句,也可能继续执行下面的显示语句,再去执行被调度的assign连续赋值。

        这就给了我们一个启示,在改变了一个全组合逻辑的电路的输入后,紧接着显示输出,可能无法得到更新后的输出。一个更好的做法是给$display语句一定的延时,这样就能确保在执行$display前,连续赋值已经执行完毕,因为不同时间的语句执行是不会产生竞争的。

//例5
`timescale 1ns/1ps
module test();reg a;wire b;initial begin#1;a = 1;#1;a = 0;#0.01 $display("b is %b", b);endassign b = a;endmodule

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/167543.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

机器学习数据集整理:图像、表格

前言 如果你对这篇文章感兴趣,可以点击「【访客必读 - 指引页】一文囊括主页内所有高质量博客」,查看完整博客分类与对应链接。 表格数据 Sklearn 提供了 13 个表格型数据,且数据处理接口统一;LIBSVM 提供了 131 个表格型数据&a…

【TypeScript】常见数据结构与算法(二):链表

文章目录 链表结构(LinkedList)链表以及数组的缺点数组链表的优势 什么是链表?封装链表相关方法源码链表常见面试题237-删除链表中的节点206 - 反转链表 数组和链表的复杂度对比 链表结构(LinkedList) 链表以及数组的缺点 链表…

AcWing103.电影——离散化

题目 莫斯科正在举办一个大型国际会议,有 n n n 个来自不同国家的科学家参会。 每个科学家都只懂得一种语言。 为了方便起见,我们把世界上的所有语言用 1 到 109 之间的整数编号。 在会议结束后,所有的科学家决定一起去看场电影放松一下。…

Interactive Visual Data Analysis

Words&Contents Home | Interactive Visual Data Analysis Book Outline 这本书对视觉、互动和分析方法进行了系统而全面的概述,作为数据可视化方面比较好的读物; 目录 Words&Contents Book Outline (一)Introduct…

AIGC 3D即将爆发,混合显示成为产业数字化的生产力平台

2023年,大语言模型与生成式AI浪潮席卷全球,以文字和2D图像生成为代表的AIGC正在全面刷新产业数字化。而容易为市场所忽略的是,3D图像生成正在成为下一个AIGC风口,AIGC 3D宇宙即将爆发。所谓AIGC 3D宇宙,即由文本生成3D…

VBA_MF系列技术资料1-227

MF系列VBA技术资料 为了让广大学员在VBA编程中有切实可行的思路及有效的提高自己的编程技巧,我参考大量的资料,并结合自己的经验总结了这份MF系列VBA技术综合资料,而且开放源码(MF04除外),其中MF01-04属于定…

安装compiler version 5

这个compiler version5 在我的资源里面可以免费下载; 另外这个东西还需要安装,安装教程在这里:Keil最新版保姆教程(解决缺少V5编译器问题) - 哔哩哔哩 (bilibili.com) 看吧安装好了year

C语言链表使用

目录 双链表增删改查链表带功能函数 双链表增删改查 #include <stdio.h> #include <stdlib.h>// 双链表结点的定义 typedef struct DNode{int data;struct DNode *prev;struct DNode *next; } DNode;// 创建双链表 DNode *createDoublyLinkedList() {int n, i;pri…

【C语言】qsort的秘密

一&#xff0c;本文目标 qsort函数可以对任意类型数据甚至是结构体内部的数据按照你想要的规则排序&#xff0c;它的功能很强大&#xff0c;可是为什么呢&#xff1f; 我将通过模拟实现qsort函数来让你对这整个过程有一个清晰的深刻的理解。 二&#xff0c;qsort函数原型 v…

leetcode刷题详解一

算法题常用API std::accumulate 函数原型&#xff1a; template< class InputIt, class T > T accumulate( InputIt first, InputIt last, T init );一般求和的&#xff0c;代码如下&#xff1a; int sum accumulate(vec.begin() , vec.end() , 0);详细用法参考 lo…

【python海洋专题四十七】风速的风羽图

【python海洋专题四十七】风速的风羽图 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【python海洋专题三】图像修饰之画布和坐标轴 【Python海洋专题四】之水深地图图像修饰 【Pyth…

记一次linux操作系统实验

前言 最近完成了一个需要修改和编译linux内核源码的操作系统实验&#xff0c;个人感觉这个实验还是比较有意思的。这次实验总共耗时4天&#xff0c;从对linux实现零基础&#xff0c;通过查阅资料和不断尝试&#xff0c;直到完成实验目标&#xff0c;在这过程中确实也收获颇丰&…

pytorch模型优化简介,未完结版

如有帮助&#xff0c;点赞收藏关注&#xff01; 如需转载&#xff0c;请注明出处&#xff01; 今天来介绍torch模型中的优化器 优化是指在每个训练步骤中调整模型参数以减少模型误差的过程。 优化算法定义如何执行这个过程 所有优化逻辑都封装在优化器对象中。在这里&#xf…

【黑马甄选离线数仓day04_维度域开发】

1. 维度主题表数据导出 1.1 PostgreSQL介绍 PostgreSQL 是一个功能强大的开源对象关系数据库系统&#xff0c;它使用和扩展了 SQL 语言&#xff0c;并结合了许多安全存储和扩展最复杂数据工作负载的功能。 官方网址&#xff1a;PostgreSQL: The worlds most advanced open s…

音视频项目——RTSP服务器解析(1)

介绍 利用线程池&#xff0c;实现 RTSP 服务器的高并发请求处理。 RTSP 是音视频的控制视频的协议&#xff0c;如果您还不了解&#xff0c;可以看看之前我解析 RTSP 协议的文章。音视频协议解析(RTP/RTCP/RTSP/RTMP)——RTSP解析-CSDN博客 解析 我们先来看 RTP 的实现。RTP 是音…

Django框架之auth模块

目录 一、Auth模块引入 二、创建超级用户(管理员) 三、依赖于auth_user表完成登录注册功能 【1】基础登陆 【2】保存用户状态 【3】登录后跳转 (1) 登录后才能访问页面 -- 局部配置 (2) 登录后才能访问页面 -- 全局配置 (3) 小结 三、修改密码 四、注销 五、注册…

Springboot将多个图片导出成zip压缩包

Springboot将多个图片导出成zip压缩包 将多个图片导出成zip压缩包 /*** 判断时间差是否超过6小时* param startTime 开始时间* param endTime 结束时间* return*/public static boolean isWithin6Hours(String startTime, String endTime) {// 定义日期时间格式DateTimeFormatt…

【数据结构】—搜索二叉树(C++实现,超详细!)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;消えてしまいそうです—真夜中 1:15━━━━━━️&#x1f49f;──────── 4:18 &#x1f504; ◀️ ⏸ ▶️…

函数计算的新征程:使用 Laf 构建 AI 知识库

Laf 已成功上架 Sealos 模板市场&#xff0c;可通过 Laf 应用模板来一键部署&#xff01; 这意味着 Laf 在私有化部署上的扩展性得到了极大的提升。 Sealos 作为一个功能强大的云操作系统&#xff0c;能够秒级创建多种高可用数据库&#xff0c;如 MySQL、PostgreSQL、MongoDB …

js实现获取原生form表单的数据序列化表单以及将数组转化为一个对象obj,将数组中的内容作为对象的key转化为对象,对应的值转换为对象对应的值

1.需求场景 哈喽 大家好啊&#xff0c;今天遇到一个场景&#xff0c; js实现获取原生form表单的数据序列化表单以及将数组转化为一个对象obj&#xff0c;将数组中的内容作为对象的key转化为对象&#xff0c;对应的值转换为对象对应的值 数组对象中某个属性的值&#xff0c;转…