如何在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內部信號發生更改,無需修改模塊間例化的部分,降低工作量。
 
以上。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM