我的 System Verilog 学习记录(5)

news2024/11/28 4:48:01



引言

本文简单介绍 System Verilog 语言的 控制流。

前文链接:

我的 System Verilog 学习记录(1)

我的 System Verilog 学习记录(2)

我的 System Verilog 学习记录(3)

我的 System Verilog 学习记录(4)


循环

简介

啥是循环 ?

循环是一段一遍又一遍地执行的代码。条件语句通常包含在循环中,以便在条件为真时终止。如果循环永远运行,则仿真将无限期挂起。

SV中有如下几种循环结构:

foreach

这是一个无限循环,就像 while(1) 一样。请注意,除非在 forever 块中包含时间延迟以提前仿真时间,否则仿真将挂起。

repeat

用于将一个块中的语句重复一定次数。下面显示的示例将显示消息5次,并继续执行代码的其余部分。

while

如果您知道verilog/C,您已经知道这一点。只要条件为真,它就会重复这个块。Counter最初是零,然后递增,直到它达到10。

for

do while

foreach

这最适合遍历数组变量,因为您不必找到数组大小,将变量设置为从0开始到数组大小-1,然后在每次迭代时递增。


while / do - while

while 循环首先检查条件是否为真,然后执行true语句。如果条件是假的,这个循环就在那里结束。
一个 do while 循环首先执行一次语句,然后检查该条件是否为真。如果条件为true,则执行语句集,直到条件变为false。如果条件为false,则循环就在那里结束。
因此,这两者之间的区别是,一个 do while 循环至少执行一次语句集。

语法

示例

while

int 变量如果定义但是没有初始化,默认给0;

用 Questa Sim 验证:

do while


foreach

SystemVerilog 数组是允许在单个变量中存储许多值的数据结构。foreach 循环仅用于迭代这样的数组,这是最简单和最方便的方法。

语法

示例:一维数组

 foreach 等价于 for 的如下代码:

示例:多维数组


for

语法

对于循环,使用三步方法来控制其语句的执行:
1.初始化影响循环运行次数的变量
2.在执行该循环之前,请检查该条件是否为真
3.修改器在每次迭代结束时执行,并跳转到步骤2。

示例:数组迭代

示例:多个初始化

示例:增加多个修改项


forever

语法

forever 语句块内必须要有对应的延时信息。

SV中,always 块不能放在类中以及其他SV程序块内。我们可以用 forever 循环达到相同目的。

下面显示的伪代码模拟了Testbench中监视器的功能1,一旦启动,只要它的监视器上有活动,就允许其运行。


repeat

语法

示例


break,continue

break

continue


if-else-if

SV引入如下几种 if - else 结构:

  • unique-if
  • unique0-if
  • priority-if

unique-if,unique0-if

unique-if 以任意顺序评估判断条件:

  • 除非有明确的else分支语句,否则匹配不到if条件的内容是会报告一个error;
  • 在if-else条件中匹配到都于一个的分支语句也会报告一个error;

注意,unique0-if 在匹配不到任何条件时不会报告error。

示例:无else分支的unique-if

示例:unique-if中存在多条件匹配

priority-if

priority-if完全按照顺序评估判断条件。当出现以下情况时,会报告一个违例:

  • 没有一个判断条件为真
  • 缺少else分支,且前面几个判断条件均不满足

示例:priority-if 缺少 else分支

示例:priority-if匹配第一个条件后退出


case

unique-case,unique0-case

所有case语句都可以通过 unique 或 unique0 关键字进行限定来执行违例检查,就像我们在 if-else-if 构造中看到的那样。
unique 和 unique0 确保没有重叠的大小写项,因此可以并行计算。如果存在重叠的案例项,则会报告违规行为。

  • 如果多于1个case语句可以和已知表达式匹配,会报告一个违例并且执行第一个匹配的case分支;
  • 如果所有的case语句都不匹配,仅在 unique 关键词下报告一个违例,unique0 则不会报告违例;

示例:unique 无一匹配

示例:unique 多个匹配

priority-case


阻塞 & 非阻塞语句

此处和 Verilog 的相同,给几个示例:

阻塞语句的赋值的立刻的。仿真结果:

加入延迟:

 非阻塞赋值示例:

 仿真结果:

 执行过程:

 加入延迟:

执行过程:

 非阻塞右侧表达式在一开始便执行计算,但是赋值过程发生在下一时间刻度。

事件

事件是在两个或多个并发活动的进程之间进行同步的静态对象句柄。一个进程将触发该事件,另一个进程等待该事件。

  • 可以和其他事件变量比较或者指定为其他事件变量
  • 可以传递给队列、函数和任务

- - 可以指定为 null

- - 将两个变量赋给另一个事件时,这两个变量指向相同的同步对象

如何触发/等待事件 ? 

  • 可以使用 ->;或 ->> 运算符触发已命名事件;
  • 可以用 @ 或者 .triggered 让进程等待事件;

示例

@ 和 .triggered 有啥区别 ?

事件的触发状态在整个时间步长中持续存在,一直到仿真进一步执行。因此,如果等待事件和事件的触发同时发生,则会出现竞争条件,而 triggered 的属性有助于避免这种情况。

