1. 验证环境结构
1.1 测试平台
测试平台(testbench)是整个验证系统的总称。
- 包括验证结构中的各个组件、组件之间的连接关系、测试平台的配置和控制。
- 从更系统的意义来讲,它还包括编译仿真的流程、结果分析报告和覆盖率检查等。
- 从狭义上讲,我们主要关注验证平台的结构和组件部分,他们可以产生设计所需要的各种输入,也会在此基础上进行设计功能的检查。
- 测试平台结构图 * 各个组件之间是相互独立的 * 验证组件与设计之间需要连接 * 验证组件之间也需要进行通信 * 验证环境也需要时钟和复位信号的驱动
- 验证语言
- SystemVerilog的使用比例明显占据主导地位。
- SystemC和C/C++在验证部分也有其应用空间。
- 方法学(UVM)的统一已经完成。
2. 验证环境组件
2.1 激励发生器
- 概念
Stimulator(激励发生器)是验证环境的重要部件,在一些场合中,它也被称为driver (驱动器)、BFM(bus functionmodel,总线功能模型), behavioral(行为模型)或者generator(发生器)。 - 主要职责
Stimulator的主要职责是模拟与DUT相邻设计的接口协议。Stimulator不应该违反协议,但不拘束于真实的硬件行为,还可以给出更多丰富的只要协议允许的激励场景。 - 接口
Stimulator的接口主要是同DUT之间连接
较精细的stimulator还可以有其它的配置接口用来控制接口的数据生成。
Stimulatort也可以有存储接口数据生成历史的功能。 - 分类
- initiator (发起器)
- responder(响应器)
2.2 检测器
- 主要功能
Monitor(监测器)的主要功能是用来观察DUT的边界或者内部信号- 观察DUT边界信号。
对于系统信号如时钟,可以监测其频率变化;对于总线信号,可以监测总线的传输类型和数据内容,以及检查总线时序是否符合协议。 - 观察DUT内部信号。
从灰盒验证的手段来看,往往需要探视DUT内部信号,用来指导stimulator的激励发送,或者完成覆盖率收集,又或者完成内部功能的检查。
- 观察DUT边界信号。
2.3 比较器
- 主要功能
模拟设计行为和功能检查 - 比较方式
- 线上比较(online check)
在仿真时收集数据和在线比较,并且实时报告。 - 线下比较(offline check)
将仿真时收集到的数据记录在文件中,在仿真结束后,通过脚本或者其它手段,进行数据比较。
- 线上比较(online check)
2.4 任务和函数
2.4.1 任务Task
- 任务的定义可以指定参数,input、output、inout及ref皆可。
- 任务可以消耗仿真时间。
- 任务可以调用其它任务或者函数。
- 虽然task不会返回值,但是我们依然可以利用return来使task结束。
不使用return:
`timescale 1ns/1ps
module test;
task mytask(input [7:0] x
,input [7:0] y
,output [15:0] z);
#5ns;
z = x*y - 1;
#5ns;
endtask
byte unsigned a = 3 ;
byte unsigned b = 4 ;
byte unsigned c;
initial begin
mytask(a,b,c);
repeat(5)begin
#1ns;
$display("@time %t c = %0d", $time, c);
end
end
endmodule
返回结果
time 11000 c=11
time 12000 c=11
time 13000 c=11
time 14000 c=11
time 15000 c=11
使用return:
`timescale 1ns/1ps
module test;
task mytask(input [7:0] x
,input [7:0] y
,output [15:0] z);
#5ns;
z = x*y - 1;
return;
#5ns;
endtask
byte unsigned a = 3 ;
byte unsigned b = 4 ;
byte unsigned c;
initial begin
mytask(a,b,c);
repeat(5)begin
#1ns;
$display("@time %t c = %0d", $time, c);
end
end
endmodule
返回结果
time 6000 c=11
time 7000 c=11
time 8000 c=11
time 9000 c=11
time 10000 c=11
2.4.2 函数Funnction
- 参数方向声明
参数方向可声明为input、output、inout、ref,默认input类型。 - 函数返回方式
- 可以使用return直接返回值
return会立即返回 - 可以将值赋给与函数同名的变量
赋值给函数同名变量后将继续执行后续代码。
- 可以使用return直接返回值
- 代码示例
module test;
function automatic void myfunc1 (input [7:0] x
,input [7:0] y
,output [15:0] z);
z = x*y - 1;
endfunction
function [15:0] myfunc2 (input [7:0] x
,input [7:0] y);
myfunc2 = x*y - 1;
endfunction
initial begin
byte unsigned a = 3 ;
byte unsigned b = 4 ;
byte unsigned c1 , c2;
myfunc1(a,b,c1);
$display("c = %0d" , c1);
c2 = myfunc2(a , b);
$display("c = %0d" , c2);
end
endmodule
返回结果:
c = 11
c = 11
2.4.3 任务和函数的区别
仿真时间:function不会消耗仿真时间,而task则可能会消耗仿真时间。
调用:function无法调用task,而task可以调用function。
数据返回:一个可以返回数据的function只能返回一个单─数值,而任务或者void function不会返回数值。一个可以返回数据的function可以作为一个表达式中的操作数,而该操作数的值即function的返回值。
2.5 参数传递
- 参数默认方向
参数方向可声明为input、output、inout、ref,默认input类型。 - 默认数据类型
若没有声明数据类型,默认为1位宽的logic。 - 参数默认值*
带有参数默认值的方法被调用时,如果这些参数没有被传递值,那么编译器将会为这些参数传入对应的默认值。 - 参数与传递方式
- 位置调用
- 名字调用
3. 问答题:
- 激励器(stimulator)对于它所生成的激励,有什么办法将其所有激励数据保存下来?
Stimulatort也可以有存储接口数据生成历史的功能。 - function和task的比较?
仿真时间:function不会消耗仿真时间,而task则可能会消耗仿真时间。
调用:function无法调用task,而task可以调用function。
数据返回:一个可以返回数据的function只能返回一个单─数值,而任务或者void function不会返回数值。一个可以返回数据的function可以作为一个表达式中的操作数,而该操作数的值即function的返回值。 - 参数方向有哪些?差别在哪里?
参数方向可声明为input、output、inout、ref,默认input类型- input:输入端口
- output:输出端口
- inout:双向连接端口
- ref:input,output,inout作为参数传递的过程中是作为参数值传递的,数据在调用过程中均需要被复制。而ref参数传递的则为传递参数的引用地址,参数的传递方式指定为引用而不是复制,比input,output和inout更好用。可以把数组传递给子程序,在任务里可以修改变量而且修改结果对调用他的函数是可见的。