SystemVerilog interface使用说明

1. Interface概念

        System Verilog中引入了接口定义,接口与module 等价的定义,是要在其他的接口、module中直接定义,不能写在块语句中,跟class是不同的。接口是将一组线捆绑起来,可以将接口传递给module

2. 接口的优点

        一)通过接口在module之间或内部进行信号,模块的输入列表就是一个接口,这样简单,避免手动连线的错误。

        二)如果需要增加模块的IO,只需要在接口中增加,不需要改变模块的输入列表,防止输入错误、少改了哪个模块的列表。

        三)在UVM 中需要在不同的class之间传递信号,用接口的话,传递一组信号只需要uvm_config_db一个接口就可以了,如果不用接口,那么就需要好多条uvm_config_db语句。
        四)接口中可以定义一些initial(生成时钟),always块,任务,函数,类的句柄。

3. 定义接口

        可以在接口中定义一些信号、函数、任务、class对象,也可以有always,initial语句块。比如可以在initial块中生成时钟clk。

3.1 定义

interface if(input bit clk);
    logic data;
    logic valid;
    logic addr;
endinterface

3.2 modport

        可以用modport将接口中的信号分组。比如总线接口中,master、slave、arbiter需要的信号是不同的,输入输出也不同。
 

interface if(input bit clk);
    logic [7:0] data;
    logic valid;
    logic [7:0] addr;
    logic request;
    logic grant;
    logic command;
    logic ready;
    modport MASTER(output request,addr,command);
    modport SLAVE(input request,addr,command,output ready);
    modport ARBITER(input request,output grant);
endinterface
module Master (if.MASTER if_u);
...
endmodule
module test;
    if if_u;
    Master m_u(if_u.MASTER);
endmodule    

4. 激励时序

        测试平台需要和设计之间的时序密切配合。比如在同一个时间片内,一个信号需要被同时写入和读取,那么采样到新值还是旧值?非阻塞赋值可以解决这个问题,值的计算在active区域,值的更新在NBA区域——采样到的是旧值

4.1 时钟块控制同步信号的时序

        在接口中定义时钟块,时钟块中的任何信号都相对于时钟同步驱动和采样。时钟块大都在测试平台中使用。

interface if(input bit clk);
    logic [7:0] data;
    logic valid;
    logic [7:0] addr;
    clocking cb@(posedge clk);
        input valid;
        input data;
        input addr;
    endclocking
    modport TEST(clocking cb);
    modport DUT(input valid ,input data);
endinterface

        一个接口中可以有多个时钟块,但每个时钟块只有一个时钟表达式。如@(posedge clk)定义了单时钟;@(clk)定义了DDR时钟(双数据率,两个沿)

4.2 logic还是wire

        在测试平台中,如果用过程赋值语句驱动接口中的信号,那么信号要在接口中定义为logic,如果是连续赋值驱动,定义成wire。

        定义成logic的一个好处是,如果多个信号驱动logic,那么编译器会报错,这样你就知道写错了,如果是wire,这个错误就隐藏了。

4.3 对测试平台和DUT中事件的调度

        如果没有用时钟块,测试平台对DUT的驱动和采样存在竞争,这是因为测试平台的事件和DUT的事件混合在同一个时间片中。

        SV中将测试平台中的事件和DUT中的事件分离。时间片划分:


SV的主要调度区域:

4.4 设计和测试平台之间的时序

        时钟块(测试平台)在#1step延时之后采样DUT,也就是采样上一个时间片postponed区域的数据。也就是前面讲的采样旧值。

        时钟块(测试平台)在#0延时之后驱动DUT信号。0延迟说明还在同一个time slot,DUT能够捕捉到变化。

更细致的时间片划分:

time slot
activedesign
inactive显示0延迟阻塞赋值;
observedSVA
reactiveSV
postponedSV 采样

 

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

        为了同步接口中的信号,可以在时钟沿采样或者驱动接口信号。可以在接口中定义时钟块来同步接口信号:

interface if(input bit clk);
    logic data;
    logic valid;
    logic addr;
    clocking cb@(posedge clk);
        input valid;
        input data;
        input addr;
    endclocking
    modport TEST(clocking cb);
    modport DUT(input valid ,input data);
endinterface

在测试平台中的信号才需要同步。

5.1 接口信号采样时序

        如果时钟块中的信号采样DUT中的信号,采样的是上一个时间片(time slot)postponed区域的数据。即如果DUT信号在时钟沿发生0-1跳变,那么采样到0。DUT接口想要驱动TEST接口中时钟块里的信号,需要先给DUT接口信号赋值:

