systemverilog的接口interface 负载实例

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

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

则是避免了这个问题。

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

`timescale 1ns / 1ps
interface 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);
endinterface

module simulus(if_port.simulus port);   //    使用接口的激励模块
  
  always@(port.cp) begin
    port.cp.a <= $radnom()%2 ;
    port.cp.b <= $random()%2 ;
    port.cp.cin <= $random()%2 ;
  end
endmodule:simulus

module adder(if_port.adder port);       //     一位加法器
  assign { port.cout , port.sum } = port.a + port.b + port.cin ;
endmodule:adder

module 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 );
  end
endmodule

module 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;
endinterface

class    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);    
   endtask
endclass

module  devA( Sbus s ) ... 
endmodule    // devices that use SBus
module  devB( Sbus s ) ... 
endmodule

module  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

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

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

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值