SystemVerilog学习笔记(九)

2024-03-27 01:10
文章标签 学习 笔记 systemverilog

本文主要是介绍SystemVerilog学习笔记(九),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本文思维导图如下:

1. 线程控制

1.1 并行线程

Verilog中与顺序线程begin…end相对的是并行线程fork…join。

1.1.1创建线程

SV引入了两种新新的创建线程的方法,fork…join_nonefork…join_any

  • fork…join
    fork…join需要所有并行的线程都结束以后才会继续执行。
  • fork…join_any
    fork…join_any则会等到任何一个线程结束以后就继续执行。
  • fork…join_none
    fork…join_none则不会等待其子线程而继续执行。
实例

1.1.2子程序等待/停止

需要注意的是,fork…join_any和fork. . .join_none继续执行后,其一些未完成的子程序仍将在后台运行。如果要等待这些子程序全部完成,或者停止这些子程序,可以使用wait fork或者disable fork。
(1)wait fork

(2)disable fork

1.2 时序控制

SV可以通过延迟控制或者事件等待来对过程块完成时序控制。

1.2.1 延迟控制

延迟控制即通过#来完成。

#10 rega = regb;

1.2.2 事件控制

事件(event)控制即通过@来完成。

@r rega = regb ;
@(posedge clock) rega = regb;

1.2.3 事件等待

wait语句也可以与事件或者表达式结合来完成。

real AOR[] ;
initial wait(AOR.size() > 0) … ;

2. 进程间同步和通信

测试平台中的所有线程都需要同步并交换数据。
一个线程等待另外一个,例如验证环境需要等待所有激励结束、比较结束才可以结束仿真。比如监测器需要将监测到的数据发送至比较器,比较器又需要从不同的缓存获取数据进行比较。

2.1 事件

  • 声明
    可以通过event来声明一个命名event变量,并且去触发它。这个命名event可以用来控制进程的执行。
  • 触发
    可以通过->来触发事件。
    其它等待该事件的进程可以通过@操作符或者wait()来检查event触发状态来完成。
  • 等待
    wait__order可以使得进程保持等待,直到在参数列表中的事件event按照顺序从左到右依次完成。如果参数列表中的事件被触发但是没有按照要求的顺序,那么会使得等待操作失败。

wait_order ( a, b, c);

wait order( a, b, c ) else $display ( “Error: eventsout of order” );

bit success ;
wait order( a, b, c ) success = 1; else success = 0 ;

2.2 旗语

旗语从概念上讲,是一个容器。在创建旗语的时候,会为其分配固定的钥匙数量。使用旗语的进程必须先获得其钥匙,才可以继续执行。旗语的钥匙数量可以有多个,等待旗语钥匙的进程也可同时有多个。旗语通常用于互斥,对共享资源的访问控制,以及基本的同步

### 2.2.1用法 * 创建旗语,并为其分配钥匙的方式如下: >semaphore sm; >sm = new ();
  • 创建一个具有固定钥匙数量的旗语:

new (N = 0)

  • 从旗语那里获取一个或多个钥匙(阻塞型) :

get (N = 1)

  • 将一个或多个钥匙返回到旗语中:

put (N = 1)

  • 尝试获取一个或多个钥匙而不会阻塞(非阻塞型) :

try_get (N = 1)

2.2.2基本操作

senmaphore: :new()

new ())的原型如下:

function new (int keyCount = 0) ;

keyCount指定最初分配给旗语的钥匙数目。keyCount的默认值为0。当更多钥匙放入旗语时,钥匙数目可以超出初始时的keyCount数量,而不是删除。

semaphore: :put()

put ()方法用于将钥匙数量返回给旗语。
put ()的原型如下:

function void put (int keyCount = 1) ;

keycount指定返回到旗语的钥匙数量。默认值为1。调用semaphore.put ()函数时,指定数量的钥匙将返回到旗语。如果其它进程已经在等待旗语,则该进程应在有足够数量钥匙的情况下返回。

semaphore: :get()

get ()方法用于从旗语中获取指定数量的钥匙。get ()的原型如下:

task get (int keycount = 1) ;

keyCount指定从旗语获取所需的钥匙数,默认值为1。如果指定数量的钥匙可用,则该方法返回并继续执行。如果指定数量的钥匙不足,进程将阻塞,直到钥匙数目充足。旗语的等待队列是先进先出(FIFO),即先排队等待旗语的将优先得到钥匙。

semaphore : :try_get()

try get ()方法用于从信号量中获取指定数量的钥匙,但不会被阻塞。try_get ()的原型如下:

function int try_get (int keyCount = 1) ;

keyCount指定从旗语处获取所需的钥匙数目,默认值为1。如果指定数量的钥匙可用,则该方法返回正数并继续执行。如果指定数量的钥匙不足,则该方法返回0。

