如何在SV代码中使用interface语法

前言
测试下可综合的interface接口,为了方便未来接口定义的懒惰操作以及减少出错的概率。
综合工具:Vivado2018.3
流程
首先看接口是什么?
顾名思义,用于模块间信号交互的路。是一系列信号组。
想象一辆公交车(bus),分立的信号就是乘客,将乘客封装进bus,就是接口。
对于最简单的使用interface的demo需要三个模块:top,输入,输出。用接口简化输入输出的信号组。
(1)定义interface:interface可以有外界输入信号。通过modport定义不同的接口方向。
interface f_bus1(input logic i_clk,i_rst_n);
    logic l_ready;
    logic l_valid;
    logic [7:0] l_cnt;
    modport master(input i_clk,i_rst_n,
                   output l_ready,l_valid,l_cnt);
    modport slave (input i_clk,i_rst_n,
                   input  l_ready,l_valid,l_cnt);
endinterface //f_bus1
(2)top层:
使用了extern语法,对top层的信号组进行了外界定义,模块定义的时候信号组无需重复申明。
定义interface及用modport指定不同方向,子模块的方向根据modport指定。
interface的实例,如果没有外界信号送入,则为空,这里有时钟和复位送入。
genafic产生interface的输出信号送入到test模块中。
注意:bus的连接通过interface的实例加modport的名称指定。
extern module demo_sv (
    input     i_clk       ,
    input     i_rst_n     ,
    input     i_a         ,
    output    o_b                    
);

///子层模块定义
interface f_bus1(input logic i_clk,i_rst_n);
    logic l_ready;
    logic l_valid;
    logic [7:0] l_cnt;
    modport master(input i_clk,i_rst_n,
                   output l_ready,l_valid,l_cnt);
    modport slave (input i_clk,i_rst_n,
                   input  l_ready,l_valid,l_cnt);
endinterface //f_bus1

module demo_sv (.*);
f_bus1 inst_f_bus1 (
    .i_clk      (i_clk),
    .i_rst_n    (i_rst_n)
);
genafic  inst_genafic (
    .f_bus1            (inst_f_bus1.master),   
    .i_a               (i_a)
);
test  inst_test (
    .f_bus1            (inst_f_bus1.slave),   
    .o_b               (o_b)
);

endmodule

(3)genafic模块:
通过interface定义接口,后面跟上名字(任意)。
模块内部要使用接口中的信号:通过接口名字加interface内部信号的方式进行使用。
module genafic (
     interface f_bus1,
     input     i_a           
);
logic [7:0] l_cnt = '0;
always_ff @(posedge f_bus1.i_clk)
begin
    if (f_bus1.i_rst_n)
        l_cnt <= '0;
    else if (i_a)
        l_cnt <= l_cnt + 'd1;
end
assign f_bus1.l_ready = l_cnt[0];
assign f_bus1.l_valid = l_cnt[1];
assign f_bus1.l_cnt   = l_cnt;

endmodule:genafic
(4)test模块:
同样定义interface,使用一样。
module test (
    interface f_bus1,
    output o_b

);
logic l_b = '0;
always_ff @(posedge f_bus1.i_clk)
begin
    if (f_bus1.i_rst_n)
        l_b <= '0;
    else if (f_bus1.l_ready && f_bus1.l_valid)
    begin
        if (f_bus1.l_cnt == 'd10)
            l_b <= 1'b1;
        else 
            l_b <= 1'b0;
    end    
end

assign o_b = l_b;

endmodule:test
(5)导入vivado2018.3生成原理图看看。

好处就是:如果interface内部信号发生更改,无需修改模块间例化的部分,降低工作量。
 
以上。
posted @ 2020-08-12 13:45  小翁同学  阅读(2501)  评论(0编辑  收藏  举报