目录

0.interface的直观理解

1.使用端口的TB与DUT通信

2.使用接口的TB与DUT通信

3.使用modport将interface中的信号分组

4.接口中的clocking block

4.1为何要引入clocking block?

4.2clocking block的作用

5.接口信号的驱动和采样

5.1接口信号的采样

5.2接口信号的驱动

5.3输入/出偏差input/output skew


0.interface的直观理解

若想将TB和DUT连接起来,按照最常规的方法,是通过映射的方法将各个端口的信号一一连接,如下图所示,当一个DUT的信号有几十个甚至上百个的时候,就产生了许多的连线,一一连接十分繁琐且容易出错。

因此我们引入接口的方法,我们可以把接口类比成一根HDMI线,其内部包含了许多子线,使它们按照规定好的输入/出规则排列,因此使用的时候用的时候直接连接即可,而省去了一根一根线连接的繁琐操作。

下面我们通过代码进一步理解其使用方法。

1.使用端口的TB与DUT通信

如下是一段仲裁器的RTL代码,可见其在起始部分一一描述了端口的类型和方向,这里需要注意的是以下代码用了SV的变量类型logic,一般来说,设计人员主要还是用verilog语言来写RTL代码,即在端口声明时用的不是logic而是reg/wire型。

module arb_port(output logic [1:0] grant,output logic grant_valid,input logic [1:0] request,input logic rst,input logic clk);//DUT的输入/出信号声明,相当于一根一根的线······endmodule

以下代码是一个针对上述代码的简单的测试平台,其仍然使用端口来与DUT一一连接:

module test(input logic [1:0] grant,input logic grant_valid,output logic [1:0] request,input logic rst,input logic clk);//通过每根线一一连接initial begin//激励产生@(posedge clk) request <=2’b01;$display(“@%05: Drove req=01”,$time);repeat(2) @(posedge clk )if(grant_valid &&(grant!=2’b01))$display(“@%0t:a1:grant!=2’b01”,$time);·······$finish;end
endmodule

再创建一个顶层控制文件,用来连接DUT和TB:

module top;logic[1:0]grant, request;logic grant_valid;bit clk,rst;always #5 clk=~clk;//实例化DUT和TEST文件arb_port a1(grant, grant_valid, request, rst, clk);test t1(grant, grant_valid, request, rst, clk);
endmodule

由上述可见,若一个DUT包含上百个端口信号,则在TB和TOP中去声明每一个端口是非常繁琐的事情,且还容易出错,因此我们引入接口interface的方法,来简化这种繁琐的声明。

2.使用接口的TB与DUT通信

一般设计人员不会按照接口的方式声明端口,它他们仍然用端口的方式声明,因此此处RTL代码同上:

module arb_port(output logic [1:0] grant,output logic grant_valid,input logic [1:0] request,input logic rst,input logic clk);······
endmodule

验证人员拿到RTL代码后,会先写一个接口文件来简化连接,如下:

interface arb_if(input bit clk);//外部时钟,一般clk和rst都由top生成,所以这里作为input输入logic[1:0] grant,request;//使用logic类型,就不用管信号是input还是output,但logic不支持inout信号!!logic grant_valid;logic rst;
endinterface

此时再写TB时,端口信号声明会大大简化:

module test(arb_if arbif);//接口的例化,繁琐的端口声明被简化,相当于连接了一次“HDMI”线initial begin@(posedge arbif.clk) arbif.request <=2’b01;//这里要注意,信号要写成 arbif.信号的形式,表明是接口中的信号,并注意接口信号必须使用非阻塞赋值来驱动!!!$display(“@%05: Drove req=01”,$time);repeat(2) @(posedge arbif.clk )if(arbif.grant_valid &&(arbif.grant!=2’b01))$display(“@%0t:a1:grant!=2’b01”,$time);·······$finish;end
endmodule

顶层TOP控制文件,用来连接DUT和TB:

module top;bit clk;always #5 clk=~clk;//生成时钟arb_if arbif(clk);//例化接口,不用再一一书写端口arb_port a1(.grant(arbif.grant),.request(arbif.request),.rst(arbif.rst),.clk(arbif.clk)); //连接DUT,由于RTL代码信号声明并未采用接口的方式,因此通过这种信号映射的方式连接test t1(arbif); //连接tb
endmodule:top

此时相当于TB和DUT的连接如下图所示,将对应的端口一一连接,但并没有指明每个信号相对于TB和DUT的相对方向,所以又引入了modport。