2.2.3实例

2.3 信箱

信箱mailbox可以使得进程之间的信息得以交换,数据可以由一个进程写入信箱,再由另外一个进程获得。

信箱在创建时可以限制其容量,或者不限制。 当信箱容量写满时,后续再写入的动作会被挂起,直到信箱的数据从中读取,使得信箱有空间以后才可以继续写入。 不限制容量的信箱则不会挂起写入信箱的动作。

2.3.1 内建方法

new()

new()用于创建信箱。可以在创建信箱的时候限定或者不限定其大小默认情况下,如果不传入参数,bound默认值为0,表示不限定信箱大小,如果传入的数值大于0,那么表示信箱的最大容量。bound应为正数,如果未负数的话,系统会提示警告和出现无法预期的行为。

function new (int bound = 0) ;

put()

put()会将信息按照FIFO的顺序写入到信箱中,如果信箱此时已满,则put()任务会挂起,直到信箱有新的空间可以容纳消息。

try_put()

try put()试着写入信箱但不会阻塞。try put()也会按照FIFO顺序写入信箱,不会发生阻塞。如果信箱已满,则写入失败,返回0;如果信箱未满,则写入成功,返回1。

get()/peek()

获取信息: get()同时会取出数据,peek()不会取出数据。get()会将信息从信箱中取出,如果信箱此时为空,则get()任务会挂起,直到信箱中有消息可以读取,任务才会返回。该方法会将读取到的消息从信箱中移除。

try_get()/try_peek()

试着从信箱取出数据但不会阻塞。try get()也会将信息从信箱中取出,只是该函数不会发生阻塞。如果信箱为空,则读取失败,返回0;如果信箱不为空,则读取成功,返回1。该方法也会将读取到的消息从信箱中移除。

num()

num()会返回信箱目前的消息数目。可以结合num()与get()或者put(),防止get()/put()方法在信箱为空或者为满的时候被阻塞。

2.3.2 实例

mailbox #(int) mb;//声明mailbox句柄,并且指明该mailbox中只能存放int类型的数据

2.4虚方法

给pringtB添加关键词virtual,P1扩大查找范围,扩大到子类对象里面。如果子类里面有同名的方法,若有,调用子类里面同名的方法(以子类的实现优先)。
子类不添加virtual无影响,父类添加即可。

3. 类型转换

3.1 静态转换

静态转换操作符不对转换值进行检查。
转换时指定目标类型,并在要转换的表达式前加上单引号即可。Verilog对整数和实数类型,或者不同位宽的向量之间进行隐式转换。

int i;
real r;
i = int ’ (10.0 - 0.1); //cast is optional
r= real’(42);// cast is optional

3.2 动态转换

我们总是可以将子类的句柄赋值给父类的句柄。但是在我们将父类的句柄赋值给子类的句柄时,编译将会报错。
$cast()系统函数可以将父类句柄转换为子类句柄,只要该父类句柄指向的是一个子类的对象。

function int $cast( singular dest_var, singularsource_exp ) ;

或者

task $cast( singular dest_var, singular source_exp );

4. 问答题

1. 用bit key =0来实现的类似旗语(semaphore)的功能,来保护对共享资源的访问,是否有不安全的地方?示例代码如下(包含自然语言表征)。如果有不安全的地方,请用文字表述,并且对以下代码进行修改,并且进行测试、编译和仿真打印消息。

bit key = 1;//创建钥匙
task get_key();
wait(key > 0);
key = 0;//获得钥匙
…//省略对于共享资源的处理
key = 1; /还回钥匙
endtask

答:当多个task并行执行时,只要key=1,满足wait(key>0)即可执行,无法实现资源同时只能被指定个数的进程访问的目的。

