數字設計
一、關於組合邏輯
競爭冒險:一個邏輯門的多個輸入信號同時跳變(路徑時延不同,使得狀態改變的時刻有先有后)。這種現象叫做競爭,引起的結果稱為冒險。
消除毛刺(冒險):(1)增加冗余項;(2)加濾波電容;(3)加選通信號;
注:在平常實踐中,可以使用如下小細節:(1)輸出加D觸發器;(2)使用格雷碼;
注意理解組合邏輯與時序邏輯的差別。
二、關於時序邏輯
1. 時鍾基礎
1.1 常見時鍾類型
(1)全局時鍾;
(2)內部邏輯時鍾,即組合邏輯和計數器分頻產生的時鍾。對於前者,一般禁止使用,對於后者,也應盡量少使用(用PLL、DLL、DCM替代);
(3)門控時鍾;(一般在組合邏輯中使用,且驅動門控時鍾的邏輯都是只包含一個與門/或門,盡量避免使用,除非要求被使用以降低系統功耗)
推薦的門控時鍾電路:
(拓展)使能時鍾:主要是用於時序邏輯中,比門控時鍾要來的穩定。
1.2 時鍾抖動
芯片的某一個給定點上時鍾周期發生暫時性變化,也就是說時鍾周期在不同的周期上可能加長或縮短。它是一個平均值為0的平均變量。
1.3 Xilinx中與全局時鍾資源和 DLL相關的硬件原語
IBUFG,IBUFGDS,BUFG,BUFGP,BUFGCE,BUFGMUX,BUFGDLL,DCM等。
1.4 同步電路設計
概念:所有電路均在同一時鍾的上升沿或者下降沿觸發下同步地工作。(多時鍾應被視為同步電路概念的延伸,這個時候應盡量做到局部同步)
設計准則:
(1)盡可能使用統一時鍾,並走全局時鍾網絡;
(2)避免使用混合時鍾沿采樣數據(即同時使用上升沿和下降沿);
(3)盡量少使用分頻器產生的時鍾;
(4)避免使用門控時鍾;
(5)當需要多個時鍾時,盡量使局部同步(分成多個模塊,每個模塊一個時鍾);
個人總結:
同步邏輯和異步邏輯的概念應該都屬於同步電路的范疇,它們都是由時鍾來控制電路狀態的跳變,只不過前者是有統一的時鍾或時鍾之間有固定的因果關系,后者則相反。
同步電路和異步電路的區別是:同步電路利用時鍾脈沖使其子系統同步工作,而異步電路不依賴時鍾,其邏輯輸出和任何時鍾信號都沒關系,主要是組合邏輯電路。
1.5 FPGA設計中如何實現同步時序電路的延時
小延時:寄存器打一拍或幾拍;
大延時:利用高速時鍾產生計數器,用計數器控制延時;
2. 寄存器(reg)基礎
(1)reg、wire。
(2)基礎寄存器
(3)帶異步復位的寄存器
(4)帶異步置位的寄存器
(5)既帶異步復位又帶異步置位的寄存器
注:這種情況下,當可能出現set和clr同時有效時,可通過if……else語句設置優先級(比如使異步復位的優先級較高),綜合出的電路為:
(6)帶同步使能的寄存器
3.建立、保持時間及亞穩態
3.1 建立、保持時間
3.2 亞穩態的產生
如果觸發器不滿足建立時間和保持時間,則會進入亞穩態,即:觸發器無法在某個規定的時間段內到達一個可以確認的狀態。
3.3 如何消除
只要系統中有異步元件,亞穩態就是無法避免的,亞穩態主要發生在異步信號檢測、跨時鍾域信號傳輸以及復位電路等常用設計中。針對這幾種應用情況,改善方法如下:
3.3.1 降低系統工作時鍾
3.3.2 用反應更快的觸發器
3.3.3 引入同步機制
(1)對異步信號進行同步處理(加兩級寄存器,即“一位同步器”);
(2)采用FIFO對跨時鍾域數據通信進行緩沖設計;
(3)對復位電路采用異步復位、同步釋放方式處理。
3.3.4 改善時鍾質量,用邊沿變化快速的時鍾信號
三、FPGA構造
1. 整體構造
可配置邏輯塊(查找表+觸發器) + 內部連接線 + 輸入輸出單元。(當然,現在的FPGA都比較復雜,芯片上通常還包含其他豐富的資源)
復雜FPGA:
2.查找表構造和原理
查找表(look-up-table)簡稱為LUT,LUT本質上就是一個RAM。目前FPGA中多使用4輸入的LUT,所以每一個LUT可以看成一個有 4位地址線的16x1的RAM。
當用戶通過原理圖或HDL語言描述了一個邏輯電路以后,PLD/FPGA開發軟件會自動計算邏輯電路的所有可能的結果,並把結果事先寫入RAM,這樣,每輸入一個信號進行邏輯運算就等於輸入一個地址進行查表,找出地址對應的內容,然后輸出即可。
3.存儲資源
3.1 FPGA中有哪兩種存儲器資源
一種叫BLOCK RAM,另一種是由LUT配置成的內部存儲器(也就是分布式RAM)。
注意:BLOCK RAM由一定數量固定大小的存儲塊構成的,使用BLOCK RAM資源不占用額外的邏輯資源,並且速度快。但是使用的時候消耗的BLOCK RAM資源是其塊大小的整數倍。
3.2 FPGA中可以綜合實現為RAM/ROM/CAM的三種資源
BLOCK RAM ,觸發器(FF),查找表(LUT)。
四、RTL設計思想及需要注意的問題
1. 基本描述方式
(1)數據流描述:assign語句,連續賦值語句
(2)行為級描述:always、initial語句,過程賦值語句
(3)結構化描述:實例化功能模塊
2. 阻塞和非阻塞賦值
3. 代碼的可綜合性
行為級描述可基於不同的層次,如系統級、算法級、寄存器傳輸級(RTL級)、門級、開關級。目前的EDA工具只能綜合RTL級以下的描述方式。
4. 能提升系統性能的代碼風格
(1)流水線技術;(用寄存器分割較大的組合邏輯,提高設計頻率)
(2)資源共享;(節省面積)
(3)邏輯復制;(用面積來換取時序性能的改善)
(4)改善關鍵路徑的邏輯等級;
(5)消除組合邏輯的毛刺;
5. 狀態機
5.1 分類——Moore型和Mealy型
Moore狀態機:當前輸出只與當前狀態有關;(a)
Mealy狀態機:當前輸出與當前狀態以及當前輸入有關;(b)
5.2 寫法
推薦使用兩段式(2個always塊)或者三段式(3個always塊)寫法。
(1)兩段式
(2)三段式
總體來說,三段式是最優的狀態機書寫方式:
//第一個進程,同步時序always模塊,格式化描述次態寄存器遷移到現態寄存器 always @ (posedge clk or negedge rst_n) //異步復位 if(!rst_n) current_state <= IDLE; else current_state <= next_state;//注意,使用的是非阻塞賦值 //第二個進程,組合邏輯always模塊,描述狀態轉移條件判斷 always @ (current_state) //電平觸發 begin next_state = x; //要初始化,使得系統復位后能進入正確的狀態 case(current_state) S1: if(...) next_state = S2; //阻塞賦值 ... endcase end //第三個進程,同步時序always模塊,格式化描述次態寄存器輸出 always @ (posedge clk or negedge rst_n) ...//初始化 case(next_state) S1: out1 <= 1'b1; //注意是非阻塞邏輯 S2: out2 <= 1'b1; default:... //default的作用是免除綜合工具綜合出鎖存器。 endcase end //三段式並不是一定要寫為3個always塊,如果狀態機更復雜,就不止3段了。
但是需要注意:
(1)第三段使用next_state和current_state的區別在於,當狀態跳轉時,基於next_state的輸出是立刻變化的,而基於current_state輸出會延遲一個周期,其他情況都一樣,應該根據自己的時序要求,選擇用next_state還是current_state。
(2)兩段式在組合邏輯特別復雜時適用,但要注意需在后面加一個觸發器以消除組合邏輯對輸出產生的毛刺。三段式沒有這個問題,由於第三個always會生成觸發器。
(3)第二個always塊中,組合邏輯電平要維持超過一個clock。
6. 需注意的問題
(1)在always或這initial塊中被賦值的一定是reg型,在assign中被賦值的一定是wire型;
(2)一個變量不能在多個always塊中被賦值;
(3)所有塊和實例化模塊都是並發執行的;
(4)時序邏輯使用非阻塞賦值(<=),組合邏輯使用阻塞賦值(=),且同一個塊中不能混用。always塊電平敏感時使用阻塞賦值;
(5)嚴禁組合邏輯出現反饋環路;
(6)if……else和case語句要完備,並設置default,防止產生latch;
(7)存儲器的定義 reg [3:0] mem [0:7] ,位寬為4,地址0~7;
(8)狀態機編碼最好使用one-hot碼,一個完備的狀態機應該有初始狀態和默認狀態。