module dut(if.DUT if0);
    ....
    #10 if0.valid = 1;
    #10 if0.valid = 2;
    ....
endmodule

 

5.2 接口信号驱动时序

        如果时钟块驱动DUT信号,值会立即传入到设计中。即如果时钟块中的信号在时钟沿发生0-1跳变,则时钟沿之后DUT中为1。时钟块想要驱动DUT,需要在testbench给时钟块中的信号赋值,在tb中驱动时钟块中的信号需要同步驱动,用“<=”符号。时钟块中的信号驱动采样

program tb(if.TEST if1);
    ...
    #10 if1.cb.valid <= 1;
    #10 if1.cb.valid <= 0;
    ...
endprogram

6. 使用虚接口

        之前介绍的接口都是跟module一样来描述硬件的;在SV中有面向对象的概念,在class里面使用虚接口——virtual interface。

        虚接口是一个物理接口的句柄(handler),同这个句柄来访问硬件接口。虚接口是唯一链接动态对象和静态模块、接口的一种机制

6.1 在测试平台中使用接口

interface inf; //定义接口
...
endinterface
program test(inf if0); // 接口传入测试平台
    driver drv;
    initial begin
        drv = new(if0); // 接口传给driver对象
    end
endprogram
class driver;
    virtual vif;  // 在class中为虚接口
    function new(inf i);
        vif=i;
    endfunction
endclass
module top;
    inf inf0();  // 例化接口
    test t1(inf0);
    dut d1(inf0);
endmodule

也可以在tb中跨模块引用XMR(cross module reference)接口

program test(); //没有接口参数
    virtual inf if0=top.inf0;//top是顶层模块
    ...
endprogram
module top;
    inf inf0();  // 例化接口
    test t1(); // tb无接口列表
    dut d1(inf0);
endmodule

 6.2 使用端口传递接口数组

interface inf(input clk);
...
endinterface
parameter NUM=10;
module top;
    inf xi[NUM](clk); // 顶层例化多个接口,接口名后跟个数
    test t1(xi);// 接口作为参数
    dut...
endmodule
program test(inf xi[NUM]); // 接口参数列表
    virtual inf vxi[NUM];
    initial begin
        vxi=xi;
    end
endprogram

也可以用跨模块引用。

7. 接口中的代码

接口中可以定义信号、函数、任务、class对象,也可以有always,initial语句块。

下面给一个在《UVMPrimer》中的例子:

interface tinyalu_bfm;
   import tinyalu_pkg::*;
​
   byte         unsigned        A;
   byte         unsigned        B;
   bit          clk;
   bit          reset_n;
   wire [2:0]   op;
   bit          start;
   wire         done;
   wire [15:0]  result;
   operation_t  op_set;
​
   assign op = op_set;
​
   task reset_alu();
      reset_n = 1'b0;
      @(negedge clk);
      @(negedge clk);
      reset_n = 1'b1;
      start = 1'b0;
   endtask : reset_alu
   
   task send_op(input byte iA, input byte iB, input operation_t iop, shortint result);
      if (iop == rst_op) begin
         @(posedge clk);
         reset_n = 1'b0;
         start = 1'b0;
         @(posedge clk);
         #1;
         reset_n = 1'b1;
      end else begin
         @(negedge clk);
         op_set = iop;
         A = iA;
         B = iB;
         start = 1'b1;
         if (iop == no_op) begin
            @(posedge clk);
            #1;
            start = 1'b0;           
         end else begin
            do
              @(negedge clk);
            while (done == 0);
            start = 1'b0;
         end
      end // else: !if(iop == rst_op)
      
   endtask : send_op
   
   command_monitor command_monitor_h;
​
   function operation_t op2enum();
      case(op)
        3'b000 : return no_op;
        3'b001 : return add_op;
        3'b010 : return and_op;
        3'b011 : return xor_op;
        3'b100 : return mul_op;
        default : $fatal("Illegal operation on op bus");
      endcase // case (op)
   endfunction : op2enum
​
​
   always @(posedge clk) begin : op_monitor
      static bit in_command = 0;
      command_s command;
      if (start) begin : start_high
        if (!in_command) begin : new_command
           command.A  = A;
           command.B  = B;
           command.op = op2enum();
           command_monitor_h.write_to_monitor(command);
           in_command = (command.op != no_op);
        end : new_command
      end : start_high
      else // start low
        in_command = 0;
   end : op_monitor