Δ注意接口一定要在模块儿和程序块儿外部声明,因为接口是对测试平台和DUT都可见的,如果在模块儿内部声明,则只对内部可见,对外部不可见,如下就是错误的:

module bad_tset(arb_if itf);`include "arb_if.sv"//错误
endmodule

3.使用modport将interface中的信号分组

interface arb_if( input bit clk);logic[1:0] grant,request;logic grant_valid;logic rst;modport DUT(input request, rst, clk, output grant,grant_valid);//信号相对于DUT是输入/出?modport TEST(output request, rst, input grant,grant_valid,clk);//信号相对于TB是输入/出?endinterface

此时相当于将各个信号相对于TB和DUT是输入/出都规定好,使代码信号方向更清晰明了,如下图:

一旦使用modport,则DUT(如果用接口方式声明)/TB中的接口信号声明就要这么写:

module arb_port(arb_if.DUT arbif);//相当于声明是interface中定义的DUT的modport中的信号
......endmodule

其实设计人员不会管接口的,他们仍然按照Verilog的方式写

module test(arb_if.TEST arbif);//相当于声明是interface中定义的TEST的modport中的信号
......endmodule

顶层TOP模块不变,仍然按照原来的写。

4.接口中的clocking block

4.1为何要引入clocking block?

在SystemVerilog中引入时钟块是为了解决在写testbench时对于特定时序和同步处理的要求而设计的,但对其深入的了解,由于初学还未能理解透彻,因此本部分会在后续补上。

4.2clocking block的作用

在interface中定义clocking block可以指定信号相对于时钟的时序,被定义在时钟块儿的信号都将被同步的驱动或者采样。示例代码如下:

interface arb_if( input bit clk);logic[1:0] grant,request;logic grant_valid;logic rst;clocking cb @(posedge clk); // 声明一个时钟模块cb,里面的信号根据相对于TB方向指定是输入/出?output request;input grant,grant_valid;endclockingmodport TEST(clocking cb,output rst);//为TB声明信号方向,使其更明了,这里可直接调用clocking,表明这些信号是同步的驱动或者采样;单独声明的rst表明这个信号不受clocking约束,是一个异步信号modport DUT(input request,rst,output grant);//为DUT声明信号方向endinterface

需要注意的是,根据https://www.cnblogs.com/xh13dream/p/9016356.html和一些示例代码可以发现:clocking block中的信号,被驱动时采用非阻塞赋值,被采样时采用阻塞赋值。如下所示:

5.接口信号的驱动和采样

5.1接口信号的采样

对于一个DUT的信号输出grant,clock block的cb.grant输出如波形所示:

可见在30ns处,在时钟上升沿,采样的到的信号不是后一时刻的3而是前一时刻的2;这是因为DUT是硬件,其信号需要建立时间和保持时间,但在30ns处直接发生了跳变,因此采样值保持前一时刻的2。

5.2接口信号的驱动

TEST将arb.cb.request驱动给DUT,DUT接收到的request的波形如图所示:

可见在30ns处,DUT接收到的值并不像5.1那样保持前面的值2,而是接收到后面的值1;这是因为TEST是软件,没有建立时间保持时间的概念,只要值有变化,立马反映到输出上,因此在时钟跳变沿直接发生跳转。

如果想在驱动一个信号前等待2个时钟周期,可以使用如下第一种方式或者第二种方式,但第二种方式必须在时钟块儿里的信号作为驱动信号赋值的同时使用,因为##必须知道是按照哪个时钟来做延时:

repeat(2) @arbif.cb;//等待2个时钟周期
##2 arbif.cb.request<=0;//等待2个时钟周期后赋值
##3;非法,必须和clocking块儿内的信号赋值时同时使用

5.3输入/出偏差input/output skew

为了解决5.1和5.2的问题,SV中引入了输入/输出偏差的方法使得TB采样到的值和DUT接收到的值恒为clk跳变沿之后的值。代码如下所示:

interface master_if(input bit ck)logic[7:0]data;clocking cb@(posedge clk);default:input #1step ouput #0;//定义输入/出偏差input data; endclockingmodport TEST(clocking cb);
endinterface

关于default的介绍和实际用途可见https://blog.csdn.net/qq_41337361/article/details/122156036介绍。

System Verilog学习笔记—接口interface相关推荐

  1. System Verilog学习笔记—虚接口(virtual interface)

    1.虚接口(virtual interface) 1.1为什么引入虚接口? 我们知道,通过引入interface可以简化模块儿之间的连接,即interface是连接硬件的,其是硬件语言:但对于验证来说 ...

  2. System Verilog学习笔记—fork...join_xxx的三种用法及wait fork和disable fork

    目录 0.前言 1.fork...join 2.fork...join_any 3.fork...join_none 4.其它线程执行语句 4.1wait fork 4.2 disable fork ...

  3. System Verilog学习笔记—随机化约束的控制

    目录 1.控制多个约束块儿constraint_mode() 2.控制随机变量 2.1 rand_mode() 2.2 randomize() with {} 2.3 randomize单独控制变量 ...

  4. System Verilog学习笔记—随机化约束种类

    1.为什么引入随机化? 芯片体积增大,复杂度日渐提高,定向测试已经无法满足验证的需求,而随机测试的比例逐渐提高 定向测试能找到你认为可能存在的缺陷,而随机测试可以找到连你都没有想到的缺陷 随机测试的环 ...

  5. go学习笔记接口部分

    Go学习笔记 接口 接口定义方法 练习 11.1 simple_interface.go: 练习 11.2 interfaces_poly2.go: 接口嵌套接口 如何判断接口类型 方法一varI.( ...

  6. system generator学习笔记【02】

    作者:桂. 时间:2018-05-20  23:28:04 链接:https://www.cnblogs.com/xingshansi/p/9059668.html 前言 继续学习sysgen.接触s ...

  7. Verilog学习笔记-——Verilog模块例化

    Verilog学习笔记---Verilog模块例化 在一个模块中引用另一个模块,对其端口进行相关连接,叫做模块例化.模块例化建立了描述的层次.信号端口可以通过位置或名称关联,端口连接也必须遵循一些规则 ...

  8. 【Verilog学习笔记】D触发器(门级和行为级)+4位寄存器+一个完整的激励程序

    [Verilog学习笔记]D触发器(门级和行为级)+4位寄存器+一个完整的激励程序 首先展示以下完整的程序 `timescale 1ns / 1psmodule hardreg( input wire ...

  9. 我的 System Verilog 学习记录(1)

    引言 技多不压身,准备开始学一些 System Verilog 的东西,充实一下自己,这个专栏的博客就记录学习.找资源的一个过程,希望可以给后来者一些借鉴吧,IC找工作的都加把油! 本文是准备先简单介 ...

最新文章

  1. mysql的常用函数
  2. 8月精选Python开源项目Top10
  3. php仿微信底部菜单,Android实现简单底部导航栏 Android仿微信滑动切换效果
  4. TensorFlow练习23: “恶作剧”
  5. python官网下载步骤linux-官方下载python源码,编译linux版本的python
  6. redis占用内存过低_使用多种数据结构优化Redis 内存占用
  7. ALL in BERT:一套操作冲进排行榜首页
  8. 缓存在哪里_什么是MyBatis缓存技术
  9. oracle sysnonym,Oracle权限
  10. Python高级——魔法属性和方法
  11. mac 内核调试环境搭建
  12. 【区块链】区块链学习要点记录
  13. adb 连接手机 cannot connect to xxx.xxx.x.xx:5555: 由于目标计算机积极拒绝,无法连接。 (10061)
  14. FastStone Capture 9.3 汉化绿色便携版 - 极品屏幕截图工具
  15. 常用快捷键及cmd命令
  16. 反应釜cad图_反应罐系列图(5张图)CAD格式
  17. Android cpu降频工具,免root安卓cpu降频软件-安卓cpu降频软件免root版下载-游戏大玩家...
  18. 【个人】项目实训 | 图片风格_流年滤镜
  19. 2015 iMac如何绕过TMP安装Windows11(不用Parallels虚拟机实现macOS与Windows11双系统)
  20. linux bmp图片怎么转换成ppm,ppm图像格式与bmp之间的相互转换

热门文章

  1. 关于嵌入式系统维修解决方案
  2. for(i=0,j=0;i10,j6;i++,j++)问题
  3. 50万数据生成6位数不重复字符串_提醒:你收到一套函数。这套函数全吃透,文本处理不发愁。进阶二...
  4. 一力降十会:顺丰生鲜流通的科技之力
  5. Vegas修剪器窗口的使用介绍
  6. html 功能性链接,web前端之html(三)超链接、锚链接和功能性链接
  7. mysql解压安装教程 windows_windows下MySQL解压版安装
  8. Android 的全新的 Play Widget
  9. Lego神搭建-智能物流系统:堆垛机-机械收、出入库、升降机……
  10. 用python做科学计算的好处_使用Python做科学计算初探(转)