Verilog 開關(guān)級建模

2022-05-20 14:32 更新

關(guān)鍵詞:MOS, CMOS, 雙向開關(guān), PAD

開關(guān)級建模是比門級建模更為低級抽象層次上的設(shè)計。在極少數(shù)情況下,設(shè)計者可能會選擇使用晶體管作為設(shè)計的底層模塊。隨著電路設(shè)計復(fù)雜度及相關(guān)先進(jìn)工具的出現(xiàn),以開關(guān)為基礎(chǔ)的數(shù)字設(shè)計慢慢步入黃昏。目前,Verilog 僅僅提供了用邏輯值 0、1、x、z 作為相關(guān)驅(qū)動強度的數(shù)字設(shè)計能力,因此,Verilog 中晶體管也僅被當(dāng)做導(dǎo)通或截止的開關(guān)。

MOS 開關(guān)

MOS 開關(guān)有 2 種,用如下關(guān)鍵字聲明:

nmos(N 類型 MOS 管)   pmos(P 類型 MOS 管)  
rnmos (帶有高阻抗的 NMOS 管) rpmos(帶有高阻抗的 PMOS 管)

MOS 管用來為開關(guān)邏輯建模,數(shù)據(jù)從輸入流入輸出,可通過適當(dāng)設(shè)置來開、關(guān)數(shù)據(jù)流。

帶有阻抗的 MOS 管,源極到漏極的阻抗較高,且在傳遞信號時會減小信號的強度。

MOS 管開關(guān)結(jié)構(gòu)圖如下所示。


例化時,MOS 管第一個端口為輸出端,第二個端口為數(shù)據(jù)輸入端,第三個端口為控制輸入端。

   //tri
   pmos pmos1           (OUTX, IN1, CTRL1) ;
   //no instantiation name
   nmos                 (OUTX1, IN1, CTRL2) ;

MOS 管真值表如下所示,與三態(tài)門非常相似。

nmos 控制端         pmos 控制端      
  0 1 x z     0 1 x z
0 z 0 0/z 0/z   0 0 z 0/z 0/z
1 z 1 1/z 1/z   1 1 z 1/z 1/z
x z x x x   x x z x x
z z x x x   z x z x x

CMOS 開關(guān)

CMOS 開關(guān)用關(guān)鍵字 cmos 和 rcmos (帶有高阻抗)聲明。

CMOS 有一個數(shù)據(jù)輸出,一個數(shù)據(jù)輸入和 2 個控制輸入,結(jié)構(gòu)示意圖如下:


信號 PControl 與 Ncontrol 通常是互補的。當(dāng)信號 Ncontrol 為 1 且 PControl 為 0 時,開關(guān)導(dǎo)通。 當(dāng)信號 Ncontrol 為 0 且 PControl 為 1 時,開關(guān)輸出為高阻。可以將 CMOS 開關(guān)看做是 NMOS 與 PMOS 開關(guān)的組合體。

例化時,CMOS 管第一個端口為輸出端,第二個端口為數(shù)據(jù)輸入端,第三個端口為 Ncontrol 控制輸入端,第四個端口為 Pcontrol 控制輸入端。

CMOS 開關(guān)例化格式如下。

   //coms
   cmos c1              (OUTY, IN1, NCTRL, PCTRL) ;
   //no instantiation name
   cmos                 (OUTY1, IN1, NCTRL, PCTRL) ;

既然 CMOS 可以看做是 NMOS 與 PMOS 開關(guān)的組合體,所以還可以用這兩種 MOS 開關(guān)去搭建 CMOS 開關(guān),如下:

   //the same 2-way instantiation of cmos
   nmos n2              (OUTY, IN1, NCTRL) ;
   pmos p2              (OUTY, IN1, PCTRL) ;

CMOS 真值表與 MOS 開關(guān)類似,注意 Ncontrol 與 Pcontrol 信號的互補性。

雙向開關(guān)

NMOS、PMOS、CMOS 開關(guān)門都是從漏極向源極導(dǎo)通,方向是單向的。Verilog 中還提供了雙向?qū)ǖ拈_關(guān)器件,數(shù)據(jù)可以雙向流動,兩邊的信號都可以是驅(qū)動信號。

雙向開關(guān)及其阻抗模式的關(guān)鍵字聲明如下:

tran  tranif1  tranif0   rtran  rtranif1  rtranif0

雙向開關(guān)結(jié)構(gòu)圖如下:


tran 開關(guān)為兩個信號直接的緩存,inout1 或 inout2 均可以是驅(qū)動信號。

tranif1 僅當(dāng) control 信號為 1 時,開關(guān)兩邊的信號導(dǎo)通。當(dāng) control 為 0 時,兩個信號斷開,有驅(qū)動源的信號會和驅(qū)動源保持一致的信號值,沒有驅(qū)動源的信號則呈現(xiàn)為高阻狀態(tài)。

tranif0 同理。

因此,雙向開關(guān)常用來進(jìn)行總線或信號之間的隔離。

例化時,雙向開關(guān)前

兩個端口為數(shù)據(jù)端,第三個端口為 control 控制輸入端。

雙向開關(guān)例化舉例如下:

   tranif0 tr0              (inout1, inout2, control) ;
   //no instantiation name
   tranif1                  (inout1, inout2, control) ;

電源和地