​
   always @(negedge reset_n) begin : rst_monitor
      command_s command;
      command.op = rst_op;
      command_monitor_h.write_to_monitor(command);
   end : rst_monitor
   
   result_monitor  result_monitor_h;
​
   initial begin : result_monitor_thread
      forever begin
         @(posedge clk) ;
         if (done) 
           result_monitor_h.write_to_monitor(result);
      end
   end : result_monitor_thread
  
   initial begin
      clk = 0;
      forever begin
         #10;
         clk = ~clk;
      end
   end
endinterface : tinyalu_bfm

函数使用的时候通过接口对象调用就行了

virtual tinyalu_bfm inf;
initial begin
	inf.send_op(..);
end

8. 接口使用注意事项

  • 接口不能在package中被`include 。

    下面这种写法是会报错的。
     

    package pkg;
    	`include "apb_if.sv"
        ……
    endpackage

    而要放在package外面

    `include "apb_if.sv"
    package pkg;
        ……
    endpackage
    如果要在UVM中要通过hierarchy访问DUT中的信号,最好将这些信号放在interface中,然后将virtual interface传给UVM
    
    
    // 在接口中定义信号
    interface bfm;
    	bit[7:0 addr;
    endinterface
     
    // 实例化接口
    bfm u_bfm();
            
    // 将虚接口传给UVM
    initial begin
    	uvm_config_db#(vitual bfm)::set("", uvm_test_top, "bfm", bfm);
    end
     
    // 在UVM可直接操作虚接口    
    如果不这样的话,当uvm component(driver, monitor, agent等)文件是通过package来管理的话,就不能在UVM中hierarchy引用DUT中的信号。
    
    
    
    
    
    
    
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/86378.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

23种设计模式攻关

&#x1f44d;一、创建者模式 &#x1f516;1.1、单例模式 单例模式&#xff08;Singleton Pattern&#xff09;&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供全局访问点。 在某些情况下&#xff0c;我们需要确保一个类只能有一个实例&#xff0c;比如数据库连接…

打造引人注目的直播体验:直播美颜SDK的集成与优化

随着移动互联网的迅速发展&#xff0c;视频直播已经成为人们交流、娱乐和信息传递的重要方式。在这个多元化的直播市场中&#xff0c;吸引观众的注意力变得尤为重要。其中&#xff0c;美颜技术在增强直播体验方面发挥着关键作用。直播美颜SDK的集成和优化使得主播能够以最佳状态…

雪花算法生成ID

雪花算法生成ID Snowflake&#xff0c;雪花算法是由Twitter开源的分布式ID生成算法&#xff0c;以划分命名空间的方式将64-bit位分割成多个部分&#xff0c;每个部分代表不同的含义。而Java中64bit的整数是Long类型&#xff0c;所以在Java中 SnowFlake算法生成的ID就是long来存…

ARM(实验二)

uart4.h #ifndef __H__ #define __H__#include "stm32mp1xx_rcc.h" #include "stm32mp1xx_gpio.h" #include "stm32mp1xx_uart.h"//RCC/GPIO/UART4章节初始化 void hal_uart4_init();//发送一个字符函数 void hal_put_char(const char str);//发…

深度学习|CNN卷积神经网络

CNN卷积神经网络 解决的问题人类的视觉原理原理卷积层——提取特征池化层——数据降维全连接层——输出结果 应用图像处理自然语言处理 解决的问题 在CNN没有出现前&#xff0c;图像对人工智能来说非常难处理。 主要原因&#xff1a; 图像要处理的数据量太大了。图像由像素组…

solidity0.8.0的应用案例11:透明代理合约

选择器冲突 智能合约中,函数选择器(selector)是函数签名的哈希的前4个字节。例如mint(address account)的选择器为bytes4(keccak256("mint(address)")),也就是0x6a627842. 由于函数选择器仅有4个字节,范围很小,因此两个不同的函数可能会有相同的选择器,例如…

PMP如何备考?学习方式这里有

预习阶段&#xff1a;强烈建议跟着习课视频学习&#xff08;自己看书真的很难看懂&#xff09;&#xff0c;初步了解PMBOK&#xff0c;有个大致印象&#xff1b; 精讲阶段&#xff1a;这个时候就需要静下心来深入了解各个知识模块&#xff0c;不仅是看PMBOK&#xff0c;还要尽…

从C语言到C++_33(C++11_上)initializer_list+右值引用+完美转发+移动构造/赋值

目录 1. 列表初始化initializer_list 2. 前面提到的一些知识点 2.1 小语法 2.2 STL中的一些变化 3. 右值和右值引用 3.1 右值和右值引用概念 3.2 右值引用类型的左值属性 3.3 左值引用与右值引用比较 3.4 右值引用的使用场景 3.4.1 左值引用的功能和短板 3.4.2 移动…

线程池UncaughtExceptionHandler无效?可能是使用方式不对

背景 在业务处理中&#xff0c;使用了线程池来提交任务执行&#xff0c;但是今天修改了一小段代码&#xff0c;发现任务未正确执行。而且看了相关日志&#xff0c;也并未打印结果。 源码简化版如下&#xff1a; 首先&#xff0c;自定义了一个线程池 public class NamedThrea…

视频批量剪辑矩阵分发系统源码开源分享----基于PHP语言

批量剪辑视频矩阵分发&#xff1a; 短视频seo主要基于抖音短视频平台&#xff0c;为企业实现多账号管理&#xff0c;视频分发&#xff0c;视频批量剪辑&#xff0c;抖音小程序搭建&#xff0c;企业私域转化等&#xff0c;本文主要介绍短视频矩阵系统抖音小程序开发详细及注意事…

selenium +Jmeter 的性能测试

通过Jmeter快速将已有的Selenium 代码以性能测试的方式组织起来&#xff0c;并使用JMeter 丰富的报表展示测试结果 from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By driver …

孟羽童:成为勇敢逆袭的职场女性

相信职场中的小伙伴几乎都听过孟羽童这个名字&#xff0c;她从籍籍无名的应届毕业生到现如今摇身一变职场女强人&#xff0c;相信一定有职场人值得借鉴的地方。那么今天小编就给大家分享一下孟羽童的职场经历带给我的启发。 该图片来自网络&#xff0c;侵删 1、年龄并不是成功的…

java八股文面试[java基础]——final 关键字作用

为什么局部内部类和匿名内部类只能访问final变量&#xff1a; 知识来源 【基础】final_哔哩哔哩_bilibili

【Redis】Redis 的主从同步

【Redis】Redis 的主从同步 很多企业都没有使用 Redis 的集群&#xff0c;但是至少都做了主从。有了主从&#xff0c;当主节点(Master) 挂掉的时候&#xff0c;运维让从节点 (Slave) 过来接管&#xff0c;服务就可以继续&#xff0c;否则主节点需要经过数据恢复和重启的过程&a…

xcode15 change

jump to define 由原先的 control command left click 改为command left click

NLP与大模型主题全国师资培训班落地,飞桨持续赋能AI人才培养

为了推动大模型及人工智能相关专业人员的培养&#xff0c;8月11日-8月13日&#xff0c;由中国计算机学会主办、机械工业出版社、北京航空航天大学、百度飞桨联合承办 “CCF群星计划之文心高校行- NLP与大模型”主题师资培训班&#xff08;以下简称培训班&#xff09;在北京天信…

怎样压缩mp4视频大小?

怎样压缩mp4视频大小&#xff1f;由于视频文件的体积通常比其他类型的文件更大&#xff0c;因此它们需要更多的存储空间来保存。但是&#xff0c;如果我们的设备、应用程序或平台不支持某些视频格式或分辨率&#xff0c;或者我们没有足够的存储空间来容纳这些大型视频文件&…

产品流程图是什么?怎么做?

产品流程图是什么&#xff1f; 产品流程图是一种图形化的表达方式&#xff0c;用于描述产品开发、制造、销售、使用等各个阶段中涉及的流程、步骤和关系。它通过图形符号、箭头、文本等元素&#xff0c;展示了产品的各个环节之间的关联和顺序&#xff0c;通常被用于可视化产…

Vivado2018的工程迁移到Vivado2019上

Vivado2018的工程迁移到Vivado2019上 说明&#xff1a; 迁移很简单直接打开以后直接更新IP核后&#xff0c;即可重新编译工程 1、打开Vivado2019软件&#xff0c;准备打开工程 2、更新IP核 3、重新编译即可

Cesium.Entity图片纹理在不同观察角度有不同亮度

Cesium.Entity图片纹理在不同观察角度有不同亮度 测试代码&#xff1a; viewer.entities.add({rectangle: {coordinates: Cesium.Rectangle.fromDegrees(-92.0, 30.0, -76.0, 40.0),material: "../images/rect.png",} }); 测试图片&#xff1a; rect.png 这个图片…