Title

SystemVerilog -- 6.0 Interface

SystemVerilog Interface

What is an Interface ?

Interface 是一种将信号封装到 block 中的方法。所有相关信号组合到一起形成一个接口块,以便可以将其重新用于其他项目。此外,与 DUT 和其它验证组件的连接也变的更加容易。interface

Example

APB 总线协议信号被放在给定的接口中。请注意,信号在 interfaceendinterface 中声明。

interface 
    logic [31:0]   paddr;
    logic [31:0]   pwdata;
    logic [31:0]   prdata;
    logic          penable;
    logic          pwrite;
    logic          psel;
endinterface

Why are signals declared ? logic

logic是一种新的数据类型,允许您通过赋值语句和过程块来驱动这种类型的信号。请记住,在 verilog 中,您可以驱动 only in 过程块和 only in assign 语句。但这只是一个原因。reg wire

连接到 DUT 的信号应支持 4-state,一边可以捕获 X/Z 值。如果这些信号是bit,那么 X/Z 将显示为 0,并且您将错过 DUT 的 X/Z 值。

How to define port directions ?

接口信号可用于各种验证组件以及被测设备,因此用于定义信号方向。不同的modport定义可以传递给不同的组件,这使我们能够为每个组件定义不同的输入-输出方向。modport

interface myBus (input clk);
    logic [7:0] data;
    logic       enable;

    // From TestBench perspective, 'data' is input and `write` is output
    modport TB (input data, clk, output enable);

    // From DUT perspective, 'data' is output and `write` is input 
    modport DUT (output data, input enable, clk);
endinterface

How to connect an interface with DUT ?

应该实例化 DUT 的 top tb 模块中创建一个接口对象,并将其传递给 DUT。必须确保将正确的模块端口分配给 DUT。

module dut (myBus busIf);
    always @(posedge busIf.clk)begin
        if (busIf.enable)
            busIf.data <= busIf.data + 1;
        else
            busIf.data <= 0;
    end
endmodule

// Fillename : tb_top.sv
module tb_top;
    bit clk;
    
    // Create a clock
    always #10 clk = ~clk;

    // Create an interface object
    myBus busIf (clk);

    // Instantiate the DUT; pass modport DUT of busIf
    dut dut0 (busIf.DUT);

    // TestBench code : let's wiggle enable
    initial begin
        busIf.enable <= 0;
        #10 bufIf.enable <= 1;
        #40 bufIf.enable <= 0;
        #20 bufIf.enable <= 1;
        #100 $finish;
    end
endmodule

What are the advantages ?

接口可以包含任务、函数、参数、变量、功能覆盖率和断言。这使我们能够通过该区块内的接口监控和记录交易。无论有多少端口,连接到设计也变得更加容易,因为这些信息封装在接口中。

// Before interface
dut dut0 (
          .data(data),
          .enable(enable) // all other signals
         );
// With interface - higher level of abstraction possible
dut dut0 (busIf.DUT);

How to parameterize an interface ?

与模块相同的方式。

interface myBus #(parameter D_WIDTH=31) (input clk);
    logic [D_WIDTH-1:0] data;
    logic               enable;
endinterface

What are clocking blocks ?

时钟块内指定的信号将相对于该时钟进行采样/驱动。接口中可以有多个时钟块。请注意,这适用于与测试平台相关的信号。您希望控制 TB 何时从 DUT 驱动和采样信号。解决部分竞争条件,但不是全部。您还可以参数化偏斜值。

interface my_int (input bit clk);
    // Rest of interface code

    clocking cb_clk @(posedge clk);
      defdault input #3ns output #2ns;
      input  enable;
      output data;
    endclocking
endinterface

在上面的例子中,我们已经指定,默认情况下,输入应该在 clk 的位置之前采样 3ns,输出应该在 clk 的位置之后驱动 2ns。

How to use a clocking block ?

// To wait for posedge of clock
@busIf.cb_clk;

// To use clocking block signals
busIf.cb_clk.enable = 1;

如您所见,在enable 被 assign = 1 之前,您不必等待 clk 的上升沿。这样,您可以放心,再下一个上升沿 clk 之后,enable 信号将在下一个posedge clk之后2ns被驱动。

posted on 2024-04-15 21:35  松—松  阅读(50)  评论(0编辑  收藏  举报

导航