晶體管級電路需要源極(Vdd, 邏輯 1)與地極(Vss, 邏輯 0),分別用關(guān)鍵字 supply1 和 supply0 來定義。 用法如下:

   supply1              VDD ;
   supply0              GND ;
   wire                 siga = VDD ; //siga is connected to logic 1
   wire                 sigb = GND ; //sign is connected to logic 0

PAD 模型仿真

《Verilog 教程》《Verilog 模塊與端口》一節(jié)中,涉及過 PAD 模型的編寫與仿真。下面,利用三態(tài)門對 PAD 模型進(jìn)行重塑,上下拉功能固定,并利用雙向開關(guān)對 PAD 連接性進(jìn)行測試。

利用三態(tài)門編寫的帶有 pullup 功能的 pad 模型如下,pulldown 功能的 pad 模型切換下注釋即可。

module PADUP(
   //DIN, pad driver when pad configured as output
   //OEN, pad direction(1-input, o-output)
   input        DIN, OEN ,
   inout        PAD ,
   //pad load when pad configured as input
   output       DOUT
  );
   //input:(not effect pad external input logic), output: DIN->PAD
   bufif0 (PAD, DIN, OEN) ;     //0-output
   bufif1 (DOUT, PAD, OEN) ;    //1-input
   pullup (PAD);
   //pulldown (PAD);   //pulldown
endmodule

利用雙向開關(guān)控制 PAD IO 連接性的 testbench 編寫如下。

測試流程為 PAD0/1 互連,然后 PAD0 作為輸出,PAD1 作為輸入,驅(qū)動 PAD0, 讀取 PAD1 的值。然后兩者方向各自取反,驅(qū)動 PAD1 讀取 PAD0 的值。

PAD2/3 測試過程完全一樣。

`timescale 1ns/1ns
module test ;
   parameter    PULL_UP         = 1 ;
   parameter    PULL_DOWN       = 0 ;
   parameter    IO0_OUT         = 0 ;
   parameter    IO1_OUT         = 1 ;
   parameter    IO2_OUT         = 2 ;
   parameter    IO3_OUT         = 3 ;
   parameter    IO0_IN          = 0 ;
   parameter    IO1_IN          = 1 ;
   parameter    IO2_IN          = 2 ;
   parameter    IO3_IN          = 3 ;
   reg [3:0]    DIN, OEN ;
   wire [3:0]   DOUT ;
   wire [3:0]   PAD ;
   //test connection control, using tranif1
   reg [1:0]    con_ena ;
   tranif1 (PAD[0], PAD[1], con_ena[0]);
   tranif1 (PAD[2], PAD[3], con_ena[1]);
   reg err = 0;
   task test_io_conn;
      //test pull
      input             pull_type ;
      //test conn
      input [1:0]       xout ;     //output postion
      input [1:0]       yin ;     //output postion
      DIN[xout]         = ~pull_type ;
      # 20 ;
      if (DOUT[yin] != ~pull_type) begin
         $display("write value and get value is: %h, %h", ~pull_type, DOUT[yin]);
         err        |= 1 ;
      end
      DIN[xout]         = pull_type;
      # 20 ;
      if (DOUT[yin] != pull_type) begin
         $display("write value and get value is: %h, %h", pull_type, DOUT[yin]);
         err        |= 1 ;
      end
   endtask
   initial begin
      con_ena   = 2'b01 ;
      OEN       = 4'b1111 ;
      #13 ;
      //test between io0/io1
      OEN[0]    = 0 ;
      OEN[1]    = 1 ; //gpio0 -> gpio1
      test_io_conn(PULL_UP, IO0_OUT, IO1_IN);
      OEN[1]    = 0 ;
      OEN[0]    = 1 ; //gpio0 -> gpio1
      test_io_conn(PULL_UP, IO1_OUT, IO0_IN);
      OEN       = 4'b1111 ;
      con_ena   = 2'b10 ;
      OEN[2]    = 1'b0 ;
      OEN[3]    = 1'b1 ;
      test_io_conn(PULL_DOWN, IO2_OUT, IO3_IN);
      OEN[3]    = 1'b0 ;
      OEN[2]    = 1'b1 ;
      test_io_conn(PULL_DOWN, IO3_OUT, IO2_IN);
   end
   PADUP        u_pad_up0( DIN[0], OEN[0], PAD[0], DOUT[0]) ;
   PADUP        u_pad_up1( DIN[1], OEN[1], PAD[1], DOUT[1]) ;
   PADDOWN      u_pad_down3( DIN[2], OEN[2], PAD[2], DOUT[2]) ;
   PADDOWN      u_pad_down4( DIN[3], OEN[3], PAD[3], DOUT[3]) ;
   initial begin
      forever begin
         #100;
         //$display("---gyc---%d", $time);
         if ($time >= 1000) begin
            $finish ;
         end
      end
   end
endmodule // test

仿真結(jié)果如下。

由圖可知,13ns 之內(nèi),4 個 PAD 均為輸入時,PAD 值均與 pull 功能對應(yīng),即 PAD0-1 均有上拉功能,PAD2-3 均有下拉功能。

13-53ns 之內(nèi),PAD0 作為輸出,PAD1 作為輸入,并且相連,兩者的邏輯值變化一致。同理,53ns-93ns 之內(nèi),PAD1 作為輸出,PAD0 作為輸入, 相連狀態(tài)下兩者邏輯值也是一致的。這說明 PAD0/1 的輸入輸出功能都是正常的。

PAD2/3 結(jié)果也類似,這里不再做說明。


點擊這里下載源碼


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

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號