Verilog 模塊與端口

2022-05-19 09:28 更新

關(guān)鍵詞:模塊,端口,雙向端口,PAD

結(jié)構(gòu)建模方式有 3 類描述語句: ?Gate?(門級(jí))例化語句,?UDP ?(用戶定義原語)例化語句和 ?module ?(模塊) 例化語句。本次主要講述使用最多的模塊級(jí)例化語句。

模塊

模塊是 Verilog 中基本單元的定義形式,是與外界交互的接口。

模塊格式定義如下:

module module_name 
#(parameter_list)
(port_list) ;
              Declarations_and_Statements ;
endmodule

模塊定義必須以關(guān)鍵字 ?module ?開始,以關(guān)鍵字 ?endmodule ?結(jié)束。

模塊名,端口信號(hào),端口聲明和可選的參數(shù)聲明等,出現(xiàn)在設(shè)計(jì)使用的 Verilog 語句之前。

模塊內(nèi)部有可選的 5 部分組成,分別是變量聲明,數(shù)據(jù)流語句,行為級(jí)語句,低層模塊例化及任務(wù)和函數(shù),如下圖表示。這 5 部分出現(xiàn)順序、出現(xiàn)位置都是任意的。但是,各種變量都應(yīng)在使用之前聲明。變量具體聲明的位置不要求,但必須保證在使用之前的位置。


前面大多數(shù)仿真代碼都會(huì)用到 ?module? 聲明,大家可以自行參考,這里不再做具體舉例。下面介紹端口時(shí),再做詳細(xì)的仿真。

端口

端口是模塊與外界交互的接口。對(duì)于外部環(huán)境來說,模塊內(nèi)部是不可見的,對(duì)模塊的調(diào)用只能通過端口連接進(jìn)行。

端口列表

模塊的定義中包含一個(gè)可選的端口列表,一般將不帶類型、不帶位寬的信號(hào)變量羅列在模塊聲明里。下面是一個(gè) PAD 模型的端口列表:

module pad(
    DIN, OEN, PULL,
    DOUT, PAD);

一個(gè)模塊如果和外部環(huán)境沒有交互,則可以不用聲明端口列表。例如之前我們仿真時(shí) test.sv 文件中的 test 模塊都沒有聲明具體端口。

module test ;  //直接分號(hào)結(jié)束
    ......     //數(shù)據(jù)流或行為級(jí)描述
endmodule

端口聲明

  1. 端口信號(hào)在端口列表中羅列出來以后,就可以在模塊實(shí)體中進(jìn)行聲明了。
  2. 根據(jù)端口的方向,端口類型有 3 種: 輸入(?input?),輸出(?output?)和雙向端口(?inout?)。

    ?input?、?inout? 類型不能聲明為 reg 數(shù)據(jù)類型,因?yàn)?nbsp;reg 類型是用于保存數(shù)值的,而輸入端口只能反映與其相連的外部信號(hào)的變化,不能保存這些信號(hào)的值。

    ?output? 可以聲明為 wire 或 reg 數(shù)據(jù)類型。

    上述例子中 pad 模塊的端口聲明,在 ?module? 實(shí)體中就可以表示如下:

    //端口類型聲明
    input        DIN, OEN ;
    input [1:0]  PULL ;  //(00,01-dispull, 11-pullup, 10-pulldown)
    inout        PAD ;   //pad value
    output       DOUT ;  //pad load when pad configured as input
    
    //端口數(shù)據(jù)類型聲明
    wire         DIN, OEN ;
    wire  [1:0]  PULL ;
    wire         PAD ;
    reg          DOUT ;
  3. 在 Verilog 中,端口隱式的聲明為 wire 型變量,即當(dāng)端口具有 wire 屬性時(shí),不用再次聲明端口類型為 wire 型。但是,當(dāng)端口有 reg 屬性時(shí),則 reg 聲明不可省略。
  4. 上述例子中的端口聲明,則可以簡(jiǎn)化為:

    //端口類型聲明
    input        DIN, OEN ;
    input [1:0]  PULL ;    
    inout        PAD ;    
    output       DOUT ;    
    reg          DOUT ;
  5. 當(dāng)然,信號(hào) DOUT 的聲明完全可以合并成一句:
  6. output reg      DOUT ;
  7. 還有一種更簡(jiǎn)潔且常用的方法來聲明端口,即在 ?module? 聲明時(shí)就陳列出端口及其類型。reg 型端口要么在 ?module? 聲明時(shí)聲明,要么在 ?module? 實(shí)體中聲明,例如以下 2 種寫法是等效的。
  8. module pad(
        input        DIN, OEN ,
        input [1:0]  PULL ,
        inout        PAD ,
        output reg   DOUT
        );
     
    module pad(
        input        DIN, OEN ,
        input [1:0]  PULL ,
        inout        PAD ,
        output       DOUT
        );
     
        reg        DOUT ;

inout 端口仿真

對(duì)包含有 ?inout? 端口類型的 pad 模型進(jìn)行仿真。pad 模型完整代碼如下:

module pad(
    //DIN, pad driver when pad configured as output
    //OEN, pad direction(1-input, o-output)
    input        DIN, OEN ,
    //pull function (00,01-dispull, 10-pullup, 11-pulldown)
    input [1:0]  PULL ,
    inout        PAD ,
    //pad load when pad configured as input
    output reg   DOUT
    );
 
    //input:(not effect pad external input logic), output: DIN->PAD
    assign       PAD = OEN? 'bz : DIN ;
 
    //input:(PAD->DOUT)
    always @(*) begin
        if (OEN == 1) begin //input
            DOUT   = PAD ;
        end
        else begin
            DOUT   = 'bz ;
        end
    end
 
    //use tristate gate in Verilog to realize pull up/down function
    bufif1  puller(PAD, PULL[0], PULL[1]);
 
endmodule

testbench代碼如下:

`timescale 1ns/1ns
 
module test ;
    reg          DIN, OEN ;
    reg [1:0]    PULL ;
    wire         PAD ;
    wire         DOUT ;
 
    reg          PAD_REG ;
    assign       PAD = OEN ? PAD_REG : 1'bz ; //
 
    initial begin
        PAD_REG   = 1'bz ;        //pad with no dirve at first
        OEN       = 1'b1 ;        //input simulation
        #0 ;      PULL      = 2'b10 ;   //pull down
        #20 ;     PULL      = 2'b11 ;   //pull up
        #20 ;     PULL      = 2'b00 ;   //dispull
        #20 ;     PAD_REG   = 1'b0 ;
        #20 ;     PAD_REG   = 1'b1 ;
 
        #30 ;     OEN       = 1'b0 ;    //output simulation
                  DIN       = 1'bz ;
        #15 ;     DIN       = 1'b0 ;
        #15 ;     DIN       = 1'b1 ;
    end
 
    pad     u_pad(
        .DIN     (DIN) ,
        .OEN     (OEN) ,
        .PULL    (PULL) ,
        .PAD     (PAD) ,
        .DOUT    (DOUT)
    );
 
    initial begin
        forever begin
            #100;
            if ($time >= 1000)  $finish ;
        end
    end
 
endmodule // test

仿真結(jié)果如下:


仿真結(jié)果分析如下:

當(dāng) PAD 方向?yàn)?nbsp;input 且沒有驅(qū)動(dòng)時(shí),pull 功能能通過 PAD 的值而體現(xiàn)。

前 60ns 內(nèi),PAD 的驅(qū)動(dòng)端 ?PAD_REG? 為 z, 可認(rèn)為沒有驅(qū)動(dòng),所以開始時(shí) PULL=2, 下拉,PAD值為 0; 20ns 時(shí),PULL=3,上拉,PAD 值為 1;

40ns 時(shí),PULL=0,沒有 pull 功能,PAD 值輸入為 z。

60ns~100ns 后,PAD 的驅(qū)動(dòng)端 ?PAD_REG? 開始正常驅(qū)動(dòng)。此時(shí)相當(dāng)于 PAD 直接與 ?PAD_REG? 相連,所以 PAD 值與其驅(qū)動(dòng)值保持一致。

以上分析,PAD 方向都是 input,所有輸出端 DOUT 與 PAD 值保持一致。

當(dāng) PAD 方向?yàn)?nbsp;output 時(shí),即 120ns 時(shí) OEN= 0,PAD 值與輸入端 DIN 值保持一致。

點(diǎn)擊這里下載源碼


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)