2. SV的原生旗语semaphore在例化以后,并不能从其获取哪一个对象(字符串stringID)获取了钥匙,那么请你将semaphore封装到一个类中,重新定义get()/put(方法,并且通过最后的一个打印函数来得知当前获取钥匙的string ID是谁?示例代码大致如下,请完成提示需要完成的地方,对你的代码进行编译和仿真,展示你的代码和仿真的打印消息。
答:sv代码如下

module tb;class smart_key;semaphore s;//创建旗语string holder;function new(N= 1);s = new(N);//分配1把钥匙endfunctiontask get(int N= 1,string str);//请添加需要的参数,并且实现该方法s.get();//拿到钥匙holder = str;#1ns;//$display("%0t: %s get the key",$time,str);endtasktask put(int N= 1,string str);//请添加需要的参数,并且实现该方法s.put();//放回钥匙#1ns;//$display("%0t: %s put the key",$time,str);endtaskfunction void print_key_holders();//请事先该方法,使其能够打印出当前获得钥匙的ID$display("%0t: now %s hold the key",$time,holder);endfunctionendclass: smart_keyinitial beginsmart_key skey = new();string string1 = "A";string string2 = "B";string string3 = "C";fork begin skey.get(1,string1);skey.print_key_holders();skey.put(1,string1);endbegin skey.get(1,string2);skey.print_key_holders();skey.put(1,string2);endbegin skey.get(1,string3);skey.print_key_holders();skey.put(1,string3);endjoin
endendmodule: tb

仿真结果:

1000: now A hold the key
2000: now B hold the key
3000: now C hold the key

3. 我们在使用信箱mailbox时,如何可以限定其容量为8,并且只能存放string类型呢?那么,是否类似的方法也可以限定一个存放字符串的队列其最大容量为8呢?
答:声明方法如下

mailbox #(int) mb;
mb = new(8);

队列空间是动态的,不能限定其最大容量。

写的不错,可以参考:SV学习笔记—线程之间的通信(事件event、信箱mailbox、旗语semaphore)_Verification_White的博客-CSDN博客_sv event

这篇关于SystemVerilog学习笔记(九)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/850464

相关文章

51单片机学习记录———定时器

文章目录 前言一、定时器介绍二、STC89C52定时器资源三、定时器框图四、定时器模式五、定时器相关寄存器六、定时器练习 前言 一个学习嵌入式的小白~ 有问题评论区或私信指出~ 提示:以下是本篇文章正文内容,下面案例可供参考 一、定时器介绍 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成。 定时器作用: 1.用于计数系统,可

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[word] word设置上标快捷键 #学习方法#其他#媒体

word设置上标快捷键 办公中,少不了使用word,这个是大家必备的软件,今天给大家分享word设置上标快捷键,希望在办公中能帮到您! 1、添加上标 在录入一些公式,或者是化学产品时,需要添加上标内容,按下快捷键Ctrl+shift++就能将需要的内容设置为上标符号。 word设置上标快捷键的方法就是以上内容了,需要的小伙伴都可以试一试呢!

Tolua使用笔记(上)

目录   1.准备工作 2.运行例子 01.HelloWorld:在C#中,创建和销毁Lua虚拟机 和 简单调用。 02.ScriptsFromFile:在C#中,对一个lua文件的执行调用 03.CallLuaFunction:在C#中,对lua函数的操作 04.AccessingLuaVariables:在C#中,对lua变量的操作 05.LuaCoroutine:在Lua中,

AssetBundle学习笔记

AssetBundle是unity自定义的资源格式,通过调用引擎的资源打包接口对资源进行打包成.assetbundle格式的资源包。本文介绍了AssetBundle的生成,使用,加载,卸载以及Unity资源更新的一个基本步骤。 目录 1.定义: 2.AssetBundle的生成: 1)设置AssetBundle包的属性——通过编辑器界面 补充:分组策略 2)调用引擎接口API

Javascript高级程序设计(第四版)--学习记录之变量、内存

原始值与引用值 原始值:简单的数据即基础数据类型,按值访问。 引用值:由多个值构成的对象即复杂数据类型,按引用访问。 动态属性 对于引用值而言,可以随时添加、修改和删除其属性和方法。 let person = new Object();person.name = 'Jason';person.age = 42;console.log(person.name,person.age);//'J

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

《offer来了》第二章学习笔记

1.集合 Java四种集合:List、Queue、Set和Map 1.1.List:可重复 有序的Collection ArrayList: 基于数组实现,增删慢,查询快,线程不安全 Vector: 基于数组实现,增删慢,查询快,线程安全 LinkedList: 基于双向链实现,增删快,查询慢,线程不安全 1.2.Queue:队列 ArrayBlockingQueue:

硬件基础知识——自学习梳理

计算机存储分为闪存和永久性存储。 硬盘(永久存储)主要分为机械磁盘和固态硬盘。 机械磁盘主要靠磁颗粒的正负极方向来存储0或1,且机械磁盘没有使用寿命。 固态硬盘就有使用寿命了,大概支持30w次的读写操作。 闪存使用的是电容进行存储,断电数据就没了。 器件之间传输bit数据在总线上是一个一个传输的,因为通过电压传输(电流不稳定),但是电压属于电势能,所以可以叠加互相干扰,这也就是硬盘,U盘

人工智能机器学习算法总结神经网络算法(前向及反向传播)

1.定义,意义和优缺点 定义: 神经网络算法是一种模仿人类大脑神经元之间连接方式的机器学习算法。通过多层神经元的组合和激活函数的非线性转换,神经网络能够学习数据的特征和模式,实现对复杂数据的建模和预测。(我们可以借助人类的神经元模型来更好的帮助我们理解该算法的本质,不过这里需要说明的是,虽然名字是神经网络,并且结构等等也是借鉴了神经网络,但其原型以及算法本质上还和生物层面的神经网络运行原理存在