接口
- 通过端口实现模块之间的连接
实际上的操作是,首先定义两个需要连接的模块A(变量为a,b)和模块B(变量为c,d)。再定义一个interface C,其变量分别为e,f。在顶层中将模块C发别与模块A和模块B连接,也就是e,f分别和a,b,c,d连接,最终实现a和c,b和d连接
- 实现模块和端口之间的连接
首先定义需要连接的模块A及接口B,再定义一个顶层top模块,在顶层top模块中首先通过接口例化一个新的接口b,在将定义的模块A和接口b的连接
- 实现类和模块之间的通信(虚接口)
实际上的操作是首先定义需要的接口A,类B和模块C。但是在定义类的同时,在其中通过接口定义了新的接口a并且在类中完成对a接口的初始化,并且这里存在一共接口的替换。随后定义顶层模块中例化接口a,在将接口a与模块C相连接,最后还要通过initial创建事务对象。
//接口连接,模块与模块之间的连接
interface arb_if(input bit clk);
logic [1:0] grant,request;
logic rst;
endinterface
module arb(arb_if arbif);
//...
always@(posedge arbif.clk or negedge arbif.rst)
begin
if(arbif.rst)
arbif.grant <= 0;
else
arb_if.grant = this.grant;
end
endmodule
module test(arb_if arbif);
//...
initial begin
//...
end
endmodule
module top;
bit clk;
always #5 clk=!clk;
arb_if arbif(clk);
arb a1(arbif);
test t1(arbif);
endmodule
//接口连接,接口与端口之间的连接
module arb_port(input logic [1:0] request,output logic [1:0]grant
,input logic clk,input logic rstn);
//...
endmodule
module top;
bit clk;
always #5 clk = !clk;
arb_if arbif(clk);
arb_port(.grant(arb_if.grant),.request(arb_if.request),.clk(arb_if.clk),.rstn(arb_if.rstn));
endmodule
//接口的连接,实现类和模块之间的连接,类似前者,但是实际上需要在类中做一些新的内容
interface SBus;
endinterface
class a;
virtual SBus bus;
function new(virtual SBus s)
bus = s;//传入一个interface给到这里的上面定义的bus中
endfunction
//...
endclass
对比:对于第一点,在没有接口的情况下,模块与模块之间的连接实际上通过模块间独立的信号连接;当存在接口时,是通过一个公共接口分别不同模块间的端口连接,在外部环境中没有各个独立的信号,而是只存在一个接口;对于第三点实际上是实现类和模块之间的连接,在顶层模块中同样是实现模块和接口的连接,但是在该接口需要在类中初始化,最终实现模块和类的连接
- 端口模式和时钟控制块
modport:modport只能做方向的声明,而不能声明变量,也就是modport中所有的变量必须在interface中先声明,才能在modport中规定方向
clocking:不仅可以定义在interface,也可以定义在module,program中;另外clocking列举的的信号不是自己定义的,而是由interface定义的或者其他声明clocking的模块定义的。
一些其他的点:(1)利用clocking采样/利用clocking做数据驱动/接口的同步:repeat (3) @bus.cb表示等待三个有效时钟沿(2)时钟块中使用modport时,同步信号需要加上接口名和时钟块名前缀。调用interface的时候什么时候需要加上clocking?
竞争问题:比如clk1驱动clk2(信号是clk1同步信号)和d1(信号是d+1的信号),那么在clk1上升沿采集d1为1,那么等到clk2上升沿再次采集d1时才会变成2.这是由于实际上clk2和d1信号均是由clk1驱动的,因此均和clk1存在一个延迟,也就是在clk1上升沿时采样,clk2和d1信号均没有发送驱动,而当在clk2上升沿采样时,clk2和d1相较于clk1的延迟已过去,所以此时采样实际时d1+1,也就是为2.(可以采用clocking块去解决采样过程中的竞争问题)
如何消除竞争问题,涉及SV中的采样问题,一共有三种,分别是property中sequence的采样特性,interface采样特性,program采样特性。这些采样过程都和SV中的调度机制密切相关。
- 接口和模块的对比
模块的端口如果声明为input,output或者inout时,那么列化时可以不连接;模块端口如果声明为interface,那么例化时必须连接到一个接口实例或者另外一个接口端口
接口端口指的是接口中声明端口,比如外部接入的时钟信号或者复位信号(接口端口中一般只定义一些时钟信号或复位信号等公共信号,interface bus(input logic clock);
接口无法例化模块,但是接口可以例化接口;接口内部可以声明所以变量或者线网(注意是内部);接口和模块的连接(将接口与端口逐一连接,在顶层top中,采用模块名 实例名(接口名)的方式)。
软件中不能例化接口,但是可以利用接口的指针找到接口的实例,进而找到实例中的信号。
- 结构体和interface之间的差别