等待已触发状态的进程始终解除阻塞,而不管等待和触发的顺序如何。

示例

仿真结果:

 请注意,由于 @ 和 -> 操作符之间的竞争条件,Thread2从未收到触发。

等待顺序

等待按给定顺序触发事件,如果有任何事件无序执行,则会发出错误。

示例:

合并事件

将一个事件变量分配给另一个事件变量时,等待触发第一个事件的所有进程都将等待第二个变量被触发。

函数

SV中的函数和Verilog 中的具有相同特性。

函数的主要目的就是可以在表达式计算上调用,且不耗费仿真时间。

  • 函数不能有时间控制语句,比如 @ ,#,fork join ,wait
  • 函数不能调用任务,因为任务可以有时间控制语句

示例:ANSI-C 风格的声明

示例:使用声明和IO口

如何通过值传递参数 ?

按值传递是将参数传递给子例程的默认机制。每个参数都被复制到子例程区域,对子例程区域中的该局部变量所做的任何更改在子例程外部不可见。

 仿真log:

如何通过参考传递参数 

通过引用传递的参数不会复制到子例程区域,而是将对原始参数的引用传递给子例程。参数声明前面带有ref关键字。对子例程内的变量所做的任何更改都将反映在子例程外部的原始变量中。

 对具有静态(static)生存期的子例程使用按引用传递参数是非法的。


 

任务

函数用于对输入进行一些处理并返回单个值,而任务更为通用,它可以计算多个结果值并使用output 和 inout 类型的参数返回计算结果。任务可以包含时间控制语句,如@posedge等。

语法

静态任务

如果任务是静态的,则其所有成员变量将在已启动以并发运行的同一任务的不同调用之间共享。

启用任务的参数(x,y,z)与任务定义的参数(a,b,c)相对应。因为a和b是输入,所以x和y的值将分别放在a和b中。因为c被声明为输出,并且在调用期间与z连接,所以和将自动从c传递给变量z。

自动任务

关键字 aotumatic 将使任务重入,否则默认情况下它将是静态的。自动任务中的所有项都是为每个调用动态分配的,而不是在并发运行的同一任务的调用之间共享。请注意,层次结构引用不能访问自动任务项。
为了便于说明,考虑从并发运行的不同初始块中调用的静态任务显示。在这种情况下,任务中声明的整数变量在任务的所有调用中共享,因此每个调用显示的值应该增加。

示例:

自动任务:

全局任务

在所有模块外部声明的任务称为全局任务,因为它们具有全局作用域,并且可以在任何模块内调用。

如果任务是在模块 des 中声明的,则必须引用模块实例名称来调用它。

函数和任务的区别

当函数尝试调用任务或包含耗时的语句时,编译器会报告错误。

任务禁止

可以用 disable 关键字禁止任务执行。


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

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

相关文章

算法课堂-分治算法

分治算法 把一任务分成几部分(通常是两部分)来完成(或只完成一部分),从而实现整个任务的完成 或者你可以把递归理解为分治算法的一部分 因为递归就是把问题分解来解决问题 例子 称假币 最笨的方法:两两称…

(三十六)大白话数据库幻读,本质到底是个什么问题?

上一讲我们给大家讲解了不可重复读这个问题,这个问题简单来说,就是一个事务多次查询一条数据,结果每次读到的值都不一样,这个过程中可能别的事务会修改这条数据的值,而且修改值之后事务都提交了,结果导致人…

多变量线性回归模型

多变量线性回归模型 模型参数为n1维向量,此时模型公式为 hθ(x)θ0x0θ1x1θ2x2...θnxnh_{\theta}(x)\theta_{0}x_{0}\theta_{1}x_{1}\theta_{2}x_{2}...\theta_{n}x_{n} hθ​(x)θ0​x0​θ1​x1​θ2​x2​...θn​xn​ 可以简化为 hθ(x)θTXh_{\theta}(x)\th…

Gradle7.4安装与基本使用

文章目录一.前言二.下载Gradle三.Gradle镜像源-全局级配置四.配置Gradle wrapper-项目级配置五.Gradle对测试的支持五.生命周期5.1 settings文件六.Gradle任务入门6.1 任务行为6.2 任务依赖方式七. Dependencies依赖引入7.1 依赖冲突及解决方案八.Gradle整合多模块SpringBoot九…

NLP复习大纲

第一章:概述 1. 什么是自然语言处理? 计算机具备人类的听、说、读、写、译、问、答、搜索、摘要、对话和聊天等能力 知识和常识进行推理和决策 支持客服、诊断、法律、教学等场景 2. 自然语言处理的主要任务有哪些? 分析、理解、转换、…

要理解网络,其实不就是理解这三张表吗

我们如果要理解数据是如果在网络世界中穿梭的,那其实只要了解其中的三张表就可以了。这三张表分别为路由表、转发表、ARP 表。 假设我们用聊天工具聊天的时候,我在北京,你在广东,当我给你发送一条消息的时候。搭载这这条消息的数据…

带你沉浸式体验删库跑路

