在verilog中每当遇到复杂的模块时,我们都不得不书写一长串端口声明,

稍有不慎就会写错,并且难以检查。但在systemverilog中,接口interface

则是避免了这个问题。

下面的代码是对一个一位加法器的验证,使用了接口。

`timescale 1ns / 1psinterface if_port( input bit clk );     //   声明接口  logic a , b , cin , sum ,cout ;      //   声明所有的连接线    clocking cp@(posedge clk);           //    声明在同一个时钟变化下,连接线的方向。      output a , b, cin ;  endclocking    clocking cn@(posedge clk);    input a , b , cin , sum ,cout;  endclocking    modport simulus(clocking cp);      //   声明端口的输入与输出  modport adder( input a , b , cin , output sum ,cout );  modport monitor(clocking cn);endinterfacemodule simulus(if_port.simulus port);   //    使用接口的激励模块    always@(port.cp) begin    port.cp.a <= $radnom()%2 ;    port.cp.b <= $random()%2 ;    port.cp.cin <= $random()%2 ;  endendmodule:simulusmodule adder(if_port.adder port);       //     一位加法器  assign { port.cout , port.sum } = port.a + port.b + port.cin ;endmodule:addermodule monitor(if_port.monitor mon);    //       监测模块,在时钟的下降沿打印结果  always@( mon.cn )begin    $display(" %d %d %d %d  %d ",mon.cn.a , mon.cn.b , mon.cn.cin , mon.cn.cout , mon.cn.sum );  endendmodulemodule top;  timeunit 1ns ;  timeprecision 1ps ;      //    模块内部的时钟情况  bit clk ;    if_port port(clk);           //    实例化所有模块,并且连接接口  simulus sim(port.simulus);  adder add(port.adder);  monitor mon(port.monitor);    initial begin    clk <= 0 ;                  //   时钟的生成    while(1) #10 clk = ~clk ;  end  endmodule

相信由这个例子,大家可以看出接口的使用方法。尽管在这个例子中接口的使用比较繁琐,

但在一个较大型的模块中时,使用接口绝对是最佳的方式。

在接口中还有一种叫做虚接口,虚接口是接口的一个句柄,可以同过虚接口来操作接口成员的值。

下面就看看IEEE sv标准中的例子。

interface  SBus;    // A Simple bus interface        logic  req, grant;        logic [7:0] addr, data;endinterfaceclass    SBusTransctor;   // SBus transactor class        virtual SBus bus;    // virtual interface of type Sbus            function new( virtual SBus s );                        bus = s;    // initialize the virtual interface        endfunction       task request();  // request the bus                       bus.req <= 1'b1;       endtask      task wait_for_bus(); // wait for the bus to be granted                       @(posedge bus.grant);       endtaskendclassmodule  devA( Sbus s ) ... endmodule    // devices that use SBusmodule  devB( Sbus s ) ... endmodulemodule  top;           SBus s[1:4] ();  // instantiate 4 interfaces    devA a1( s[1] );  // instantiate 4 devices        devB b1( s[2] );        devA a2( s[3] );        devB b2( s[4] );            initial begin                    SbusTransactor t[1:4];  // create 4 bus-transactors and bind                    t[1] = new( s[1] );                    t[2] = new( s[2] );                    t[3] = new( s[3] );                    t[4] = new( s[4] );                    // test t[1:4]        endendmodule

可以看出接口与模块还是以实例化的方式相互连接,但在激励上使用了类与虚接口来进行实现。

这样在书写激励时可以动态的修改激励,并且在一定程度上增进了代码的复用程度。