- 超大規模積體電路設計教程
- 超大規模積體電路設計 - 首頁
- 超大規模積體電路設計 - 數字系統
- 超大規模積體電路設計 - FPGA 技術
- 超大規模積體電路設計 - MOS 電晶體
- 超大規模積體電路設計 - MOS 反相器
- 組合 MOS 邏輯電路
- 時序 MOS 邏輯電路
- VHDL 程式設計
- VHDL - 簡介
- VHDL - 組合電路
- VHDL - 時序電路
- Verilog
- Verilog - 簡介
- 行為建模與時序
- 超大規模積體電路設計有用資源
- 超大規模積體電路設計 - 快速指南
- 超大規模積體電路設計 - 有用資源
- 超大規模積體電路設計 - 討論
超大規模積體電路設計 - 快速指南
超大規模積體電路設計 - 數字系統
超大規模積體電路 (VLSI) 是透過將數千個電晶體組合到單個晶片上來建立積體電路 (IC) 的過程。VLSI 起源於 20 世紀 70 年代,當時複雜的半導體和通訊技術正在發展。微處理器是一種 VLSI 器件。
在引入 VLSI 技術之前,大多數 IC 的功能有限。一個電子電路可能由CPU、ROM、RAM和其他粘合邏輯組成。VLSI 使 IC 設計人員能夠將所有這些都新增到一個晶片中。
電子工業在過去幾十年中取得了驚人的發展,這主要是由於大規模整合技術和系統設計應用的快速發展。隨著超大規模整合 (VLSI) 設計的出現,積體電路 (IC) 在高效能計算、控制、電信、影像和影片處理以及消費電子產品中的應用數量正在快速增長。
當前的尖端技術,例如高解析度和低位元率影片以及蜂窩通訊,為終端使用者提供了大量的應用程式、處理能力和便攜性。預計這一趨勢將快速增長,這對 VLSI 設計和系統設計具有非常重要的意義。
VLSI 設計流程
下圖顯示了 VLSI IC 電路設計流程。各個設計級別均已編號,各個模組顯示設計流程中的過程。
規範是首先要確定的,它們抽象地描述了待設計的數字 IC 電路的功 能、介面和架構。
然後建立行為描述,以根據功能、效能、對給定標準的符合性以及其他規範來分析設計。
使用 HDL 完成 RTL 描述。對該 RTL 描述進行模擬以測試功能。從這裡開始,我們需要 EDA 工具的幫助。
然後使用邏輯綜合工具將 RTL 描述轉換為門級網表。門級網表是根據門和它們之間連線來描述電路的,這些門以滿足時序、功耗和麵積規範的方式製造。
最後,製作物理佈局,對其進行驗證,然後傳送到製造工廠。
Y 圖表
Gajski-Kuhn Y 圖表是一個模型,它捕獲了設計半導體器件時的考慮因素。
Gajski-Kuhn Y 圖表的三個域位於徑向軸上。每個域都可以使用同心環細分為不同的抽象級別。
在頂層(外環),我們考慮晶片的架構;在較低的級別(內環),我們依次將設計細化為更詳細的實現 -
透過高階綜合或邏輯綜合過程,可以從行為描述建立結構描述。
透過佈局綜合,可以從結構描述建立物理描述。
設計層次結構 - 結構
設計層次結構涉及“分而治之”的原則。它只不過是將任務分解成更小的任務,直到達到最簡單的級別。此過程最適用,因為設計的最後演變變得非常簡單,其製造變得更容易。
我們可以將給定任務設計到設計流程過程的域(行為、結構和幾何)。為了理解這一點,讓我們以設計一個 16 位加法器為例,如下圖所示。
在這裡,整個 16 位加法器晶片被分成四個 4 位加法器模組。此外,將 4 位加法器進一步劃分為 1 位加法器或半加法器。1 位加法是最簡單的設計過程,其內部電路也很容易在晶片上製造。現在,連線所有最後的四個加法器,我們可以設計一個 4 位加法器,繼續下去,我們可以設計一個 16 位加法器。
超大規模積體電路設計 - FPGA 技術
FPGA – 簡介
FPGA的全稱是“現場可程式設計門陣列”。它包含一萬到一百萬多個具有可程式設計互連的邏輯閘。可程式設計互連可供使用者或設計人員輕鬆執行給定功能。給定圖中顯示了一個典型的 FPGA 晶片模型。有一些 I/O 塊,它們根據功能進行設計和編號。對於每個邏輯級別組合模組,都有CLB(可配置邏輯塊)。
CLB 執行分配給模組的邏輯運算。CLB 和 I/O 塊之間的互連是藉助水平佈線通道、垂直佈線通道和 PSM(可程式設計多路複用器)實現的。
它包含的 CLB 數量僅決定 FPGA 的複雜性。CLB 和 PSM 的功能由 VHDL 或任何其他硬體描述語言設計。程式設計後,CLB 和 PSM 被放置在晶片上,並透過佈線通道相互連線。
優點
- 它只需要很少的時間;從設計過程到功能晶片。
- 它不涉及任何物理製造步驟。
- 唯一的缺點是,它比其他樣式貴。
門陣列設計
就快速原型製作能力而言,門陣列 (GA) 排名第二,僅次於 FPGA。雖然使用者程式設計對於 FPGA 晶片的設計實現非常重要,但 GA 使用金屬掩模設計和處理。門陣列實現需要兩步製造過程。
第一階段產生每個 GA 晶片上的一組未提交的電晶體。這些未提交的晶片可以儲存以備後用,這可以透過定義陣列電晶體之間的金屬互連來完成。金屬互連的圖案化是在晶片製造過程結束時完成的,因此週轉時間仍然可以很短,從幾天到幾周不等。下圖顯示了門陣列實現的基本處理步驟。
典型的門陣列平臺使用稱為通道的專用區域,用於 MOS 電晶體行或列之間的單元間佈線。它們簡化了互連。執行基本邏輯閘的互連模式儲存在庫中,然後可以使用該庫根據網表定製未提交電晶體的行。
在大多數現代 GA 中,多層金屬用於通道佈線。透過使用多層互連,可以在有源單元區域上實現佈線;因此,可以像在海門 (SOG) 晶片中一樣移除佈線通道。在這裡,整個晶片表面都覆蓋著未提交的 nMOS 和 pMOS 電晶體。可以使用金屬掩模定製相鄰電晶體以形成基本邏輯閘。
對於單元間佈線,必須犧牲一些未提交的電晶體。這種設計風格帶來了更高的互連靈活性,通常還具有更高的密度。GA 晶片利用率由使用的芯片面積除以總芯片面積來衡量。它高於 FPGA,晶片速度也是如此。
基於標準單元的設計
基於標準單元的設計需要開發完整的定製掩模組。標準單元也稱為多單元。在這種方法中,所有常用的邏輯單元都經過開發、表徵並存儲在標準單元庫中。
庫可能包含幾百個單元,包括反相器、與非門、或非門、複雜的 AOI、OAI 門、D 鎖存器和觸發器。每種門型別都可以實現多個版本,以提供針對不同扇出足夠的驅動能力。反相器門可以具有標準尺寸、雙倍尺寸和四倍尺寸,以便晶片設計人員可以選擇合適的尺寸以獲得高電路速度和佈局密度。
根據幾個不同的表徵類別對每個單元進行表徵,例如:
- 延遲時間與負載電容
- 電路模擬模型
- 時序模擬模型
- 故障模擬模型
- 用於佈局佈線的單元資料
- 掩模資料
為了自動放置單元和佈線,每個單元佈局的設計高度固定,以便可以並排繫結多個單元以形成行。電源和地軌平行於單元的上邊界和下邊界執行。因此,相鄰單元共享一個公共電源匯流排和一個公共地匯流排。下圖是基於標準單元的設計的平面圖。
全定製設計
在全定製設計中,整個掩模設計都是新的,無需使用任何庫。這種設計風格的開發成本正在上升。因此,設計重用的概念正變得越來越流行,以縮短設計週期和降低開發成本。
最難的全定製設計可能是儲存單元的設計,無論是靜態的還是動態的。對於邏輯晶片設計,可以使用同一晶片上不同設計風格的組合(即標準單元、資料路徑單元和可程式設計邏輯陣列 (PLA))獲得良好的協商。
實際上,設計人員進行全定製佈局,即每個電晶體的幾何形狀、方向和位置。設計效率通常非常低;通常每個設計人員每天只有幾十個電晶體。在數字 CMOS VLSI 中,由於人工成本高,幾乎不使用全定製設計。這些設計風格包括高產量產品的 設計,例如儲存晶片、高效能微處理器和 FPGA。
超大規模積體電路設計 - MOS 電晶體
互補金氧半導體 (CMOS) 技術現已被廣泛用於在眾多不同應用中形成電路。如今的計算機、CPU 和手機都使用 CMOS,因為它具有幾個關鍵優勢。CMOS 具有低功耗、相對較高的速度、兩種狀態下的高噪聲容限,並且可以在很寬的源電壓和輸入電壓範圍內工作(前提是源電壓固定)。
對於我們將討論的過程,可用的電晶體型別是金氧半導體場效應電晶體 (MOSFET)。這些電晶體像“三明治”一樣形成,由半導體層(通常是切片或晶片,來自單晶矽)、一層二氧化矽(氧化物)和一層金屬組成。
MOSFET 的結構
如圖所示,MOS 結構包含三層 -
金屬柵極電極
絕緣氧化層 (SiO2)
P 型半導體(襯底)
MOS 結構形成一個電容器,柵極和襯底作為兩個極板,氧化層作為介電材料。介電材料 (SiO2) 的厚度通常在 10 nm 到 50 nm 之間。可以透過施加到柵極和襯底端子的外部電壓來控制襯底內的載流子濃度和分佈。現在,為了理解 MOS 的結構,首先考慮 P 型半導體襯底的基本電特性。
半導體材料中載流子的濃度始終遵循**質量作用定律**。質量作用定律表示為:
$$n.p=n_{i}^{2}$$
其中:
n 為電子載流子濃度
p 為空穴載流子濃度
ni 為矽的本徵載流子濃度
現在假設襯底以受主(硼)濃度NA均勻摻雜。因此,p型襯底中的電子和空穴濃度為:
$$n_{po}=\frac{n_{i}^{2}}{N_{A}}$$
$$p_{po}=N_{A}$$
這裡,摻雜濃度NA比本徵濃度ni大(1015到1016 cm−3)。現在,為了理解MOS結構,考慮p型矽襯底的能級圖。
如圖所示,導帶和價帶之間的帶隙為1.1eV。這裡,費米勢ΦF是本徵費米能級(Ei)和費米能級(EFP)之間的差值。
其中費米能級EF取決於摻雜濃度。費米勢ΦF是本徵費米能級(Ei)和費米能級(EFP)之間的差值。
數學上表示為:
$$\Phi_{Fp}=\frac{E_{F}-E_{i}}{q}$$
導帶和自由空間之間的電勢差稱為電子親和勢,用qx表示。
因此,電子從費米能級移動到自由空間所需的能量稱為功函式(qΦS),其表示式為:
$$q\Phi _{s}=(E_{c}-E_{F})+qx$$
下圖顯示了構成MOS器件的各組成部分的能帶圖。
如圖所示,絕緣SiO2層具有8eV的大能帶隙,功函式為0.95 eV。金屬柵極的功函式為4.1eV。這裡,功函式不同,因此會在MOS系統中產生壓降。下圖顯示了MOS系統的組合能帶圖。
如圖所示,金屬柵極和半導體(Si)的費米能級處於相同的電勢。表面處的費米勢稱為表面勢ΦS,其大小小於費米勢ΦF。
MOSFET的工作原理
MOSFET由一個MOS電容和兩個放置在溝道區域附近的p-n結組成,該區域由柵極電壓控制。為了使兩個p-n結反向偏置,襯底電勢保持低於其他三個端子的電勢。
如果柵極電壓升高到超過閾值電壓(VGS>VTO),則會在表面上形成反型層,並在源極和漏極之間形成n型溝道。該n型溝道將根據VDS的值傳輸漏極電流。
對於不同的VDS值,MOSFET可以工作在不同的區域,如下所述。
線性區
在VDS = 0時,反型溝道區域處於熱平衡狀態,漏極電流ID = 0。現在,如果施加小的漏極電壓VDS > 0,則與VDS成比例的漏極電流將開始從源極流向漏極,穿過溝道。
溝道為電流從源極流向漏極提供了連續的路徑。這種工作模式稱為**線性區**。下圖顯示了線上性區工作的n溝道MOSFET的截面圖。
飽和區邊緣
現在,如果增加VDS,則溝道中的電荷和溝道深度在漏極端減小。對於VDS = VDSAT,溝道中的電荷減少到零,這稱為**夾斷點**。下圖顯示了在飽和區邊緣工作的n溝道MOSFET的截面圖。
飽和區
對於VDS>VDSAT,在漏極附近會形成耗盡層,並且透過增加漏極電壓,該耗盡層會延伸到源極。
這種工作模式稱為**飽和區**。來自源極到溝道末端的電子進入漏極耗盡區,並在高電場中被加速朝向漏極。
MOSFET電流-電壓特性
為了理解MOSFET的電流-電壓特性,對溝道進行了近似。如果沒有這種近似,MOS系統的三維分析將變得複雜。用於電流-電壓特性的**漸變溝道近似(GCA)** 將簡化分析問題。
漸變溝道近似(GCA)
考慮線上性模式下工作的n溝道MOSFET的截面圖。這裡,源極和襯底連線到地。VS = VB = 0。柵源電壓(VGS)和漏源電壓(VDS)是控制漏極電流ID的外部引數。
將VGS設定為高於閾值電壓VTO的電壓,以在源極和漏極之間形成溝道。如圖所示,x方向垂直於表面,y方向平行於表面。
這裡,y = 0在源極端,如圖所示。相對於源極的溝道電壓用VC(Y)表示。假設閾值電壓VTO沿溝道區域(從y = 0到y = L)是恆定的。溝道電壓VC的邊界條件為:
$$V_{c}\left ( y = 0 \right ) = V_{s} = 0 \,且\,V_{c}\left ( y = L \right ) = V_{DS}$$
我們還可以假設:
$$V_{GS}\geq V_{TO}$$ 且
$$V_{GD} = V_{GS}-V_{DS}\geq V_{TO}$$
設Q1(y)為表面反型層中的總可動電子電荷。此電子電荷可表示為:
$$Q1(y)=-C_{ox}.[V_{GS}-V_{C(Y)}-V_{TO}]$$
下圖顯示了表面反型層的空間幾何形狀並指出了其尺寸。當我們從漏極移動到源極時,反型層逐漸變細。現在,如果我們考慮溝道長度L的小區域dy,則該區域提供的增量電阻dR可表示為:
$$dR=-\frac{dy}{w.\mu _{n}.Q1(y)}$$
這裡,負號是由於反型層電荷Q1的負極性,μn是表面遷移率,它是常數。現在,將Q1(y)的值代入dR方程:
$$dR=-\frac{dy}{w.\mu _{n}.\left \{ -C_{ox}\left [ V_{GS}-V_{C\left ( Y \right )} \right ]-V_{TO} \right \}}$$
$$dR=\frac{dy}{w.\mu _{n}.C_{ox}\left [ V_{GS}-V_{C\left ( Y \right )} \right ]-V_{TO}}$$
現在,小dy區域中的電壓降可以表示為:
$$dV_{c}=I_{D}.dR$$
將dR的值代入上述方程:
$$dV_{C}=I_{D}.\frac{dy}{w.\mu_{n}.C_{ox}\left [ V_{GS}-V_{C(Y)} \right ]-V_{TO}}$$
$$w.\mu _{n}.C_{ox}\left [ V_{GS}-V_{C(Y)}-V_{TO} \right ].dV_{C}=I_{D}.dy$$
為了獲得整個溝道區域上的漏極電流ID,上述方程可以沿溝道從y = 0積分到y = L,電壓VC(y) = 0到VC(y) = VDS,
$$C_{ox}.w.\mu _{n}.\int_{V_{c}=0}^{V_{DS}} \left [ V_{GS}-V_{C\left ( Y \right )}-V_{TO} \right ].dV_{C} = \int_{Y=0}^{L}I_{D}.dy$$
$$\frac{C_{ox}.w.\mu _{n}}{2}\left ( 2\left [ V_{GS}-V_{TO} \right ] V_{DS}-V_{DS}^{2}\right ) = I_{D}\left [ L-0 \right ]$$
$$I_{D} = \frac{C_{ox}.\mu _{n}}{2}.\frac{w}{L}\left ( 2\left [ V_{GS}-V_{TO} \right ]V_{DS}-V_{DS}^{2} \right )$$
對於線性區VDS < VGS − VTO。對於飽和區,VDS的值大於(VGS − VTO)。因此,對於飽和區VDS = (VGS − VTO)。
$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{\left [ 2V_{DS} \right ]V_{DS}-V_{DS}^{2}}{L} \right )$$
$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{2V_{DS}^{2}-V_{DS}^{2}}{L} \right )$$
$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{V_{DS}^{2}}{L} \right )$$
$$I_{D} = C_{ox}.\mu _{n}.\frac{w}{2}\left ( \frac{\left [ V_{GS}-V_{TO} \right ]^{2}}{L} \right )$$
超大規模積體電路設計 - MOS 反相器
反相器是所有數字設計的核心。一旦清楚地理解了它的工作原理和特性,設計更復雜的結構,如與非門、加法器、乘法器和微處理器就會大大簡化。這些複雜電路的電氣行為幾乎可以完全透過推斷反相器的結果來推導。
反相器的分析可以擴充套件到解釋更復雜門(如與非門、或非門或異或門)的行為,而這些門又構成了乘法器和處理器等模組的構建塊。在本章中,我們關注反相器門的單一實現形式,即靜態CMOS反相器——簡稱CMOS反相器。這當然是目前最流行的,因此值得我們特別關注。
工作原理
理想反相器的邏輯符號和真值表如下圖所示。這裡A是輸入,B是反相輸出,由它們的節點電壓表示。使用正邏輯,邏輯1的布林值由Vdd表示,邏輯0由0表示。Vth是反相器閾值電壓,其值為Vdd /2,其中Vdd是輸出電壓。
當輸入小於Vth時,輸出從0切換到Vdd。因此,對於0<Vin<Vth,輸出等於邏輯0輸入;對於Vth<Vin< Vdd,輸出等於反相器的邏輯1輸入。
圖中所示的特性是理想的。nMOS反相器的通用電路結構如下圖所示。
從給定的圖中,我們可以看到反相器的輸入電壓等於nMOS電晶體的柵極到源極電壓,反相器的輸出電壓等於nMOS電晶體的漏極到源極電壓。nMOS的源極到襯底電壓也稱為電晶體驅動器,其接地;因此VSS = 0。輸出節點連線到用於VTC的集總電容。
電阻負載反相器
基本電阻負載反相器的結構如下圖所示。這裡,增強型nMOS充當驅動電晶體。負載由一個簡單的線性電阻RL組成。電路的電源為VDD,漏極電流ID等於負載電流IR。
電路工作原理
當驅動電晶體的輸入小於閾值電壓VTH (Vin < VTH)時,驅動電晶體處於截止區域,不導通任何電流。因此,負載電阻上的電壓降為零,輸出電壓等於VDD。現在,當輸入電壓進一步增加時,驅動電晶體將開始導通非零電流,nMOS進入飽和區。
數學上表示為:
$$I_{D} = \frac{K_{n}}{2}\left [ V_{GS}-V_{TO} \right ]^{2}$$
進一步增加輸入電壓,驅動電晶體將進入線性區域,驅動電晶體的輸出減小。
$$I_{D} = \frac{K_{n}}{2}2\left [ V_{GS}-V_{TO} \right ]V_{DS}-V_{DS}^{2}$$
下圖所示的電阻負載反相器的VTC指示驅動電晶體的工作模式和電壓點。
採用N型MOSFET負載的反相器
使用MOSFET作為負載器件的主要優點是電晶體佔用的矽面積小於電阻負載佔用的面積。這裡,MOSFET是有源負載,採用有源負載的反相器比採用電阻負載的反相器效能更好。
增強型負載NMOS
圖中顯示了兩個帶有增強型負載器件的反相器。負載電晶體可以在飽和區或線性區工作,具體取決於施加到其柵極端的偏置電壓。飽和增強型負載反相器如圖(a)所示。它只需要一個電源和簡單的製造工藝,因此VOH限制為VDD − VT。
線性增強型負載反相器如圖(b)所示。它始終線上性區域工作;因此VOH電平等於VDD。
與飽和增強型反相器相比,線性負載反相器具有更高的噪聲容限。但是,線性增強型反相器的缺點是需要兩個獨立的電源,並且這兩個電路都存在高功耗問題。因此,增強型反相器不用於任何大規模數字應用。
耗盡型負載NMOS
可以使用耗盡型負載反相器克服增強型負載反相器的缺點。與增強型負載反相器相比,耗盡型負載反相器需要更多幾個製造步驟來進行溝道注入,以調整負載的閾值電壓。
耗盡型負載反相器的優點是:VTC轉換尖銳、噪聲容限更好、單電源和整體佈局面積更小。
如圖所示,負載的柵極和源極端子相連線;因此,VGS = 0。因此,負載的閾值電壓為負。因此,
$$V_{GS,load}> V_{T,load}$$ 成立
因此,無論輸入和輸出電壓電平如何,負載器件始終具有導電通道。
當負載電晶體處於飽和區時,負載電流由下式給出
$$I_{D,load} = \frac{K_{n,load}}{2}\left [ -V_{T,load}\left ( V_{out} \right ) \right ]^{2}$$
當負載電晶體處於線性區時,負載電流由下式給出
$$I_{D,load} = \frac{K_{n,load}}{2}\left [ 2\left | V_{T,load}\left ( V_{out} \right ) \right |.\left ( V_{DD}-V_{out} \right )-\left ( V_{DD}-V_{out} \right )^{2} \right ]$$
耗盡型負載反相器的電壓傳輸特性如下圖所示:
CMOS反相器——電路、工作原理和描述
CMOS反相器電路如下圖所示。這裡,nMOS和pMOS電晶體充當驅動電晶體;當一個電晶體導通時,另一個電晶體截止。
這種配置稱為**互補MOS(CMOS)**。輸入連線到兩個電晶體的柵極端,以便可以用輸入電壓直接驅動兩者。nMOS的襯底連線到地,pMOS的襯底連線到電源VDD。
因此,兩個電晶體的VSB = 0。
$$V_{GS,n}=V_{in}$$
$$V_{DS,n}=V_{out}$$
並且,
$$V_{GS,p}=V_{in}-V_{DD}$$
$$V_{DS,p}=V_{out}-V_{DD}$$
當nMOS的輸入小於閾值電壓(Vin < VTO,n)時,nMOS截止,pMOS處於線性區。因此,兩個電晶體的漏極電流均為零。
$$I_{D,n}=I_{D,p}=0$$
因此,輸出電壓VOH等於電源電壓。
$$V_{out}=V_{OH}=V_{DD}$$
當輸入電壓大於VDD + VTO,p時,pMOS電晶體處於截止區,nMOS處於線性區,因此兩個電晶體的漏極電流均為零。
$$I_{D,n}=I_{D,p}=0$$
因此,輸出電壓VOL等於零。
$$V_{out}=V_{OL}=0$$
如果Vin > VTO並且滿足以下條件,則nMOS工作在飽和區。
$$V_{DS,n}\geq V_{GS,n}-V_{TO,n} $$
$$V_{out}\geq V_{in}-V_{TO,n} $$
如果Vin < VDD + VTO,p並且滿足以下條件,則pMOS工作在飽和區。
$$V_{DS,p}\leq V_{GS,p}-V_{TO,p} $$
$$V_{out}\leq V_{in}-V_{TO,p} $$
對於不同的輸入電壓值,下面列出了兩個電晶體的工作區域。
| 區域 | Vin | Vout | nMOS | pMOS |
|---|---|---|---|---|
| A | < VTO, n | VOH | 截止 | 線性 |
| B | VIL | 高 ≈ VOH | 飽和 | 線性 |
| C | Vth | Vth | 飽和 | 飽和 |
| D | VIH | 低 ≈ VOL | 線性 | 飽和 |
| E | > (VDD + VTO, p) | VOL | 線性 | 截止 |
CMOS的VTC如下圖所示:
組合 MOS 邏輯電路
組合邏輯電路或門是所有數字系統的基本構建塊,它們對多個輸入變數執行布林運算,並將輸出確定為輸入的布林函式。我們將檢查簡單的電路配置,例如雙輸入NAND門和NOR門,然後將我們的分析擴充套件到更一般的多輸入電路結構。
接下來,將以類似的方式介紹CMOS邏輯電路。我們將強調nMOS耗盡型負載邏輯和CMOS邏輯電路之間的異同,並透過示例指出CMOS門的優點。在其最一般的形式中,執行布林函式的組合邏輯電路或門可以表示為多輸入單輸出系統,如圖所示。
參考接地電位的節點電壓表示所有輸入變數。使用正邏輯約定,“1”的布林(或邏輯)值可以用VDD的高電壓表示,“0”的布林(或邏輯)值可以用0的低電壓表示。輸出節點載入了電容CL,它表示電路中寄生器件的組合電容。
CMOS邏輯電路
CMOS雙輸入NOR門
該電路由並聯連線的n網路和串聯連線的互補p網路組成。輸入電壓VX和VY施加到一個nMOS電晶體和一個pMOS電晶體的柵極。
當一個或兩個輸入都為高電平時,即當n網路在輸出節點和地之間建立導電路徑時,p網路將截止。如果兩個輸入電壓都低,即n網路截止,則p網路在輸出節點和電源電壓之間建立導電路徑。
對於任何給定的輸入組合,互補電路結構使得輸出透過低電阻路徑連線到VDD或地,並且對於任何輸入組合,VDD和地之間都不會建立直流電流路徑。CMOS雙輸入NOR門的輸出電壓將獲得VOL = 0的邏輯低電壓和VOH = VDD的邏輯高電壓。開關閾值電壓Vth的方程為
$$V_{th}\left ( NOR2 \right ) = \frac{V_{T,n}+\frac{1}{2}\sqrt{\frac{k_{p}}{k_{n}}\left ( V_{DD}-\left | V_{T,p} \right | \right )}}{1+\frac{1}{2}\sqrt{\frac{k_{p}}{k_{n}}}}$$
CMOS雙輸入NOR門的佈局
該圖顯示了使用單層金屬和單層多晶矽的CMOS雙輸入NOR門的示例佈局。此佈局的特性為:
- 每個輸入的單垂直多晶線
- 分別為N型和P型器件的單活性形狀
- 水平執行的金屬匯流排
下圖顯示了CMOS N0R2門的示意圖;它直接對應於佈局,但不包含W和L資訊。擴散區域由矩形表示,金屬連線和實線和圓分別表示觸點,交叉影線條帶分別表示多晶矽柱。示意圖用於規劃最佳佈局拓撲。
CMOS雙輸入NAND門
下圖給出了雙輸入CMOS NAND門的電路圖。
該電路的工作原理與CMOS雙輸入NOR運算完全對偶。由兩個串聯連線的nMOS電晶體組成的n網路,如果兩個輸入電壓都為邏輯高電平,則在輸出節點和地之間建立導電路徑。p網路中的兩個並聯連線的pMOS電晶體將關閉。
對於所有其他輸入組合,一個或兩個pMOS電晶體將導通,而p網路截止,從而在輸出節點和電源電壓之間建立電流路徑。該門的開關閾值獲得為:
$$V_{th}\left ( NAND2 \right ) = \frac{V_{T,n}+2\sqrt{\frac{k_{p}}{k_{n}}\left ( V_{DD}-\left | V_{T,p} \right | \right )}}{1+2\sqrt{\frac{k_{p}}{k_{n}}}}$$
此佈局的特性如下:
- 輸入的單多晶矽線垂直穿過N和P有源區域。
- 單個有源形狀用於構建nMOS器件和pMOS器件。
- 電源匯流排在佈局的頂部和底部水平執行。
- 輸出線水平執行,便於與相鄰電路連線。
複雜邏輯電路
NMOS耗盡負載複雜邏輯閘
為了實現多個輸入變數的複雜功能,可以將為NOR和NAND開發的基本電路結構和設計原理擴充套件到複雜的邏輯閘。使用少量電晶體實現複雜邏輯功能的能力是nMOS和CMOS邏輯電路最吸引人的特性之一。考慮以下布林函式為例:
$$ \overline{Z=P\left ( S+T \right )+QR} $$
用於實現此功能的nMOS耗盡負載複雜邏輯閘如圖所示。在此圖中,三個驅動電晶體的左側nMOS驅動分支用於執行邏輯函式P(S+T),而右側分支執行函式QR。透過並聯連線這兩個分支,並將負載電晶體置於輸出節點和電源電壓VDD之間,我們得到給定的複雜函式。每個輸入變數只分配給一個驅動器。
檢查電路拓撲結構可以得到下拉網路的簡單設計原則:
- OR運算由並聯連線的驅動器執行。
- AND運算由串聯連線的驅動器執行。
- 反轉由MOS電路操作的特性提供。
如果實現該函式的電路中所有輸入變數均為邏輯高電平,則由五個nMOS電晶體組成的下拉網路的等效驅動器(W/L)比率為
$$ \frac{W}{L}=\frac{1}{\frac{1}{\left ( W/L \right )Q}+\frac{1}{\left ( W/L \right )R}}+\frac{1}{\frac{1}{\left ( W/L \right )P}+\frac{1}{\left ( W/L \right )S+\left ( W/L \right )Q}} $$
複雜的CMOS邏輯閘
n網路或下拉網路的實現基於為nMOS耗盡負載複雜邏輯閘檢查的相同基本設計原則。pMOS上拉網路必須是n網路的對偶網路。
這意味著nMOS網路中的所有並聯連線都將對應於pMOS網路中的串聯連線,而nMOS網路中的所有串聯連線都將對應於pMOS網路中的並聯連線。該圖顯示了從n網路(下拉)圖構建對偶p網路(上拉)圖的簡單方法。
下拉網路中的每個驅動電晶體用ai表示,每個節點用下拉圖中的一個頂點表示。接下來,在下拉圖的每個封閉區域內建立一個新的頂點,並且相鄰的頂點透過邊連線,這些邊只穿過下拉圖中的每條邊一次。這個新圖顯示了上拉網路。
使用尤拉圖法的佈局技術
該圖顯示了複雜函式的CMOS實現及其採用任意門排序的簡圖,該排序為CMOS門提供了非常非最佳化的佈局。
在這種情況下,多晶矽列之間的間距必須允許擴散之間的擴散到擴散間距。這肯定會消耗相當多的額外矽面積。
透過使用尤拉路徑,我們可以獲得最佳佈局。尤拉路徑定義為一條不間斷的路徑,它恰好遍歷圖的每條邊(分支)一次。在下拉樹圖和上拉樹圖中找到具有相同輸入順序的尤拉路徑。
VLSI設計 - 順序MOS邏輯電路
邏輯電路分為兩類:(a)組合電路和(b)時序電路。
在組合電路中,輸出僅取決於最新輸入的條件。
在時序電路中,輸出不僅取決於最新的輸入,還取決於早期輸入的條件。時序電路包含儲存單元。
時序電路有三種類型:
雙穩態 - 雙穩態電路有兩個穩定的工作點,並將處於任一狀態。例如:儲存單元、鎖存器、觸發器和暫存器。
單穩態 - 單穩態電路只有一個穩定的工作點,即使它們暫時被擾動到相反的狀態,它們也會及時返回到它們穩定的工作點。例如:定時器、脈衝發生器。
無穩態 - 電路沒有穩定的工作點,並在多個狀態之間振盪。例如:環形振盪器。
CMOS邏輯電路
基於NOR門的SR鎖存器
如果置位輸入 (S) 等於邏輯 "1" 並且復位輸入等於邏輯 "0",則輸出 Q 將被強制為邏輯 "1"。而 $\overline{Q}$ 被強制為邏輯 "0"。這意味著 SR 鎖存器將被置位,而不管其先前狀態如何。
類似地,如果 S 等於 "0" 並且 R 等於 "1",則輸出 Q 將被強制為 "0",而 $\overline{Q}$ 被強制為 "1"。這意味著鎖存器被複位,而不管其先前保持的狀態如何。最後,如果輸入 S 和 R 都等於邏輯 "1",則兩個輸出都將被強制為邏輯 "0",這與 Q 和 $\overline{Q}$ 的互補性相沖突。
因此,此輸入組合在正常操作期間不允許使用。基於NOR的SR鎖存器的真值表在表中給出。
| S | R | Q | $\overline{Q}$ | 操作 |
|---|---|---|---|---|
| 0 | 0 | Q | $\overline{Q}$ | 保持 |
| 1 | 0 | 1 | 0 | 置位 |
| 0 | 1 | 0 | 1 | 復位 |
| 1 | 1 | 0 | 0 | 不允許 |
基於NOR門的CMOS SR鎖存器如下圖所示。
如果 S 等於 VOH 並且 R 等於 VOL,則並聯連線的電晶體 M1 和 M2 都將導通。節點 $\overline{Q}$ 上的電壓將假設 VOL = 0 的低邏輯電平。
同時,M3 和 M4 關閉,導致節點 Q 處的邏輯高電壓 VOH。如果 R 等於 VOH 並且 S 等於 VOL,則 M1 和 M2 關閉,M3 和 M4 導通。
基於NAND門的SR鎖存器
基於NAND的SR鎖存器的框圖和門級原理圖如圖所示。S和R輸入端的小圓圈表示電路響應於低電平有效輸入訊號。基於NAND的SR鎖存器的真值表在表中給出。
| S | R | Q | Q′ | |
| 0 | 0 | NC | NC | 無變化。鎖存器保持當前狀態。 |
| 1 | 0 | 1 | 0 | 鎖存器置位。 |
| 0 | 1 | 0 | 1 | 鎖存器復位。 |
| 1 | 1 | 0 | 0 | 無效條件。 |
如果 S 變為 0(當 R = 1 時),Q 變為高電平,將 $\overline{Q}$ 拉低,鎖存器進入置位狀態。
S = 0 則 Q = 1(如果 R = 1)
如果 R 變為 0(當 S = 1 時),Q 變為高電平,將 $\overline{Q}$ 拉低,鎖存器被複位。
R = 0 則 Q = 1(如果 S = 1)
保持狀態需要 S 和 R 都為高電平。如果 S = R = 0,則輸出不允許,因為它會導致不確定的狀態。基於NAND門的CMOS SR鎖存器如圖所示。
基於NAND門的耗盡負載nMOS SR鎖存器如圖所示。其操作類似於CMOS NAND SR鎖存器。CMOS電路實現具有低靜態功耗和高噪聲容限。
CMOS邏輯電路
帶時鐘的SR鎖存器
該圖顯示了一個添加了時鐘的基於NOR的SR鎖存器。只有當 CLK 為高電平時,鎖存器才響應輸入 S 和 R。
當 CLK 為低電平時,鎖存器保持其當前狀態。觀察 Q 狀態變化:
- 當 S 在正 CLK 期間變為高電平時。
- 在 CLK 低時間內 S & R 變化後的前沿 CLK 邊沿。
- S 在 CLK 為高電平時出現正毛刺。
- 當 R 在正 CLK 期間變為高電平時。
帶時鐘的基於NOR的SR鎖存器的CMOS AOI實現如圖所示。請注意,只需要12個電晶體。
當 CLK 為低電平時,N 樹 N 中的兩個串聯端子斷開,P 樹中的兩個並聯電晶體導通,從而保持儲存單元中的狀態。
當時鍾為高電平時,電路簡單地變為基於NOR的CMOS鎖存器,它將響應輸入 S 和 R。
基於NAND門的帶時鐘的SR鎖存器
電路採用四個NAND門實現。如果使用CMOS實現此電路,則需要16個電晶體。
- 只有當 CLK 為高電平時,鎖存器才響應 S 或 R。
- 如果兩個輸入訊號和 CLK 訊號都為高電平有效:即,當 CLK = "1" S = "1" 且 R = "0" 時,鎖存器輸出 Q 將被置位。
- 類似地,當 CLK = "1",S = "0" 時,鎖存器將被複位,並且
當 CLK 為低電平時,鎖存器保持其當前狀態。
帶時鐘的JK鎖存器
上圖顯示了一個基於NAND門的帶時鐘的JK鎖存器。SR鎖存器的缺點是,當S和R都為高電平時,其輸出狀態變得不確定。JK鎖存器透過使用從輸出到輸入的反饋來消除這個問題,這樣真值表的所有輸入狀態都是允許的。如果 J = K = 0,鎖存器將保持其當前狀態。
如果 J = 1 且 K = 0,則鎖存器將在下一個正跳變時鐘沿置位,即 Q = 1,$\overline{Q}$ = 0。
如果 J = 0 且 K = 1,則鎖存器將在下一個正跳變時鐘沿復位,即 Q = 1 且 $\overline{Q}$ = 0。
如果 J = K = 1,則鎖存器將在下一個正跳變時鐘沿翻轉。
帶時鐘的JK鎖存器的操作總結在表中給出的真值表中。
J |
K |
Q |
$\overline{Q}$ | S |
R |
Q |
$\overline{Q}$ | 操作 |
| 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 保持 |
| 1 | 0 | 1 | 1 | 1 | 0 | |||
| 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 復位 |
| 1 | 0 | 1 | 0 | 0 | 1 | |||
| 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 置位 |
| 1 | 0 | 1 | 1 | 1 | 0 | |||
| 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 翻轉 |
| 1 | 0 | 1 | 0 | 0 | 1 |
CMOS D鎖存器實現
D鎖存器通常使用傳輸門(TG)開關實現,如圖所示。輸入TG由CLK啟用,而鎖存反饋環路TG由CLK啟用。當CLK為高電平時接受輸入D。當CLK變為低電平時,輸入電路開路,鎖存器設定為先前的D資料。
VLSI設計 - VHDL簡介
VHDL代表超高速積體電路硬體描述語言。它是一種程式語言,用於透過資料流、行為和結構建模風格來建模數字系統。該語言於1981年首次為國防部(DoD)在VHSIC專案下引入。
描述設計
在VHDL中,實體用於描述硬體模組。實體可以使用以下方式描述:
- 實體宣告
- 結構體
- 配置
- 包宣告
- 包主體
讓我們看看這些是什麼?
實體宣告
它定義了硬體模組的名稱、輸入輸出訊號和模式。
語法 −
entity entity_name is Port declaration; end entity_name;
實體宣告應以“entity”開頭,以“end”結尾。方向將是輸入、輸出或雙向。
| 輸入 (In) | 埠可讀 |
| 輸出 (Out) | 埠可寫 |
| 雙向 (Inout) | 埠可讀寫 |
| 緩衝 (Buffer) | 埠可讀寫,只能有一個源。 |
結構體 −
結構體可以使用結構化、資料流、行為或混合樣式來描述。
語法 −
architecture architecture_name of entity_name architecture_declarative_part; begin Statements; end architecture_name;
在這裡,我們應該指定我們正在為其編寫結構體主體的實體名稱。結構體語句應該位於“begin”和“end”關鍵字內。結構體宣告部分可能包含變數、常量或元件宣告。
資料流建模
在這種建模風格中,資料流經實體的流程是用併發(並行)訊號表達的。VHDL中的併發語句是WHEN和GENERATE。
除此之外,僅使用運算子(AND、NOT、+、*、sll等)的賦值也可以用於構建程式碼。
最後,這種程式碼中還可以使用一種特殊的賦值,稱為BLOCK。
在併發程式碼中,可以使用以下內容:
- 運算子
- WHEN語句(WHEN/ELSE或WITH/SELECT/WHEN);
- GENERATE語句;
- BLOCK語句
行為建模
在這種建模風格中,實體的行為是一組語句,按指定的順序依次執行。只有放在PROCESS、FUNCTION或PROCEDURE內的語句才是順序執行的。
PROCESSES、FUNCTIONS和PROCEDURES是唯一順序執行的程式碼段。
但是,作為一個整體,這些塊中的任何一個仍然與放在其外部的任何其他語句併發。
行為程式碼的一個重要方面是它不限於順序邏輯。事實上,我們可以用它來構建順序電路和組合電路。
行為語句是IF、WAIT、CASE和LOOP。變數也受到限制,它們應該只在順序程式碼中使用。變數永遠不能是全域性的,因此它的值不能直接傳遞出去。
結構化建模
在這種建模中,實體被描述為一組互連的元件。元件例化語句是一個併發語句。因此,這些語句的順序並不重要。結構化建模風格只描述元件(視為黑盒)的互連,而不暗示元件本身或它們共同代表的實體的任何行為。
在結構化建模中,結構體主體由兩部分組成:宣告部分(在關鍵字begin之前)和語句部分(在關鍵字begin之後)。
邏輯運算 – 與門
| X | Y | Z |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 1 |
VHDL Code: Library ieee; use ieee.std_logic_1164.all; entity and1 is port(x,y:in bit ; z:out bit); end and1; architecture virat of and1 is begin z<=x and y; end virat;
波形
邏輯運算 – 或門
| X | Y | Z |
|---|---|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
VHDL Code: Library ieee; use ieee.std_logic_1164.all; entity or1 is port(x,y:in bit ; z:out bit); end or1; architecture virat of or1 is begin z<=x or y; end virat;
波形
邏輯運算 – 非門
| X | Y |
|---|---|
| 0 | 1 |
| 1 | 0 |
VHDL Code: Library ieee; use ieee.std_logic_1164.all; entity not1 is port(x:in bit ; y:out bit); end not1; architecture virat of not1 is begin y<=not x; end virat;
波形
邏輯運算 – 與非門
| X | Y | Z |
|---|---|---|
| 0 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
VHDL Code: Library ieee; use ieee.std_logic_1164.all; entity nand1 is port(a,b:in bit ; c:out bit); end nand1; architecture virat of nand1 is begin c<=a nand b; end virat;
波形
邏輯運算 – 或非門
| X | Y | Z |
|---|---|---|
| 0 | 0 | 1 |
| 0 | 1 | 0 |
| 1 | 0 | 0 |
| 1 | 1 | 0 |
VHDL Code: Library ieee; use ieee.std_logic_1164.all; entity nor1 is port(a,b:in bit ; c:out bit); end nor1; architecture virat of nor1 is begin c<=a nor b; end virat;
波形
邏輯運算 – 異或門
| X | Y | Z |
|---|---|---|
| 0 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
VHDL Code: Library ieee; use ieee.std_logic_1164.all; entity xor1 is port(a,b:in bit ; c:out bit); end xor1; architecture virat of xor1 is begin c<=a xor b; end virat;
波形
邏輯運算 – 同或門
| X | Y | Z |
|---|---|---|
| 0 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
VHDL Code: Library ieee; use ieee.std_logic_1164.all; entity xnor1 is port(a,b:in bit ; c:out bit); end xnor1; architecture virat of xnor1 is begin c<=not(a xor b); end virat;
波形
VHDL組合電路程式設計
本章解釋組合電路的VHDL程式設計。
半加器的VHDL程式碼
VHDL Code: Library ieee; use ieee.std_logic_1164.all; entity half_adder is port(a,b:in bit; sum,carry:out bit); end half_adder; architecture data of half_adder is begin sum<= a xor b; carry <= a and b; end data;
波形
全加器的VHDL程式碼
Library ieee; use ieee.std_logic_1164.all; entity full_adder is port(a,b,c:in bit; sum,carry:out bit); end full_adder; architecture data of full_adder is begin sum<= a xor b xor c; carry <= ((a and b) or (b and c) or (a and c)); end data;
波形
半減器的VHDL程式碼
Library ieee; use ieee.std_logic_1164.all; entity half_sub is port(a,c:in bit; d,b:out bit); end half_sub; architecture data of half_sub is begin d<= a xor c; b<= (a and (not c)); end data;
波形
全減器的VHDL程式碼
Library ieee; use ieee.std_logic_1164.all; entity full_sub is port(a,b,c:in bit; sub,borrow:out bit); end full_sub; architecture data of full_sub is begin sub<= a xor b xor c; borrow <= ((b xor c) and (not a)) or (b and c); end data;
波形
多路複用器的VHDL程式碼
Library ieee;
use ieee.std_logic_1164.all;
entity mux is
port(S1,S0,D0,D1,D2,D3:in bit; Y:out bit);
end mux;
architecture data of mux is
begin
Y<= (not S0 and not S1 and D0) or
(S0 and not S1 and D1) or
(not S0 and S1 and D2) or
(S0 and S1 and D3);
end data;
波形
多路分解器的VHDL程式碼
Library ieee; use ieee.std_logic_1164.all; entity demux is port(S1,S0,D:in bit; Y0,Y1,Y2,Y3:out bit); end demux; architecture data of demux is begin Y0<= ((Not S0) and (Not S1) and D); Y1<= ((Not S0) and S1 and D); Y2<= (S0 and (Not S1) and D); Y3<= (S0 and S1 and D); end data;
波形
8 x 3編碼器的VHDL程式碼
library ieee; use ieee.std_logic_1164.all; entity enc is port(i0,i1,i2,i3,i4,i5,i6,i7:in bit; o0,o1,o2: out bit); end enc; architecture vcgandhi of enc is begin o0<=i4 or i5 or i6 or i7; o1<=i2 or i3 or i6 or i7; o2<=i1 or i3 or i5 or i7; end vcgandhi;
波形
3 x 8譯碼器的VHDL程式碼
library ieee; use ieee.std_logic_1164.all; entity dec is port(i0,i1,i2:in bit; o0,o1,o2,o3,o4,o5,o6,o7: out bit); end dec; architecture vcgandhi of dec is begin o0<=(not i0) and (not i1) and (not i2); o1<=(not i0) and (not i1) and i2; o2<=(not i0) and i1 and (not i2); o3<=(not i0) and i1 and i2; o4<=i0 and (not i1) and (not i2); o5<=i0 and (not i1) and i2; o6<=i0 and i1 and (not i2); o7<=i0 and i1 and i2; end vcgandhi;
波形
4位並行加法的VHDL程式碼
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity pa is
port(a : in STD_LOGIC_VECTOR(3 downto 0);
b : in STD_LOGIC_VECTOR(3 downto 0);
ca : out STD_LOGIC;
sum : out STD_LOGIC_VECTOR(3 downto 0)
);
end pa;
architecture vcgandhi of pa is
Component fa is
port (a : in STD_LOGIC;
b : in STD_LOGIC;
c : in STD_LOGIC;
sum : out STD_LOGIC;
ca : out STD_LOGIC
);
end component;
signal s : std_logic_vector (2 downto 0);
signal temp: std_logic;
begin
temp<='0';
u0 : fa port map (a(0),b(0),temp,sum(0),s(0));
u1 : fa port map (a(1),b(1),s(0),sum(1),s(1));
u2 : fa port map (a(2),b(2),s(1),sum(2),s(2));
ue : fa port map (a(3),b(3),s(2),sum(3),ca);
end vcgandhi;
波形
4位奇偶校驗器的VHDL程式碼
library ieee;
use ieee.std_logic_1164.all;
entity parity_checker is
port (a0,a1,a2,a3 : in std_logic;
p : out std_logic);
end parity_checker;
architecture vcgandhi of parity_checker is
begin
p <= (((a0 xor a1) xor a2) xor a3);
end vcgandhi;
波形
4位奇偶校驗生成器的VHDL程式碼
library ieee;
use ieee.std_logic_1164.all;
entity paritygen is
port (a0, a1, a2, a3: in std_logic; p_odd, p_even: out std_logic);
end paritygen;
architecture vcgandhi of paritygen is
begin
process (a0, a1, a2, a3)
if (a0 ='0' and a1 ='0' and a2 ='0' and a3 =’0’)
then odd_out <= "0";
even_out <= "0";
else
p_odd <= (((a0 xor a1) xor a2) xor a3);
p_even <= not(((a0 xor a1) xor a2) xor a3);
end vcgandhi
波形
順序電路的VHDL程式設計
本章解釋如何進行順序電路的VHDL程式設計。
SR鎖存器的VHDL程式碼
library ieee; use ieee.std_logic_1164.all; entity srl is port(r,s:in bit; q,qbar:buffer bit); end srl; architecture virat of srl is signal s1,r1:bit; begin q<= s nand qbar; qbar<= r nand q; end virat;
波形
D鎖存器的VHDL程式碼
library ieee; use ieee.std_logic_1164.all; entity Dl is port(d:in bit; q,qbar:buffer bit); end Dl; architecture virat of Dl is signal s1,r1:bit; begin q<= d nand qbar; qbar<= d nand q; end virat;
波形
SR觸發器的VHDL程式碼
library ieee; use ieee.std_logic_1164.all; entity srflip is port(r,s,clk:in bit; q,qbar:buffer bit); end srflip; architecture virat of srflip is signal s1,r1:bit; begin s1<=s nand clk; r1<=r nand clk; q<= s1 nand qbar; qbar<= r1 nand q; end virat;
波形
JK觸發器的VHDL程式碼
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity jk is
port(
j : in STD_LOGIC;
k : in STD_LOGIC;
clk : in STD_LOGIC;
reset : in STD_LOGIC;
q : out STD_LOGIC;
qb : out STD_LOGIC
);
end jk;
architecture virat of jk is
begin
jkff : process (j,k,clk,reset) is
variable m : std_logic := '0';
begin
if (reset = '1') then
m : = '0';
elsif (rising_edge (clk)) then
if (j/ = k) then
m : = j;
elsif (j = '1' and k = '1') then
m : = not m;
end if;
end if;
q <= m;
qb <= not m;
end process jkff;
end virat;
波形
D觸發器的VHDL程式碼
Library ieee; use ieee.std_logic_1164.all; entity dflip is port(d,clk:in bit; q,qbar:buffer bit); end dflip; architecture virat of dflip is signal d1,d2:bit; begin d1<=d nand clk; d2<=(not d) nand clk; q<= d1 nand qbar; qbar<= d2 nand q; end virat;
波形
T觸發器的VHDL程式碼
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity Toggle_flip_flop is
port(
t : in STD_LOGIC;
clk : in STD_LOGIC;
reset : in STD_LOGIC;
dout : out STD_LOGIC
);
end Toggle_flip_flop;
architecture virat of Toggle_flip_flop is
begin
tff : process (t,clk,reset) is
variable m : std_logic : = '0';
begin
if (reset = '1') then
m : = '0';
elsif (rising_edge (clk)) then
if (t = '1') then
m : = not m;
end if;
end if;
dout < = m;
end process tff;
end virat;
波形
4位向上計數器的VHDL程式碼
library IEEE;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity counter is
port(Clock, CLR : in std_logic;
Q : out std_logic_vector(3 downto 0)
);
end counter;
architecture virat of counter is
signal tmp: std_logic_vector(3 downto 0);
begin
process (Clock, CLR)
begin
if (CLR = '1') then
tmp < = "0000";
elsif (Clock'event and Clock = '1') then
mp <= tmp + 1;
end if;
end process;
Q <= tmp;
end virat;
波形
4位向下計數器的VHDL程式碼
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity dcounter is
port(Clock, CLR : in std_logic;
Q : out std_logic_vector(3 downto 0));
end dcounter;
architecture virat of dcounter is
signal tmp: std_logic_vector(3 downto 0);
begin
process (Clock, CLR)
begin
if (CLR = '1') then
tmp <= "1111";
elsif (Clock'event and Clock = '1') then
tmp <= tmp - 1;
end if;
end process;
Q <= tmp;
end virat;
波形
VLSI設計 - Verilog介紹
Verilog是一種硬體描述語言(HDL)。它是一種用於描述數字系統(如網路交換機、微處理器、儲存器或觸發器)的語言。這意味著,使用HDL,我們可以描述任何級別的數字硬體。用HDL描述的設計與技術無關,非常易於設計和除錯,通常比原理圖更有用,特別是對於大型電路。
Verilog支援多個抽象級別的設計。主要三個是:
- 行為級
- 暫存器傳輸級
- 門級
行為級
此級別使用併發演算法(行為)來描述系統。每個演算法都是順序的,這意味著它由一組依次執行的指令組成。函式、任務和塊是主要元素。不考慮設計的結構實現。
暫存器傳輸級
使用暫存器傳輸級進行設計,使用操作和暫存器之間的資料傳輸來指定電路的特性。現代RTL程式碼的定義是“任何可綜合的程式碼都稱為RTL程式碼”。
門級
在邏輯級別內,系統的特性由邏輯連結及其定時屬性來描述。所有訊號都是離散訊號。它們只能具有確定的邏輯值(`0`、`1`、`X`、`Z`)。可用的操作是預定義的邏輯原語(基本門)。門級建模可能不是邏輯設計的正確方法。門級程式碼是使用諸如綜合工具之類的工具生成的,其網表用於門級模擬和後端。
詞法標記
Verilog語言源文字檔案是詞法標記流。標記由一個或多個字元組成,每個字元都恰好在一個標記中。
Verilog HDL使用的基本詞法標記類似於C程式語言中的標記。Verilog區分大小寫。所有關鍵字都小寫。
空白
空白可以包含空格、製表符、換行符和換頁符。除了用於分隔標記外,這些字元都被忽略。
空白字元是空格、製表符、回車符、換行符和換頁符。
註釋
有兩種形式可以表示註釋
- 1) 單行註釋以標記 // 開頭,以回車符結尾。
例://這是單行語法
- 2) 多行註釋以標記 /* 開頭,以標記 */ 結尾。
例:/* 這是多行語法 */
數字
您可以使用二進位制、八進位制、十進位制或十六進位制格式指定數字。負數用二進位制補碼錶示。Verilog允許整數、實數以及帶符號和無符號數。
語法如下:<size> <radix> <value>
大小或無大小的數字可以在 <Size> 中定義,<radix> 定義它是二進位制、八進位制、十六進位制還是十進位制。
識別符號
識別符號是用於定義物件的名稱,例如函式、模組或暫存器。識別符號應以字母字元或下劃線字元開頭。例:A_Z、a_z、_
識別符號是字母、數字、下劃線和 $ 字元的組合。它們最多可以有 1024 個字元。
運算子
運算子是用於設定條件或操作變數的特殊字元。有時會使用一個、兩個或三個字元來對變數執行操作。
例:>、+、~、&! =。
Verilog關鍵字
在Verilog中具有特殊含義的詞稱為Verilog關鍵字。例如,assign、case、while、wire、reg、and、or、nand和module。它們不應用作識別符號。Verilog關鍵字還包括編譯器指令以及系統任務和函式。
門級建模
Verilog具有內建的原語,如邏輯閘、傳輸門和開關。這些很少用於設計工作,但它們在綜合後用於ASIC/FPGA單元的建模。
門級建模具有兩個屬性:
驅動強度 − 輸出門的強度由驅動強度定義。如果與源直接連線,則輸出最強。如果連線是透過導電電晶體,則強度降低;如果透過上拉/下拉電阻連線,則強度最低。通常不指定驅動強度,在這種情況下,強度預設為strong1和strong0。
延遲 − 如果未指定延遲,則門沒有傳播延遲;如果指定兩個延遲,則第一個表示上升延遲,第二個表示下降延遲;如果只指定一個延遲,則上升和下降都相等。在綜合中可以忽略延遲。
門原語
Verilog中使用具有一個輸出和多個輸入的基本邏輯閘。GATE使用一個關鍵字 - and、nand、or、nor、xor、xnor 在Verilog中用於N個輸入和1個輸出。
Example: Module gate() Wire ot0; Wire ot1; Wire ot2; Reg in0,in1,in2,in3; Not U1(ot0,in0); Xor U2(ot1,in1,in2,in3); And U3(ot2, in2,in3,in0)
傳輸門原語
傳輸門原語包括緩衝器和反相器。它們具有單個輸入和一個或多個輸出。在下面顯示的門例化語法中,GATE代表關鍵字buf或NOT門。
示例:Not、buf、bufif0、bufif1、notif0、notif1
Not – n輸出反相器
Buf – n輸出緩衝器
Bufifo – 三態緩衝器,低電平使能
Bufif1 – 三態緩衝器,高電平使能
Notifo – 三態反相器,低電平使能
Notif1 – 三態反相器,高電平使能
Example: Module gate() Wire out0; Wire out1; Reg in0,in1; Not U1(out0,in0); Buf U2(out0,in0);
資料型別
值集合
Verilog 主要由四個基本值構成。Verilog 中使用的所有資料型別都儲存這些值:
0(邏輯零,或假條件)
1(邏輯一,或真條件)
x(未知邏輯值)
z(高阻態)
x 和 z 的使用在綜合中非常有限。
線網 (Wire)
線網用於表示電路中的物理線,用於連線門或模組。線網的值只能讀取,不能在函式或塊中賦值。線網不能儲存值,始終由連續賦值語句或將線網連線到門/模組的輸出驅動。其他特定型別的線網包括:
Wand(線與) – Wand 的值取決於連線到它的所有器件驅動器的邏輯與。
Wor(線或) – Wor 的值取決於連線到它的所有器件驅動器的邏輯或。
Tri(三態) – 連線到 tri 的所有驅動器都必須為 z,只有一個例外(決定 tri 的值)。
Example: Wire [msb:lsb] wire_variable_list; Wirec // simple wire Wand d; Assign d = a; // value of d is the logical AND of Assign d = b; // a and b Wire [9:0] A; // a cable (vector) of 10 wires. Wand [msb:lsb] wand_variable_list; Wor [msb:lsb] wor_variable_list; Tri [msb:lsb] tri_variable_list;
暫存器 (Register)
reg(暫存器)是一個數據物件,它儲存從一個過程賦值到下一個過程賦值的值,僅用於不同的函式和過程塊。reg 是一個簡單的 Verilog 變數型別暫存器,不能表示物理暫存器。在多位暫存器中,資料以無符號數的形式儲存,不使用符號擴充套件。
示例:
reg c; // 單個 1 位暫存器變數
reg [5:0] gem; // 一個 6 位向量;
reg [6:0] d, e; // 兩個 7 位變數
輸入 (Input)、輸出 (Output)、雙向口 (Inout)
這些關鍵字用於宣告任務或模組的輸入、輸出和雙向埠。這裡的輸入和雙向埠是線網型別,輸出埠配置為線網、暫存器、Wand、Wor 或 Tri 型別。預設型別始終為線網型別。
示例
Module sample(a, c, b, d); Input c; // An input where wire is used. Output a, b; // Two outputs where wire is used. Output [2:0] d; /* A three-bit output. One must declare type in a separate statement. */ reg [1:0] a; // The above ‘a’ port is for declaration in reg.
整型 (Integer)
整型用於通用變數。主要用於迴圈索引、常量和引數。它們是“reg”型別的資料型別。它們將資料儲存為有符號數,而顯式宣告的 reg 型別則將其儲存為無符號資料。如果在編譯時未定義整型,則預設大小為 32 位。
如果整型包含常量,則綜合器會在編譯時將其調整為所需的最小寬度。
示例
Integer c; // single 32-bit integer Assign a = 63; // 63 defaults to a 7-bit variable.
Supply0,Supply1
Supply0 定義連線到邏輯 0(地)的線網,Supply1 定義連線到邏輯 1(電源)的線網。
示例
supply0 logic_0_wires; supply0 gnd1; // equivalent to a wire assigned as 0 supply1 logic_1_wires; supply1 c, s;
時間 (Time)
Time 是一個 64 位的量,可以與 $time 系統任務一起使用以儲存模擬時間。Time 不支援綜合,因此僅用於模擬。
示例
time time_variable_list; time c; c = $time; //c = current simulation time
引數 (Parameter)
引數定義了一個常量,可以在使用模組時設定,允許在例項化過程中自定義模組。
Example
Parameter add = 3’b010, sub = 2’b11;
Parameter n = 3;
Parameter [2:0] param2 = 3’b110;
reg [n-1:0] jam; /* A 3-bit register with length of n or above. */
always @(z)
y = {{(add - sub){z}};
if (z)
begin
state = param2[1];
else
state = param2[2];
end
運算子
算術運算子
這些運算子執行算術運算。+ 和 - 可用作一元 (x) 或二元 (z-y) 運算子。
算術運算中包含的運算子有:
+(加法),-(減法),*(乘法),/(除法),%(模)
示例:
parameter v = 5; reg[3:0] b, d, h, i, count; h = b + d; i = d - v; cnt = (cnt +1)%16; //Can count 0 thru 15.
關係運算符
這些運算子比較兩個運算元,並將結果返回為一位,1 或 0。
線網和暫存器變數為正。因此,(-3'd001) == 3'd111 和 (-3b001) > 3b110。
關係運算中包含的運算子有:
- ==(等於)
- !=(不等於)
- >(大於)
- >=(大於或等於)
- <(小於)
- <=(小於或等於)
示例
if (z = = y) c = 1; else c = 0; // Compare in 2’s compliment; d>b reg [3:0] d,b; if (d[3]= = b[3]) d[2:0] > b[2:0]; else b[3]; Equivalent Statement e = (z == y);
位運算子
位運算子對兩個運算元進行逐位比較。
位運算中包含的運算子有:
- &(按位與)
- |(按位或)
- ~(按位非)
- ^(按位異或)
- ~^ 或 ^~(按位異或非)
示例
module and2 (d, b, c); input [1:0] d, b; output [1:0] c; assign c = d & b; end module
邏輯運算子
邏輯運算子是位運算子,僅用於單位元運算元。它們返回一位值,0 或 1。它們可以作用於整數或位組、表示式,並將所有非零值視為 1。邏輯運算子通常用於條件語句,因為它們與表示式一起使用。
邏輯運算中包含的運算子有:
- !(邏輯非)
- &&(邏輯與)
- ||(邏輯或)
示例
wire[7:0] a, b, c; // a, b and c are multibit variables. reg x; if ((a == b) && (c)) x = 1; //x = 1 if a equals b, and c is nonzero. else x = !a; // x =0 if a is anything but zero.
歸約運算子
歸約運算子是位運算子的一元形式,作用於運算元向量的所有位。它們也返回一位值。
歸約運算中包含的運算子有:
- &(歸約與)
- |(歸約或)
- ~&(歸約與非)
- ~|(歸約或非)
- ^(歸約異或)
- ~^ 或 ^~(歸約異或非)
示例
Module chk_zero (x, z); Input [2:0] x; Output z; Assign z = & x; // Reduction AND End module
移位運算子
移位運算子根據語法中第二個運算元指定的位數來移動第一個運算元。對於左移和右移,空位都填充零(不使用符號擴充套件)。
移位運算中包含的運算子有:
- <<(左移)
- >>(右移)
示例
Assign z = c << 3; /* z = c shifted left 3 bits;
空位填充 0
連線運算子
連線運算子組合兩個或多個運算元以形成更大的向量。
連線運算中包含的運算子有:{ }(連線)
示例
wire [1:0] a, h; wire [2:0] x; wire [3;0] y, Z;
assign x = {1’b0, a}; // x[2] = 0, x[1] = a[1], x[0] = a[0]
assign b = {a, h}; /* b[3] = a[1], b[2] = a[0], b[1] = h[1],
b[0] = h[0] */
assign {cout, b} = x + Z; // Concatenation of a result
複製運算子
複製運算子建立專案的多個副本。
複製運算中使用的運算子有:{n{item}}(專案的 n 倍複製)
示例
Wire [1:0] a, f; wire [4:0] x;
Assign x = {2{1’f0}, a}; // Equivalent to x = {0,0,a }
Assign y = {2{a}, 3{f}}; //Equivalent to y = {a,a,f,f}
For synthesis, Synopsis did not like a zero replication.
For example:-
Parameter l = 5, k = 5;
Assign x = {(l-k){a}}
條件運算子
條件運算子綜合成多路複用器。它與 C/C++ 中使用的一樣,根據條件計算兩個表示式中的一個。
條件運算中使用的運算子有:
(條件) ? (條件為真時的結果) :
(條件為假時的結果)
示例
Assign x = (g) ? a : b; Assign x = (inc = = 2) ? x+1 : x-1; /* if (inc), x = x+1, else x = x-1 */
運算元
字面量
字面量是在 Verilog 表示式中使用的常量值運算元。兩個常用的 Verilog 字面量是:
字串 – 字串字面量運算元是由雙引號 (" ") 括起來的字元的一維陣列。
數值 – 常數運算元以二進位制、八進位制、十進位制或十六進位制表示。
示例
n – 表示位數的整數
F – 四種可能的基格式之一:
b 表示二進位制,o 表示八進位制,d 表示十進位制,h 表示十六進位制。
“time is” // string literal 267 // 32-bit decimal number 2’b01 // 2-bit binary 20’hB36F // 20-bit hexadecimal number ‘062 // 32-bit octal number
線網、暫存器和引數
線網、暫存器和引數是在 Verilog 表示式中用作運算元的資料型別。
位選擇“x[2]”和部分選擇“x[4:2]”
位選擇和部分選擇分別用於使用方括號“[ ]”從線網、暫存器或引數向量中選擇一位和多位。位選擇和部分選擇也以與它們的主要資料物件相同的方式用作表示式中的運算元。
示例
reg [7:0] x, y; reg [3:0] z; reg a; a = x[7] & y[7]; // bit-selects z = x[7:4] + y[3:0]; // part-selects
函式呼叫
在函式呼叫中,函式的返回值直接在表示式中使用,無需先將其賦值給暫存器或線網。只需將函式呼叫作為一種運算元型別即可。需要注意函式呼叫返回值的位寬。
Example Assign x = y & z & chk_yz(z, y); // chk_yz is a function . . ./* Definition of the function */ Function chk_yz; // function definition Input z,y; chk_yz = y^z; End function
模組
模組宣告
在 Verilog 中,模組是主要的設計實體。它指示名稱和埠列表(引數)。接下來幾行指定每個埠的輸入/輸出型別(輸入、輸出或雙向)和寬度。預設埠寬度僅為 1 位。埠變數必須透過 wire、wand……、reg 宣告。預設埠變數為 wire。通常,輸入是 wire,因為它們的資料在模組外部鎖存。如果輸出訊號儲存在內部,則輸出為 reg 型別。
示例
module sub_add(add, in1, in2, out); input add; // defaults to wire input [7:0] in1, in2; wire in1, in2; output [7:0] out; reg out; ... statements ... End module
連續賦值
模組中的連續賦值用於將值賦給線網,這是在 always 或 initial 塊之外使用的常規賦值。此賦值透過顯式賦值語句完成,或在宣告線網時為其賦值。連續賦值在模擬時連續執行。賦值語句的順序不影響它。如果更改任何右側輸入訊號,它將更改左側輸出訊號。
示例
Wire [1:0] x = 2’y01; // assigned on declaration Assign y = c | d; // using assign statement Assign d = a & b; /* the order of the assign statements does not matter. */
模組例項化
模組宣告是建立實際物件的模板。模組在其他模組內例項化,每個例項化都從該模板建立一個物件。例外是頂層模組,它是它自己的例項化。模組的埠必須與模板中定義的埠匹配。它指定:
按名稱,使用點“.模板埠名(連線到埠的線網名稱)”。或者
按位置,將埠放在模板和例項的埠列表中的相同位置。
示例
MODULE DEFINITION Module and4 (x, y, z); Input [3:0] x, y; Output [3:0] z; Assign z = x | y; End module
Verilog中的行為建模和時序
Verilog 中的行為模型包含過程語句,這些語句控制模擬並操作資料型別的變數。所有這些語句都包含在過程中。每個過程都與一個活動流相關聯。
在行為模型的模擬過程中,由“always”和“initial”語句定義的所有流程都從模擬時間“零”開始。initial 語句執行一次,always 語句重複執行。在這個模型中,暫存器變數 a 和 b 分別在模擬時間“零”初始化為二進位制 1 和 0。然後 initial 語句完成,並且在該模擬執行期間不再執行。此 initial 語句包含一個 begin-end 塊(也稱為順序塊)語句。在此 begin-end 型別塊中,a 首先初始化,然後是 b。
行為建模示例
module behave; reg [1:0]a,b; initial begin a = ’b1; b = ’b0; end always begin #50 a = ~a; end always begin #100 b = ~b; end End module
過程賦值
過程賦值用於更新 reg、integer、time 和 memory 變數。如下所述,過程賦值與連續賦值之間存在顯著差異:
連續賦值驅動 net 變數,並在輸入運算元的值發生變化時進行評估和更新。
過程賦值在圍繞它們的程式流程結構的控制下更新暫存器變數的值。
過程賦值的右側可以是任何計算結果為值的表示式。但是,右側的部分選擇必須具有常量索引。左側指示從右側接收賦值的變數。過程賦值的左側可以採用以下形式之一:
暫存器、整數、實數或時間變數 – 對這些資料型別之一的名稱引用的賦值。
暫存器、整數、實數或時間變數的位選擇 – 對單個位的賦值,同時保持其他位不變。
暫存器、整數、實數或時間變數的部分選擇 – 對兩個或多個連續位的部分選擇,同時保持其餘位不變。對於部分選擇形式,只有常量表達式是合法的。
儲存器單元 – 儲存器的一個字。請注意,在儲存器單元引用上不允許使用位選擇和部分選擇。
上述任何形式的連線 – 可以指定上述四種形式的任何形式的連線,這有效地將右側表示式的結果進行分割槽,並按順序將分割槽部分分配給連線的各個部分。
賦值延遲(不適用於綜合)
在延遲賦值中,語句執行和左側賦值之前會經過 Δt 個時間單位。使用賦值內延遲,右側立即計算,但在結果放入左側賦值之前會延遲 Δt。如果另一個過程在 Δt 期間更改右側訊號,則不會影響輸出。綜合工具不支援延遲。
語法
過程賦值變數 = 表示式
延遲賦值#Δt 變數 = 表示式;
賦值內延遲變數 = #Δt 表示式;
示例
reg [6:0] sum; reg h, ziltch; sum[7] = b[7] ^ c[7]; // execute now. ziltch = #15 ckz&h; /* ckz&a evaluated now; ziltch changed after 15 time units. */ #10 hat = b&c; /* 10 units after ziltch changes, b&c is evaluated and hat changes. */
阻塞賦值
阻塞過程賦值語句必須在其順序塊中後續語句執行之前執行。阻塞過程賦值語句不會阻止其在並行塊中後續語句的執行。
語法
阻塞過程賦值的語法如下:
<lvalue> = <timing_control> <expression>
其中,lvalue 是過程賦值語句中有效的 資料型別,= 是賦值運算子,timing control 是可選的賦值內延遲。timing control 延遲可以是延遲控制(例如,#6)或事件控制(例如,@(posedge clk))。表示式是模擬器賦值給左值的右側值。阻塞過程賦值使用的 = 賦值運算子也用於過程連續賦值和連續賦值。
示例
rega = 0;
rega[3] = 1; // a bit-select
rega[3:5] = 7; // a part-select
mema[address] = 8’hff; // assignment to a memory element
{carry, acc} = rega + regb; // a concatenation
非阻塞(RTL)賦值
非阻塞過程賦值允許您安排賦值,而不會阻塞過程流程。您可以隨時使用非阻塞過程語句,在同一時間步內進行多個暫存器賦值,而無需考慮順序或相互依賴。
語法
非阻塞過程賦值的語法如下:
<lvalue> <= <timing_control> <expression>
其中,lvalue 是過程賦值語句中有效的 資料型別,<=是非阻塞賦值運算子,timing control 是可選的賦值內 timing control。timing control 延遲可以是延遲控制或事件控制(例如,@(posedge clk))。表示式是模擬器賦值給左值的右側值。非阻塞賦值運算子與模擬器用於小於或等於關係運算符的運算子相同。當您在表示式中使用 <= 運算子時,模擬器將其解釋為關係運算符;當您在非阻塞過程賦值結構中使用它時,模擬器將其解釋為賦值運算子。
模擬器如何評估非阻塞過程賦值 當模擬器遇到非阻塞過程賦值時,模擬器將分兩個步驟評估並執行非阻塞過程賦值:
模擬器評估右側並安排將新值賦值的時間,該時間由過程 timing control 指定。模擬器評估右側並安排將新值賦值的時間,該時間由過程 timing control 指定。
在給定延遲過期或發生適當事件的時間步長結束時,模擬器透過將值賦給左側來執行賦值。
示例
module evaluates2(out); output out; reg a, b, c; initial begin a = 0; b = 1; c = 0; end always c = #5 ~c; always @(posedge c) begin a <= b; b <= a; end endmodule
條件語句
條件語句(或 if-else 語句)用於決定是否執行語句。
形式上,語法如下:
<statement> ::= if ( <expression> ) <statement_or_null> ||= if ( <expression> ) <statement_or_null> else <statement_or_null> <statement_or_null> ::= <statement> ||= ;
對
例如,以下兩個語句表達相同的邏輯:
if (expression) if (expression != 0)
由於 if-else 的 else 部分是可選的,因此當從巢狀 if 序列中省略 else 時可能會產生混淆。這透過始終將 else 與缺少 else 的最近的先前 if 關聯來解決。
示例
if (index > 0) if (rega > regb) result = rega; else // else applies to preceding if result = regb; If that association is not what you want, use a begin-end block statement to force the proper association if (index > 0) begin if (rega > regb) result = rega; end else result = regb;
if-else-if 結構
以下結構經常出現,值得單獨簡要討論。
示例
if (<expression>) <statement> else if (<expression>) <statement> else if (<expression>) <statement> else <statement>
這個 if 序列(稱為 if-else-if 結構)是編寫多路決策的最通用方法。表示式按順序求值;如果任何表示式為真,則執行與其關聯的語句,這將終止整個鏈。每個語句要麼是單個語句,要麼是語句塊。
if-else-if 結構的最後一個 else 部分處理“以上都不是”或預設情況,其中沒有滿足其他條件。有時沒有預設情況的明確操作;在這種情況下,可以省略尾隨 else,也可以將其用於錯誤檢查以捕獲不可能的條件。
case 語句
case 語句是一種特殊的多分支決策語句,它測試表達式是否與多個其他表示式之一匹配,並據此分支。case 語句用於描述例如微處理器指令的解碼。case 語句具有以下語法:
示例
<statement> ::= case ( <expression> ) <case_item>+ endcase ||= casez ( <expression> ) <case_item>+ endcase ||= casex ( <expression> ) <case_item>+ endcase <case_item> ::= <expression> <,<expression>>* : <statement_or_null> ||= default : <statement_or_null> ||= default <statement_or_null>
case 表示式按其給出的確切順序進行評估和比較。線上性搜尋期間,如果 case 專案表達式之一與括號中的表示式匹配,則執行與該 case 專案關聯的語句。如果所有比較都失敗,並且給出了 default 專案,則執行 default 專案語句。如果未給出 default 語句,並且所有比較都失敗,則不執行任何 case 專案語句。
除了語法之外,case 語句與多分支 if-else-if 結構在兩個重要方面有所不同:
if-else-if 結構中的條件表示式比將一個表示式與其他幾個表示式進行比較更通用,就像在 case 語句中一樣。
當表示式中存在 x 和 z 值時,case 語句提供確定的結果。
迴圈語句
有四種類型的迴圈語句。它們提供了一種控制語句執行零次、一次或多次的方法。
forever 連續執行語句。
repeat 執行語句固定次數。
while 執行語句,直到表示式變為假。如果表示式一開始為假,則根本不執行語句。
for 透過以下三步過程控制其關聯語句的執行:
執行通常用於初始化控制執行迴圈次數的變數的賦值
評估表示式——如果結果為零,則 for 迴圈退出,如果結果不為零,則 for 迴圈執行其關聯語句,然後執行步驟 3
執行通常用於修改迴圈控制變數值的賦值,然後重複步驟 2
迴圈語句的語法規則如下:
示例
<statement> ::= forever <statement> ||=forever begin <statement>+ end <Statement> ::= repeat ( <expression> ) <statement> ||=repeat ( <expression> ) begin <statement>+ end <statement> ::= while ( <expression> ) <statement> ||=while ( <expression> ) begin <statement>+ end <statement> ::= for ( <assignment> ; <expression> ; <assignment> ) <statement> ||=for ( <assignment> ; <expression> ; <assignment> ) begin <statement>+ end
延遲控制
延遲控制
可以使用以下語法對過程語句的執行進行延遲控制:
<statement> ::= <delay_control> <statement_or_null> <delay_control> ::= # <NUMBER> ||= # <identifier> ||= # ( <mintypmax_expression> )
以下示例將賦值的執行延遲 10 個時間單位:
#10 rega = regb;
接下來的三個示例在數字符號 (#) 後提供表示式。賦值的執行將延遲表示式值指定模擬時間量。
事件控制
可以使用以下事件控制語法將過程語句的執行與網路或暫存器上的值變化或已宣告事件的發生同步:
示例
<statement> ::= <event_control> <statement_or_null> <event_control> ::= @ <identifier> ||= @ ( <event_expression> ) <event_expression> ::= <expression> ||= posedge <SCALAR_EVENT_EXPRESSION> ||= negedge <SCALAR_EVENT_EXPRESSION> ||= <event_expression> <or <event_expression>>
*
網路和暫存器上的值變化可用作觸發語句執行的事件。這稱為檢測隱式事件。Verilog 語法還允許您根據更改的方向檢測更改——即朝向值 1 (posedge) 或朝向值 0 (negedge)。posedge 和 negedge 對未知表示式值的處理方式如下:
- 從 1 到未知以及從未知到 0 的轉換會檢測到 negedge
- 從 0 到未知以及從未知到 1 的轉換會檢測到 posedge
過程:always 和 initial 塊
Verilog 中的所有過程都在以下四個塊之一中指定。1) initial 塊 2) always 塊 3) 任務 4) 函式
initial 和 always 語句在模擬開始時啟用。initial 塊只執行一次,並且當語句完成時其活動結束。相反,always 塊重複執行。其活動僅在模擬終止時結束。在一個模組中可以定義的 initial 和 always 塊的數量沒有限制。任務和函式是從其他過程中的一個或多個位置啟用的過程。
initial 塊
initial 語句的語法如下:
<initial_statement> ::= initial <statement>
以下示例說明了在模擬開始時使用 initial 語句初始化變數。
Initial Begin Areg = 0; // initialize a register For (index = 0; index < size; index = index + 1) Memory [index] = 0; //initialize a memory Word End
initial 塊的另一個典型用法是指定一次執行以向被類比電路的主要部分提供激勵的波形描述。
Initial Begin Inputs = ’b000000; // initialize at time zero #10 inputs = ’b011001; // first pattern #10 inputs = ’b011011; // second pattern #10 inputs = ’b011000; // third pattern #10 inputs = ’b001000; // last pattern End
always 塊
“always”語句在整個模擬執行過程中持續重複。always 語句的語法如下所示
<always_statement> ::= always <statement>
由於“always”語句的迴圈性質,它只有與某種形式的 timing control 結合使用時才有用。如果“always”語句不提供時間推進的方法,“always”語句會建立模擬死鎖條件。例如,以下程式碼會建立一個無限的零延遲迴圈:
Always areg = ~areg;
為上述程式碼提供 timing control 可以建立一個可能有用的描述——如下例所示:
Always #half_period areg = ~areg;