System verilog学习

本人的学习的一些小总结,写给自己,方便复习。一些总结性的摘要性的,可能自己才能看懂写的是什么鬼东西哈哈哈

1. 数据类型。

类型:变量variables/线网net。和Verilog不同的,对变量类型,可以使用连续赋值,或者过程赋值。

数据类型:四值逻辑logic/二值逻辑bit。

有符号/无符号。logic/bit构成的向量vector是无符号。integer,int,byte,short,int,longint有符号。

多驱动或者双向inout只能用 线网wire。logic不能被多驱动。

2. 自定义类型

typedefTypedef就是用来创建新的类型的。常常和enum/struct一起用,定义枚举类型/定义结构体类型。

枚举类型enum。默认的枚举类型是int。枚举类型可转换成整型。整型不能隐式的转换成枚举类型。

结构体struct

  

3. 字符串类型

4. 设计特性

= = / = = = 的区别。

inside

unique case。每次case选项只能满足一条,不能重叠。可以并行运行,case选项必须完备。

priority case。必须至少有一个case满足。

case(z)/case(x)

5. 接口interface

modport约束不同模块连接的信号方向。(常用在设计中)。

clocking block(常用在testbench)。

6. 采样和数据驱动

设计中,避免RTL仿真中的信号竞争。采用非阻塞赋值或者特定的信号延迟来解决同步的问题。

clocking block(常用在testbench)。做信号的同步和采样。clocking block基于时钟周期对信号进行驱动或者采样的方式,使得testbench无需考虑准确及时的对信号驱动或者采样,消除信号竞争。

7. 任务和函数

function和task的区别:

  1. 任务可以消耗仿真时间,函数不可以。任务可以调用函数和任务,函数一般不能调用任务(只能在由fork...join_none语句中生成的线程中调用)。
  2. function只能返回一个单一数值,若不返回数值,应声明void。而task不会返回数值,只能通过output,inout或者ref的参数来返回。
  3. 函数至少有一个输入变量。任务可以没有或者多个输入(input)、输出(output)和双向(inout)变量

8. 数组

定宽数组:非组合型数组/组合型数组。

动态数组:

队列:

数组方法

9. 类class

封装/继承/多态(虚方法)。

类的成员默认是public。local(只有此类可以访问)/protect(此类和子类都可以)。

只要父类new函数没有参数,子类就会默认调用父类new函数(super.new写不写都调用)。若父类new函数有参数,则子类必须写super.new来调用父类new函数。必须继承new函数并调用,否则编译报错。

10. 包package

11. 随机约束

randomize()。randomize() with,内嵌约束。

系统函数:$urandom(),生成32位无符号随机数。$random(),生成32位有符号随机数。$urandom_range(max,min=0)。

类的成员变量:整型变量(bit/byte/int)/数组(定长数组/动态数组/关联数组/队列)(数组一定要先约束长度size)声明为随机属性。rand/randc。

12. 约束块

rand integer x,y,z;

constraint C {x inside {y,z};};

权重设置:

constraint C_dist {x dist {0:=40, 1:=60};};

constraint C_dist {x dist {0:/40, 1:/60};};

:=

:/

unique

条件约束

 软约束soft 约束覆盖。

13. 随机控制

rand_mode(0)/ rand_mode(1)/

14. 约束控制

constraint_mode()

15. randomize()

随机化个别变量。使用随机化函数时randomize(),如果有参数,例如randomize(x)。那么只随机化x(不管有没有声明rand),其他不管(不管有没有声明rand)。

16. 数组约束

foreach约束数组每一个成员。约束数组的size。

17. 线程控制

fork join/fork join_any/fork join_none

wait fork:等待所有fork进程全部执行完。

disable fork:停止fork…join_any中所有没有来得及执行的并发子线程。

18. event

event是2个线程之间的通信

触发:-> (非阻塞)(类比于接电话)

等待:@ or wait(阻塞)

若用->和@搭配,一定要先@再->;若用->和wait搭配,则谁先谁后都可以。@是边沿触发,wait是电平触发。event e1;@e1/wait(e1.triggred); ->e1;

Wait_order: 阻塞等待多个事件的触发,并且要求这多个事件按照用户决定顺序触发。wait_order可以和else一同使用,当多个事件 按顺序触发时,执行wait_order后的语句,否则执行else后的语句。

19. semaphore旗语

≥2个线程之间的通信。共享资源管理,多个线程访问某一个公共资源时可以使用这个要素;

20. mailbox信箱

类似FIFO,数据传输的媒介,在线程之间做数据通信或内部数据缓存时可以考虑此元素。

21. 虚方法/多态

类的三个小知识:1.小白不要给变量添加local/protect,给自己挖坑。2.类继承的时候,为了操作简单,为了能访问到更多的变量,子类和父类不要出现同名的变量。但是子类和父类出现同名的方法是常见的,因为经常要override重载方法或者继承方法。3.用不同类型的句柄(子类句柄赋值给父类句柄,复制后都指向子类对象)调用相同对象的方法时,为了让输出结果一致,要在父类或者根类声明virtual。

22. 类型转换

静态类型转换:

动态类型转换:$cast()。父类句柄赋值给子类句柄。确保该父类句柄所指向的对象是子类句柄类型的对象。(应用场景:实际项目中简化操作)。

23. 断言assertion

断言是设计的属性的描述

即时断言:1.不是时序相关的,是立即被求值2.必须放在过程快中3.只能用在动态仿真中。用不用无所谓。

并发断言:1.基于时钟周期2.可以放到过程快,模块,接口,或者program中3.可以在形式验证或者动态仿真工具中使用。时序检查

sequence/property

断言$past的用法:例如让你写abcd四个信号在时钟沿处监测,当cd同时为1时,在时钟的前两个周期要ab同时为1的断言.

property P1;

@(posedge clk) (c&&d)|->($past(a&&b,2)==1);

endproperty

a1:assert property(P1);

24. 接口上使用output和ref的区别是:

1. output 端口用于将信号值从模块(或接口)的内部传输到外部。它只能在模块(或接口)内部驱动,外部只能读取值,不能驱动它。单向

2. ref 端口用于通过引用传递变量, ref 变量的改变会直接反映在引用者和被引用者之间。它允许双向的读写访问,并使得参数的改变可以在调用者和被调用者之间直接传递。ref 端口只能是 var(变量)。双向

3. 接口模块里的信号不能定义方向,需要定义方向时使用modport指定interface相应模块里的信号方向和分组,若没有使用modport定义方向,接口中的线网信号默认为inout变量默认为ref

  • 34
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值