一、接口interface介绍

1.1.interface产生背景

传统的Verilog连接验证平台Testbench与DUT的方式名字映射、位置映射
在这里插入图片描述
下面给出实例:
在这里插入图片描述
SystemVerilog则对Verilog的连接方式进行了改进补充,引入了接口interface。

1.2.接口的使用方式

  • 可以直接通过接口的例化名字来实现连接;
  • 可以通过接口中定义的信号来实现连接;

在这里插入图片描述

  SV中接口为块之间的通信建模,接口可以看成是一捆智能的连线。接口包含了连接,同步,甚至是两个块或者更多块之间的通信功能。它们连接了设计和测试平台。具有以下特点:

  • interface中包含了 一组信号
  • interface可以是 一个独立的文件,将多个模块通用的信号集中放在一个文件中;
  • interface中集合了多个Verilog类型信号,是一个独立的端口类型;
  • interface中可以包含多个modport 定义interface的不同视图view(DUT、Test program)
  • interface中可以使用clocking模块 显式指明同步时钟域
  • interface中的clocking只用于验证平台,其中可包含多个clocking模块,clocking中的信号方向与Testbench相关

二、示例代码

以下为一个简易的仲裁器RTL(DUT)代码arb.v:

module arb(                  //简单的仲裁器
           input    reset_n,
           input    clk,
           input    request,
           output reg  grant);
     
  always @(posedge clk or negedge reset_n) begin
     if(reset_n == 1'b0)begin
        grant <= 1'b0;
     end
     else if(request == 1'b1)begin
        grant <= 1'b1;
     end
     else if(request == 1'b0)begin
        grant <= 1'b0;
     end
  end

endmodule

接口interface文件arb_if.sv:

interface arb_if(input bit clk);   //通常在接口的端口列表中声明时钟信号
       logic      grant;
       logic      request;
       logic      reset_n;

    clocking cb@(posedge clk);      //用于同步时钟域,相当于寄存器,将信号寄存一拍
       input      grant;            //clocking模块主要服务于TB
       output     request;
    endclocking
 
    modport TB(                    //定义TB视图view
        clocking   cb,
        output     reset_n);

    modport dut(                    //定义dut视图view
        input      request,
        input      reset_n,
        output     grant);

endinterface

激励文件test.sv: 通常使用program块编写,可以隐式执行$finish;系统函数结束代码块

program test(arb_if.TB arbif);     //例化接口中的TB视图
   
   initial begin
      //Asynch drive reset_n
      arbif.cb.request <= 1'b0;      //通过时钟clk上沿将request发出给DUT
      arbif.reset_n <= 1'b1;         //TB中的reset_n与request是异步关系,不需要cb
      #15  arbif.reset_n <= 1'b0;    //复位,稳定电路
      #35  arbif.reset_n <= 1'b1;    //撤离复位
      #5;
      //Synch drive request
      //repeat(5)begin
          arbif.cb.request <= 1'b1;   //TB通过clk上沿将cb.request发送至DUT,DUT会输出一个dut.grant,并传递回给TB(cb.grant)
          wait(arbif.cb.grant == 1'b1;);  //TB对接收自DUT(dut.grant)的cb.grant进行判断,完成一次信息交互
          arbif.cb.request <= 1'b0;
          @arbif.cb;    //@(posedge clk);
          @arbif.cb;
          @arbif.cb;
      //end
   end

endprogram            //program模块不需要$finish函数来结束激励

顶层文件arb_tb.sv:包裹接口文件、激励文件和DUT文件

module ARB_TB();
    bit      clk;        
    arb_if   arbif(.*);    //隐式例化接口(clk信号名一样),等价arb_if arbif(.clk(clk));
    test     u_test(.*);   //隐私例化激励文件
    arb      u_arb(        //通过接口连接TB与DUT
                  .reset_n(arbif.reset_n),
                  .clk    (clk),
                  .request(arbif.request),
                  .grant  (arbif.grant) 
               );
     initial begin
        clk = 0;
        forever #10 clk = ~clk;
     end

endmodule

对于波形图, 要注意时钟沿数数据变化边沿出现重合的情况,此时,由于数据延迟,时钟沿通常采集的是数据变化边沿之前的状态数据。如下图DUT中所示:
在这里插入图片描述
同时要注意clocking对于信号的同步时钟域作用
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