systemverilog testbench
课程内容
- 验证计划和验证环境
- sv语言的验证属性
- svtb
- 接口interface
- 面向对象编程OOP
- 随机化randomization
- 线程Threads
- 内部通信 Interprocess Communication
- 功能验证Functional Coverage
- 断言Assertions
svtb功能
- 产生激励
- 将激励输入到待测设计
- 获取响应
- 检查响应的正确性
- 根据验证目标评估验证进度
随机数产生,在makefile中
SEED = $(shell data+%s)
./simv +pulsargs_save +seed=$(SEED)
在tb.v中
din = $random(seed);
how do I verify my design-->Verification plan
- what resources will i need?
- what will we should verify?
- am i driving all possible input scenarios?
- how will i know a failure has occurred?
- how do i measure my progress?
- when will i be done?
contents of verification Plan
- description of verification levels(unit->block->IP)
- required tools(一般vcs+verdi)
- risks and dependencies(例如需要算法组提供模型,那进度也受影响)
- functions to be verified(输入的变动,寄存器配置的变动)
- specific verification methods(uvm.etc)
- coverage requirements
- testcase scenarios
- resource requirements(工具license,VIP等)
- schedule details(时间点)
function to be verified
- 关键功能
- 次要功能(对TO不致命的 如性能相关的功能、下一版才使用的功能、软件可绕过的缺陷、应用不会出现的场景)
- 普通的功能(复位与时钟产生,错误处理,debug逻辑)
- 在当前验证层级不需要验证的功能,在其他层级保证
Feature of an effective testbench
- reusable and easy to modify for different DUVs -- OOP
- testbench should be layered to enable resuse ---分层testbench
- catches bus and achieves coverage quickly --Randomize
封装
到任务7
传统verilog通过.name(wire_name),
连接DUT与testbench
sv支持.*连接eg.
u_a1 a1(.*);
u_b1 b1(.*);
或者'.name,'而省略括号内容
interface
- top与interface连接
或
- tb与interface连接
- interface里也可以加function和task
interface modport
- modport带方向,实际上是module port的缩写
Stimulus Timing
- 由此引入clocking block,其中step为时间精度,若
timescale 1ns/1ps
则为1ps
- clock skew
- 在interface中插入clocking block,以及使用方法
arbif.cb.request<=2'b01;
- '##2'表示等两个时钟周期
program block
- 示例
System verilog Data type
1 两值逻辑,减少内存消耗
2 队列,动态数组,联合数组,有自建的寻找和排序方法
3 unpack与pack数组,如unpack a[0]与a[1]占各自占32位的一位;pack压缩,a[0],a[1]共用一个32位
4 class
5 strings:内建string支持
6 enum枚举类型,增加代码可读性
verilog对于赋值全1比较麻烦
- system verilog的解决方案
logic很通用,除了不能用于双向口,双向口必须用wire
下表的类型都为二值逻辑,赋x和z转为0
$isunkown
可以查出x和z
- unpacked arrays
- 数组初始化可以用`{},
- 也可以用$size结合for(注:下图for缺begin end)
- 也可以用foreach遍历
- foreach也可以初始化二维数组
数组比较:直接全部比较src==dst
或部分比较src[1:4]==dst[1:4]
数组拷贝:直接dst=src
注意数组不能算术运算,比如相加
sv增加二进制打印$displayb
packed array压缩数组
bit [3:0] [7:0] bytes
- 压缩数组赋值可以
logic [3:0] [7:0] a = 32'h0;
,压缩数组可以看成一个数,可以使用@p_array
来表示数组变化
压缩数组与非压缩数组的下标排列
动态数组通过[]声明,$size也可以用于动态数组
- 动态数组声明,使用new进行动态分配
队列Queue通过data_type queue_name[$];
- 队列可以轻易插队
联合数组associative array通过data_type associative_array[*];
- 联合数组下标可以是其他数据类型,不一定是数字
- 联合数组也省空间
数组的方法sum,product,and,or,xor
数组总结
结构体Structure
- structure are unpacked by default,可以加packed关键字
- 压缩结构体可以按地址赋值,也可以利用逗号赋值,类似函数
枚举类型
- 枚举类型定义
操作符Operators,红色为较verilog新增
sv过程性语句procedural
- 比较符号==和!=如果一边为x则返回x
=和!只会返回0或1 - sv增加==?和!=?其中?相当于通配符
- sv中引入 inside
- 类型转换type'(expression)
- 位宽转换type'(expression)
- 对于有符号的数signed与unsigned转换
- sv允许在for循环里定义变量防止不同for循环变量i相互影响
- sv增加do ...while,至少执行一次
- sv中有casex,casez;有unique和priority
TASK and Function
-
function 不消耗时间
-
verilog中的function必须返回值return,sv中可以返回void
-
function加input output 返回void
-
Task消耗时间
-
Task可以有input output inout
-
reference传的是句柄,值会变(少用),sv中function和task可以.name(wirename)传参
OOP
- oop将复杂的数据类型和相应的方法封装在一起
- class是图纸,object是房子(实体)(通过new新建),handle是地址,properties是电灯开关,methods是开灯/关灯的操作(task、function)
- class定义
- class调用
- 空间释放用
b=null
-希望在class里声明静态变量
- shallow copy对于普通变量只是拷贝,对句柄和原来指向同样的地址,共用一个对象
- deep copy
- 注意
t1.data=5
继承
多态
-多态请自己查网络资料
-参数化的class
Randomization
why randomize
- direct test无法覆盖全部features
- deirect case测出的错误一般是预想到的
怎么用random
- DUT 不同工作模式的configuration
- 控制bench的不同工作模式
- 输入数据的random
- 随机注入错误
- 合法的delay,时钟抖动
- rand关键词,如
rand bit[7:0] y;
- randc关键词 c是cyclic的意思 ,只能用在bit与enum类型
randc bit[1:0] y;
,每个数都会出现一次不重样 - constraint使数落在特定范围
- constraint可以利用inside
- randomize() function与以上关键字结合使用
- random的结果与seed有关,seed与仿真工具有关
- dist权重,使用
:=``:/
- 条件性 constraint
- 数组约束
- rand_mode()开关随机属性
- constrasint_mode()开关约束属性
线程 fork-join和组件通信
fork-join
- fork-join等全部进程结束再执行主进程
- fork-join_any等一个运行完再执行主进程,注意子进程还会继续执行
- fork-join_none主程序直接往下走,注意子进程还会继续执行
- fork-join里的begin-end并发
- wait fork会等所有fork执行完主进程再继续
- disable fork会杀掉子进程
组件通信Interprocess Communication
- Events
- 上图实际上有点问题,应该先等@(@是采边沿)再触发->
- 下图用
wait(e1.triggered)
修正
- wait_order
Semaphores
- semaphores类似钥匙池,如多设备访问同地址mem要拿到key才能操作,防冲突
- 有new(),set(),put(),try_get()
Mailboxes(类似fifo)
- mailbox可以无限长度或是固定长度,new()括号内无数字则无限
- get()取走信件,peek()只看不拿
System Verilog Coverage
- function piont根据design spec和test plan
- 为了达到高coverage,可以建direct test或修改约束
- 只有pass的case才能计入coverage
- 声明covergroup
- 用户定义bins
- 命名bins
- iff设置某些情况下收集覆盖率,reset为1不收集
- start,stop控制何时收集
- 发生序列coverage
- cross联合coverage
Assertion断言
- assertion通过property描述,示例
- assertion property表示设计必须满足的意图
- assertion 的优势
- 捕捉设计意图
- 允许定义和验证协议
- 减少time to market(找bug快)
- 极大简化重用ip的验证(assertion随rtl一起)
- 帮助达到功能覆盖率(如flash打印指令)
- assertion property封装在sequence·
- assertion在白盒策略中,可在模块内部做 interface assertion,structural assertions(状态机跳转)
- |->和|=>,前者是当前拍,后者是下一拍
-immediate assertion(类似if判断)与concurrent assertion(消耗时间的) - 立即assertion用
immediate_assert_statement ::=assert(expression) action_block
,当expression为0、x、z则fail
- concurrent assertion用property实现
assertion sequence
- c在b后0到3拍任意一拍为高
- $符号可表示结尾,任意远的一拍
- sequence嵌套
- 1个!b和b组合为1组repetition
- sequence $函数,与时钟无关
- $past为前一个周期的采样值
- and 对开始时间一样的sequence
- intersection开始时间和结束时间都要一样
- throughout持续时间,下图fail
- 多个时钟的序列,|->一定要##n
- |=> no overlap可以不用##1
- assert与assume
- cover用于收集断言覆盖率
- 收集 生效/成功/失败/伪真的次数