systemVerilog知识汇总
扫描二维码
随时随地手机看文章
interface
Verilog语言使用端口名字连接各个模块;
systemVerilog中使用“.*”可以自动匹配具有相同名字的线网和端口,自动连接的名字必须具有相同的端口位宽,连接的端口类型必须兼容;也可以使用“.name”进行连接,.name必须满足端口名字和位宽一直;
Verilog传统连接的缺点:通信协议接口在多个模块中使用,在多个模块中都要声明相应的端口,同时不匹配的声明会导致编译错误,设计文档修改端口名后需要修改所有的模块;
interface中集合了多个Verilog类型的信号,是一个独立的端口类型,可以简化端口连接。interface包含了连接,同步,甚至多个块之间的通信,只要在interface里面声明过的信号与端口,在其它模块中都可以使用。
interface的优势:
接口便于设计重用,当两个块之间有两个以上的信号连接,并且使用特定的协议通信的时候,应当考虑接口;如果接口组一次又一次的重复出现,应该考虑虚拟接口;
接口可以用来替换原来在模块或者程序中反复声明并且位于代码内部的一系列信号,减少了连接错误的可能性;
要增加一个信号时,只需要在借口中声明一次,不需要在更高层声明,这减少了连接错误的可能性;
modport允许一个模块很方便的将接口中一系列信号捆绑在一起,也可以为信号指明方以便工具自动检查。
interface的劣势:
必须同时使用接口名和信号名,可能会使模块变得更加冗长;
如果连接的两个模块使用的是一个不会被重用的专用协议,使用接口需要做更多的工作;
连接两个接口很困难;
对于点对点的连接,使用modport的接口描述跟使用信号列表的端口一样的冗长。
modport为接口内部的信号提供了不同的视图,在interface中可以提供任意数量的modport。
clocking可以保证测试平台在正确的时间点和信号交互(驱动过早或者过晚都会引起竞争),将信号同步到一个特定的时钟上。interface可以包含多个clocking。
program block的好处
将验证平台与待测设计分隔开;
在不同的时间域运行,减少了竞争现象;
数据类型
在Verilog中,初学者经常分不清reg和wire两者的区别,在sv中对此进行了改进,这种新的数据类型为logic,但要求logic不能有多个结构性的驱动。logic有四种状态:0,1,x,z。
二值变量(只有两种状态,不用做rtl设计,提供仿真性能,减少内存使用量):bit,byte,shortint,int,longint
逻辑仿真特性:
四值状态变量的默认初始值为x,二值状态变量的默认初始值为0;
二值初始变量不能表示未初始化状态;
四值状态变量可以赋值给二值状态变量,x和z会转换成0;
$isunknown()可以检测表达式中是否存在x或者z。
固定数组
支持多维数组;
超过边界的写操作会被忽略;
超过边界的读操作返回值为x;
byte,shortint,int存放在32位的存储空间中;
longint存放在64位的存储空间中
填充数组
混合数组
动态数组
队列
队列具有排序和搜索的功能;
迅速分配额外的空间和额外的元素;
支持push和pop的操作;
支持add和remove元素操作;
可支付之固定数组和动态数组的值给队列;
不需要new函数
当满足以下条件时,动态数组和固定数组可以互相复制:相同的数据类型和相同数目的元素。
结构体
具有一组变量或者常数组成的集合,可以作为一个整体进行操作,也可以操作其中的一部分;
将逻辑上相关的信号放在一起,比如一些总线协议;
可以利用结构体的名字操作整个变量。
枚举
抽象变量代表一个数值序列;
用户可以定义每一个值;
增加了可阅读性;
支持first,last,next,prev操作;
枚举类型默认为int,所有数值需要唯一
function
函数执行过程中不消耗仿真时间,所以函数中不能有控制时间的语句。
task
含有input,output或者inout语句;
消耗仿真时间
封装:类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏。通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分;
继承:是指可以让某个类型的对象获得另一个类型的对象的属性的方法。继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。通过继承创建的新类称为“子类”或“派生类”,被继承的类称为“基类”、“父类”或“超类”。继承的过程,就是从一般到特殊的过程。
多态:就是指一个类实例的相同方法在不同情形有不同表现形式,比如build_phase中的create。体现不同的效果;
虚函数
参数化类
随机化
rand关键字声明随机变量(指定范围内均匀分布)。
周期性关键字randc(数据类型只能是bit或者enum)。
constraint语句约束块。
randomize将对象中的随机变量赋值。
seed随机种子。
dist数值分布操作符(randc的随机变量不能设置权重)。
:=指定的数值具有相同的分布权重;:/指定的数值均分权重。
双向约束
solve before
random_mode()
constraint_mode()
并发线程
并发线程没有固定的先后执行顺序;
join
join any
join none
当一个线程执行时,只有遇到wait语句才会停止;
当正在执行的线程遇到等待语句时,在队列中的ready 状态的线程可以执行;
当所有的线程进入wait状态时,仿真时间更新,进入到下一个仿真周期;
wait fork:等待所有的并发进程执行完成;
disable fork:停止所有并发子线程的执行;
线程内部通信
Verilog event:触发事件的操作符:->;等待事件的操作符:@
事件 event
不需要声明为全局变量,就可以将event作为共享资源使用;
触发事件的操作符:->(阻塞触发:触发一个事件不会阻塞当前等待事件的所有进程,边沿敏感信号)和->>(非阻塞触发:在事件发生的时间点创建一个非阻塞赋值);
等待一个事件被触发的操作符:@和wait;
triggered函数用来检查一个事件是否被触发过,返回值是一个状态;
wait_order;
事件变量:Event是一个独立的数据类型,可以进行赋值,当把一个事件复制给另外一事件时,原事件与目的事件共享原事件,两个事件合并为一个事件;当事件合并时,赋值操作仅仅会影响目的事件的执行或等待操作;
取消事件:当一个事件赋值为null,与该事件变量同步的进程无效;
比较事件:不同的事件可以进行比较;
旗语 semaphore
semaphore通常用于对共享资源的分配和同步;
共享资源在不同的进程中是互斥使用的;
new();get();put();try_put();
在验证平台,常用semaphore对共享资源进行分配,比如系统总线,在同一个时间点,只能有一个驱动使用总线;
邮箱 mailbox
mailbox是sv中不断进程间的通信方式;
将一个进程中的数据通过mailbox传递给另外一个进程,当mailbox没有数据时,线程将等待;
mailbox类似一个FIFO,可以设置一定的深度queue size;当邮箱中的信息数量达到邮箱的深度时,邮箱为满;如果邮箱为满,进程就不能再往邮箱中存放消息,直到邮箱中的信息被取走;
new();put();get();try_put();try_get();peek();try_peek();num();
如何在两个线程之间传递消息:生成器生成事务数据包,然后传递给驱动器;生成器和驱动器必须是异步操作;如果生成器和驱动器之间需要同步,则需要额外的握手信息;