前言:学习的过程比较枯燥,后面会记录一些比较有意思的东西,比如程序员之间流传的删库跑路的梗,当然本次测试是在虚拟机上进行的并进行了快照保护,所以其实没太大问题。首先得要有一个虚拟机要有一个linux iso文件装在虚拟机上以上两点不是本文重点,如果有需要可以私…

CLIP论文阅读

Learning Transferable Visual Models From Natural Language Supervision 利用自然语言的监督信号学习可迁移的视觉模型 概述 迁移学习方式就是先在一个较大规模的数据集如ImageNet上预训练,然后在具体的下游任务上再进行微调。这里的预训练是基于有监督训练的&am…

排序基础之插入排序

目录 前言 一、什么是插入排序 二、实现插入排序 三、插入排序优化 四、插入排序的特性 前言 上一篇中我们说到了《排序基础之选择排序》,这一篇我们来学习一下排序算法中的另一种基础排序算法——插入排序。 一、什么是插入排序 简单来说就是:每…

break与continue关键字

1.概述 不知道大家有没有这样一种感受哈,有的时候容易混淆break语句和continue语句的用法,总是模棱两可,不敢确定自己是否使用正确了。正好,我们本篇的重点就是break和continue关键字的用法。 2.使用场景 Java中为啥会诞生break…

js——原型和原型链

最近看了很多面试题,看到这个js原型是常考点,于是,我总结了一些该方面的知识点分享给大家,其实原型就是那么一回事,搞明白了就没啥了。结果如下图所示:原型原型又可分为显式原型和隐式原型1.1显式原型显式原…

Linux C代码获取线程ID

Linux C代码获取线程ID gettid可以获取线程id,但是通过man gettid可以看到下面这两句 也就是说glibc没有为这个gettid封装系统调用&#xff0c;需要使用syscall。 #define _GNU_SOURCE#include <unistd.h>#include <sys/syscall.h>#include <sys/types.h>ti…

自动化测试 selenium常用操作

最简单的代码实例import org.openqa.selenium.By; import org.openqa.selenium.chrome.ChromeDriver;public class AutoTestDemo1 {//浏览器自动搜索,暂停是为了能看到&#xff0c;要不访问太快public void testKunKun() throws InterruptedException {//打开浏览器ChromeDrive…

【软件工程】课程作业(三道题目:需求分析、概要设计、详细设计、软件测试)

文章目录&#xff1a;故事的开头总是极尽温柔&#xff0c;故事会一直温柔……&#x1f49c;一、你怎么理解需求分析&#xff1f;1、需求分析的定义&#xff1a;2、需求分析的重要性&#xff1a;3、需求分析的内容&#xff1a;4、基于系统分析的方法分类&#xff1a;5、需求分析…

Java static关键字(重新认识main方法)

static关键字一、static修饰成员的特点二、static什么时候使用三、static注意事项四、重新认识main方法static 是静态的意思&#xff0c;可以修饰成员变量&#xff0c;也可以修饰成员方法 一、static修饰成员的特点 被其修饰的成员, 被该类的所有对象所共享多了一种调用方式, 可…

Vue(6)

文章目录1. 自定义指令1.1 函数式1.2 对象式1.3 自定义指令常见坑1.4 创建全局指令2. 生命周期2.1 引出生命周期2.2 分析生命周期2.3 总结3. 组件3.1 认识组件3.2 使用组件 (非单文件组件)3.3 全局组件3.4 组件的几个注意点3.5 组件的嵌套3.6 VueComponent 构造函数3.7 一个重要…

openresty学习笔记

openresty 简介 openresty 是一个基于 nginx 与 lua 的高性能 web 平台&#xff0c;其内部 集成了大量精良的 lua 库、第三方模块以及大数的依赖项。用于 方便搭建能够处理超高并发、扩展性极高的动态 web 应用、 web 服务和动态网关。 openresty 通过汇聚各种设计精良的 ngi…

LearnOpenGL-入门-纹理

本人刚学OpenGL不久且自学&#xff0c;文中定有代码、术语等错误&#xff0c;欢迎指正 我写的项目地址&#xff1a;https://github.com/liujianjie/LearnOpenGLProject LearnOpenGL中文官网&#xff1a;https://learnopengl-cn.github.io/ 文章目录纹理纹理环绕方式纹理过滤多…

3.抽象工厂模式(Abstract Factory)

与工厂模式对比 工厂模式 工厂模式是类创建模式。在工厂模式中&#xff0c;只需要生产同一种产品&#xff0c;只不过是生产厂家不同。 所以产品类的设计&#xff1a; 抽象的产品类Product具体的产品类Product_A&#xff0c;Product_B, Product_C, Product_D…… 工厂的设计…

BFC的含义以及应用

什么是BFC? BFC全称是Block Formatting context&#xff0c;翻译过来就是块级格式化上下文。简单来说&#xff0c;BFC是一个完全独立的空间。让空间里的子元素不会影响到外面的布局。&#x1f603;&#x1f603;&#x1f603; 如何触发BFC呢&#xff1f; mdn给了如下方式&a…