時序邏輯電路設計 -...
TRANSCRIPT
時序邏輯電路設計 本章內容豐富可分為下列兩部分
VHDL 部分
認識 Process 敘述
認識 Generic 敘述If-Then-Else 敘述Case-When 敘述及 Loop 敘述
電路設計與模擬部分
應用 VHDL 設計模擬各式正反器
應用 VHDL 設計模擬計數器BCD 加法器與移位暫存器等
FPGA 設計實務
3-2
認識 Process 結構 3-1 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Process 結構是跨入時序邏輯設計的重要介面在電路設計之中除
了共時性敘述外可能還會穿插一個或多個 Process 結構而每個 Process
結構有點像是獨立的零件所以如果不論及 Process 結構內部的敘述
則每個 Process 結構與其它共時性敘述一樣都是同時動作的而 Process
結構的格式如圖 1 所示
圖1 Process 結構之格式示意圖
標籤
在 Process 結構裡可加入標籤以幫助解讀這個電路通常標籤是使
用有意義的文字例如 counter10clock_div 等一看就知道這個 Process
結構提供什麼服務當然在 End Process 右邊的標籤必須與開頭的標
籤一樣才行也可只在開頭放置標籤而結束的地方不放置標籤基
本上標籤可區分電路功能屬於選擇性的文字若整個電路設計之
中只有一個 Procee 結構不放置標籤並無不可
敏感信號列
在 Process 關鍵字右邊括號內為敏感信號列 (Sensitivity List)其中列
出所有可觸動此 Process 動作的信號若超過一個敏感信號則在信
號與信號之間須以逗點分隔Process 結構有點類似微處理器裡的
中斷功能 (Interrupt)並不是隨時都在工作而是在任一個敏感信
號有所變化時才會執行 Processs 內描述的動作
第三章 時序邏輯電路設計
3-3
變數的宣告
在 Process 列與 Begin 列之間可宣告此 Process 所使用的信號及變
數而宣告的格式如下
Variable 變數名稱 1 變數名稱 2hellip 資料型態 [=初值]
變數的宣告與實體區裡的輸出埠宣告類似只是在此並沒有定義
變數的信號方向
描述電路功能
在 Begin 列與 End 列之間為此 Process 主要的部分可利用時序性
語法描述電路的動作而其動作是按描述的順序
If-Then-Else 敘述 3-2 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
If-Then-Else 敘述是一種條件判斷的時序性語法也是在描述電路中
不可或缺的好工具
基本語法格式
If-Then-Else 敘述的基本語法格式如下
If 判斷條件 Then
電路描述 1
Else
電路描述 2
End If
當判斷條件成立時執行電路描述 1不成立時執行電路描述 2
如果省略 Else 的部分便成為不完整的敘述如下
If 判斷條件 Then
電路描述
End If
FPGA 設計實務
3-4
執行這個敘述時若判斷條件成立則執行電路描述但沒有交待
不成立時要做何處置所以要保持原狀
為了不要交待不清可加上「null」也就是什麼也不做的意思
如下
If 判斷條件 Then
電路描述
Else
null
End If
有了 If-Then-Else 敘述整個電路設計就精彩起來了以第 2 章的
加法器 減法器為例我們可設計一個加法器與減法器合併的電路而利
用 ADDSUB 信號做為進行加法運算還是減法運算的開關當
ADDSUB=1時執行加法運算否則執行減法運算如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity ADDSUB is
Port(A Bin std_logic_vector(7 downto 0)
CinADDSUBin std_logic
Coout std_logic
Resultsout std_logic_vector(7 downto 0))
End ADDSUB
Architecture ARCH of ADDSUB is
Begin
Process(ABCinADDSUB)
Variable TMP std_logic_vector(8 downto 0)
Begin
If ADDSUB = 1 Then
TMP = 0 amp A + B + Cin
Else
TMP = 0 amp A - B - Cin
End If
Results lt= TMP(7 downto 0)
第三章 時序邏輯電路設計
3-5
Co lt= TMP(8)
End Process
End ARCH
多重判斷條件
If-Then-Else 敘述也可以使用多重判斷也就是多個判斷條件其語
法格式如下
If 判斷條件 1 Then
電路描述 1
Elsif 判斷條件 2 Then
電路描述 2 Else
電路描述 n
End If
當判斷條件 1 成立時執行電路描述 1若不成立時再看看判斷
條件 2 是否成立若成立時執行電路描述 2若不成立時再看看判
斷條件 3 是否成立以此類推其中原本為「Else If」的關鍵字合
併為「Elsif」而 後一項判斷之後還是為「Else」敘述
巢狀結構敘述
If-Then-Else 敘述支援巢狀結構的敘述也就是 If-Then-Else 敘述之
中有 If-Then-Else 敘述多層次的描述如圖 2 所示
FPGA 設計實務
3-6
圖2 巢狀結構之 If-Then-Else
3-2-1 時脈觸發
時序邏輯電路的動作主要是依時鐘脈波 (簡稱為時脈 )來同步或驅
動必須有效地抓住時脈方能同步或精確驅動如何抓住時脈呢我
們可應用 If-Then-Else 敘述而「抓住時脈」就是時脈觸發如圖 3 所
示分別為正緣觸發時脈與負緣觸發時脈之描述
我們也可以把「clk event and clk= 1」拆開說明clk event 就是偵
測到 clk 信號有變化 (由 1 變成 0 或 0 變成 1)其中「 event」是一種屬
性clk= 1就是 clk 的值變成 1很明顯的就是 0 變成 1也就是時脈
的升緣或正緣另外我們也可以把「 clk event and clk= 1 」改為
「rising_edge(clk)」也就是 clk 的升緣(Rising Edge)更口語化
同樣地我們可很容易地了解「clk event and clk= 0」也可以
「 falling_edge(clk)」代替
第三章 時序邏輯電路設計
3-7
Clk0Process (clk)
Begin
If clk event and clk= 1 Then
End If
End Process
Clk0Process (clk)
Begin
If clk event and clk= 0 Then
End If
End Process
電路動作描述
正緣觸發
電路動作描述
負緣觸發
圖3 時脈之描述
3-2-2 信號與變數徹底研究
在第二章裡曾經提及變數(Variable)只能用於時序性敘述之中如
Process副程式等而信號可用於共時性敘述與時序性敘述換言之
在時序性敘述之中可使用信號或變數來表示某個量但有無差別表
面上看都一樣大部分人並不會區分但在電路設計之中可不能大而
化之關於這點黃國倫老師有深入研究的確信號與變數有些不同
基本上變數會即時反應而信號會在下一個時脈才會反應如下範例
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t1 is Port( Bout integer range 0 to 15 clkin std_logic) End t1 ------------------------------- Architecture ar_t1 of t1 is Signal A integer range 0 to 15=0 begin
FPGA 設計實務
3-8
Process(clk) Begin If rising_edge(clk) Then Alt=A+1 If A=5 Then Alt=0 End If End If Blt=A End Process End ar_t1
A 為信號其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果將直接輸出到 B
不管「Blt=A」敘述是在 If 敘述之前或之後所以 B 輸出為 5
緊接著經由 If 的判斷使 A 變為 0但這個 A 將於下一個時
脈觸發時才會反應到 B
由上述可知B 的輸出為 012345012hellip而信號 A
雖然處於 Process 之中仍具共時性敘述的特色如圖 4 所示為其波形
圖4 B 波形
同樣地將其中的 A 改為變數當然其指定敘述也由「lt=」改為
「 =」如下
第三章 時序邏輯電路設計
3-9
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t2 is Port( Bout integer range 0 to 15 clkin std_logic) End t2 ------------------------------- Architecture ar_t2 of t2 is -- signal A integer range 0 to 15=0 Begin Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 If A=5 Then A=0 End If End If Blt=A End Process End ar_t2
A 為變數其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果並不會立即輸出到
B而先執行 If 敘述將 A 又調整至 0結束 If 敘述之後才
會執行「B=A」敘述所以 B 輸出為 0
由上述可知B 的輸出為 01234012hellip而變數 A 所
呈現的是時序性敘述的特色如圖 5 所示為其波形
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-2
認識 Process 結構 3-1 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Process 結構是跨入時序邏輯設計的重要介面在電路設計之中除
了共時性敘述外可能還會穿插一個或多個 Process 結構而每個 Process
結構有點像是獨立的零件所以如果不論及 Process 結構內部的敘述
則每個 Process 結構與其它共時性敘述一樣都是同時動作的而 Process
結構的格式如圖 1 所示
圖1 Process 結構之格式示意圖
標籤
在 Process 結構裡可加入標籤以幫助解讀這個電路通常標籤是使
用有意義的文字例如 counter10clock_div 等一看就知道這個 Process
結構提供什麼服務當然在 End Process 右邊的標籤必須與開頭的標
籤一樣才行也可只在開頭放置標籤而結束的地方不放置標籤基
本上標籤可區分電路功能屬於選擇性的文字若整個電路設計之
中只有一個 Procee 結構不放置標籤並無不可
敏感信號列
在 Process 關鍵字右邊括號內為敏感信號列 (Sensitivity List)其中列
出所有可觸動此 Process 動作的信號若超過一個敏感信號則在信
號與信號之間須以逗點分隔Process 結構有點類似微處理器裡的
中斷功能 (Interrupt)並不是隨時都在工作而是在任一個敏感信
號有所變化時才會執行 Processs 內描述的動作
第三章 時序邏輯電路設計
3-3
變數的宣告
在 Process 列與 Begin 列之間可宣告此 Process 所使用的信號及變
數而宣告的格式如下
Variable 變數名稱 1 變數名稱 2hellip 資料型態 [=初值]
變數的宣告與實體區裡的輸出埠宣告類似只是在此並沒有定義
變數的信號方向
描述電路功能
在 Begin 列與 End 列之間為此 Process 主要的部分可利用時序性
語法描述電路的動作而其動作是按描述的順序
If-Then-Else 敘述 3-2 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
If-Then-Else 敘述是一種條件判斷的時序性語法也是在描述電路中
不可或缺的好工具
基本語法格式
If-Then-Else 敘述的基本語法格式如下
If 判斷條件 Then
電路描述 1
Else
電路描述 2
End If
當判斷條件成立時執行電路描述 1不成立時執行電路描述 2
如果省略 Else 的部分便成為不完整的敘述如下
If 判斷條件 Then
電路描述
End If
FPGA 設計實務
3-4
執行這個敘述時若判斷條件成立則執行電路描述但沒有交待
不成立時要做何處置所以要保持原狀
為了不要交待不清可加上「null」也就是什麼也不做的意思
如下
If 判斷條件 Then
電路描述
Else
null
End If
有了 If-Then-Else 敘述整個電路設計就精彩起來了以第 2 章的
加法器 減法器為例我們可設計一個加法器與減法器合併的電路而利
用 ADDSUB 信號做為進行加法運算還是減法運算的開關當
ADDSUB=1時執行加法運算否則執行減法運算如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity ADDSUB is
Port(A Bin std_logic_vector(7 downto 0)
CinADDSUBin std_logic
Coout std_logic
Resultsout std_logic_vector(7 downto 0))
End ADDSUB
Architecture ARCH of ADDSUB is
Begin
Process(ABCinADDSUB)
Variable TMP std_logic_vector(8 downto 0)
Begin
If ADDSUB = 1 Then
TMP = 0 amp A + B + Cin
Else
TMP = 0 amp A - B - Cin
End If
Results lt= TMP(7 downto 0)
第三章 時序邏輯電路設計
3-5
Co lt= TMP(8)
End Process
End ARCH
多重判斷條件
If-Then-Else 敘述也可以使用多重判斷也就是多個判斷條件其語
法格式如下
If 判斷條件 1 Then
電路描述 1
Elsif 判斷條件 2 Then
電路描述 2 Else
電路描述 n
End If
當判斷條件 1 成立時執行電路描述 1若不成立時再看看判斷
條件 2 是否成立若成立時執行電路描述 2若不成立時再看看判
斷條件 3 是否成立以此類推其中原本為「Else If」的關鍵字合
併為「Elsif」而 後一項判斷之後還是為「Else」敘述
巢狀結構敘述
If-Then-Else 敘述支援巢狀結構的敘述也就是 If-Then-Else 敘述之
中有 If-Then-Else 敘述多層次的描述如圖 2 所示
FPGA 設計實務
3-6
圖2 巢狀結構之 If-Then-Else
3-2-1 時脈觸發
時序邏輯電路的動作主要是依時鐘脈波 (簡稱為時脈 )來同步或驅
動必須有效地抓住時脈方能同步或精確驅動如何抓住時脈呢我
們可應用 If-Then-Else 敘述而「抓住時脈」就是時脈觸發如圖 3 所
示分別為正緣觸發時脈與負緣觸發時脈之描述
我們也可以把「clk event and clk= 1」拆開說明clk event 就是偵
測到 clk 信號有變化 (由 1 變成 0 或 0 變成 1)其中「 event」是一種屬
性clk= 1就是 clk 的值變成 1很明顯的就是 0 變成 1也就是時脈
的升緣或正緣另外我們也可以把「 clk event and clk= 1 」改為
「rising_edge(clk)」也就是 clk 的升緣(Rising Edge)更口語化
同樣地我們可很容易地了解「clk event and clk= 0」也可以
「 falling_edge(clk)」代替
第三章 時序邏輯電路設計
3-7
Clk0Process (clk)
Begin
If clk event and clk= 1 Then
End If
End Process
Clk0Process (clk)
Begin
If clk event and clk= 0 Then
End If
End Process
電路動作描述
正緣觸發
電路動作描述
負緣觸發
圖3 時脈之描述
3-2-2 信號與變數徹底研究
在第二章裡曾經提及變數(Variable)只能用於時序性敘述之中如
Process副程式等而信號可用於共時性敘述與時序性敘述換言之
在時序性敘述之中可使用信號或變數來表示某個量但有無差別表
面上看都一樣大部分人並不會區分但在電路設計之中可不能大而
化之關於這點黃國倫老師有深入研究的確信號與變數有些不同
基本上變數會即時反應而信號會在下一個時脈才會反應如下範例
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t1 is Port( Bout integer range 0 to 15 clkin std_logic) End t1 ------------------------------- Architecture ar_t1 of t1 is Signal A integer range 0 to 15=0 begin
FPGA 設計實務
3-8
Process(clk) Begin If rising_edge(clk) Then Alt=A+1 If A=5 Then Alt=0 End If End If Blt=A End Process End ar_t1
A 為信號其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果將直接輸出到 B
不管「Blt=A」敘述是在 If 敘述之前或之後所以 B 輸出為 5
緊接著經由 If 的判斷使 A 變為 0但這個 A 將於下一個時
脈觸發時才會反應到 B
由上述可知B 的輸出為 012345012hellip而信號 A
雖然處於 Process 之中仍具共時性敘述的特色如圖 4 所示為其波形
圖4 B 波形
同樣地將其中的 A 改為變數當然其指定敘述也由「lt=」改為
「 =」如下
第三章 時序邏輯電路設計
3-9
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t2 is Port( Bout integer range 0 to 15 clkin std_logic) End t2 ------------------------------- Architecture ar_t2 of t2 is -- signal A integer range 0 to 15=0 Begin Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 If A=5 Then A=0 End If End If Blt=A End Process End ar_t2
A 為變數其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果並不會立即輸出到
B而先執行 If 敘述將 A 又調整至 0結束 If 敘述之後才
會執行「B=A」敘述所以 B 輸出為 0
由上述可知B 的輸出為 01234012hellip而變數 A 所
呈現的是時序性敘述的特色如圖 5 所示為其波形
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-3
變數的宣告
在 Process 列與 Begin 列之間可宣告此 Process 所使用的信號及變
數而宣告的格式如下
Variable 變數名稱 1 變數名稱 2hellip 資料型態 [=初值]
變數的宣告與實體區裡的輸出埠宣告類似只是在此並沒有定義
變數的信號方向
描述電路功能
在 Begin 列與 End 列之間為此 Process 主要的部分可利用時序性
語法描述電路的動作而其動作是按描述的順序
If-Then-Else 敘述 3-2 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
If-Then-Else 敘述是一種條件判斷的時序性語法也是在描述電路中
不可或缺的好工具
基本語法格式
If-Then-Else 敘述的基本語法格式如下
If 判斷條件 Then
電路描述 1
Else
電路描述 2
End If
當判斷條件成立時執行電路描述 1不成立時執行電路描述 2
如果省略 Else 的部分便成為不完整的敘述如下
If 判斷條件 Then
電路描述
End If
FPGA 設計實務
3-4
執行這個敘述時若判斷條件成立則執行電路描述但沒有交待
不成立時要做何處置所以要保持原狀
為了不要交待不清可加上「null」也就是什麼也不做的意思
如下
If 判斷條件 Then
電路描述
Else
null
End If
有了 If-Then-Else 敘述整個電路設計就精彩起來了以第 2 章的
加法器 減法器為例我們可設計一個加法器與減法器合併的電路而利
用 ADDSUB 信號做為進行加法運算還是減法運算的開關當
ADDSUB=1時執行加法運算否則執行減法運算如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity ADDSUB is
Port(A Bin std_logic_vector(7 downto 0)
CinADDSUBin std_logic
Coout std_logic
Resultsout std_logic_vector(7 downto 0))
End ADDSUB
Architecture ARCH of ADDSUB is
Begin
Process(ABCinADDSUB)
Variable TMP std_logic_vector(8 downto 0)
Begin
If ADDSUB = 1 Then
TMP = 0 amp A + B + Cin
Else
TMP = 0 amp A - B - Cin
End If
Results lt= TMP(7 downto 0)
第三章 時序邏輯電路設計
3-5
Co lt= TMP(8)
End Process
End ARCH
多重判斷條件
If-Then-Else 敘述也可以使用多重判斷也就是多個判斷條件其語
法格式如下
If 判斷條件 1 Then
電路描述 1
Elsif 判斷條件 2 Then
電路描述 2 Else
電路描述 n
End If
當判斷條件 1 成立時執行電路描述 1若不成立時再看看判斷
條件 2 是否成立若成立時執行電路描述 2若不成立時再看看判
斷條件 3 是否成立以此類推其中原本為「Else If」的關鍵字合
併為「Elsif」而 後一項判斷之後還是為「Else」敘述
巢狀結構敘述
If-Then-Else 敘述支援巢狀結構的敘述也就是 If-Then-Else 敘述之
中有 If-Then-Else 敘述多層次的描述如圖 2 所示
FPGA 設計實務
3-6
圖2 巢狀結構之 If-Then-Else
3-2-1 時脈觸發
時序邏輯電路的動作主要是依時鐘脈波 (簡稱為時脈 )來同步或驅
動必須有效地抓住時脈方能同步或精確驅動如何抓住時脈呢我
們可應用 If-Then-Else 敘述而「抓住時脈」就是時脈觸發如圖 3 所
示分別為正緣觸發時脈與負緣觸發時脈之描述
我們也可以把「clk event and clk= 1」拆開說明clk event 就是偵
測到 clk 信號有變化 (由 1 變成 0 或 0 變成 1)其中「 event」是一種屬
性clk= 1就是 clk 的值變成 1很明顯的就是 0 變成 1也就是時脈
的升緣或正緣另外我們也可以把「 clk event and clk= 1 」改為
「rising_edge(clk)」也就是 clk 的升緣(Rising Edge)更口語化
同樣地我們可很容易地了解「clk event and clk= 0」也可以
「 falling_edge(clk)」代替
第三章 時序邏輯電路設計
3-7
Clk0Process (clk)
Begin
If clk event and clk= 1 Then
End If
End Process
Clk0Process (clk)
Begin
If clk event and clk= 0 Then
End If
End Process
電路動作描述
正緣觸發
電路動作描述
負緣觸發
圖3 時脈之描述
3-2-2 信號與變數徹底研究
在第二章裡曾經提及變數(Variable)只能用於時序性敘述之中如
Process副程式等而信號可用於共時性敘述與時序性敘述換言之
在時序性敘述之中可使用信號或變數來表示某個量但有無差別表
面上看都一樣大部分人並不會區分但在電路設計之中可不能大而
化之關於這點黃國倫老師有深入研究的確信號與變數有些不同
基本上變數會即時反應而信號會在下一個時脈才會反應如下範例
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t1 is Port( Bout integer range 0 to 15 clkin std_logic) End t1 ------------------------------- Architecture ar_t1 of t1 is Signal A integer range 0 to 15=0 begin
FPGA 設計實務
3-8
Process(clk) Begin If rising_edge(clk) Then Alt=A+1 If A=5 Then Alt=0 End If End If Blt=A End Process End ar_t1
A 為信號其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果將直接輸出到 B
不管「Blt=A」敘述是在 If 敘述之前或之後所以 B 輸出為 5
緊接著經由 If 的判斷使 A 變為 0但這個 A 將於下一個時
脈觸發時才會反應到 B
由上述可知B 的輸出為 012345012hellip而信號 A
雖然處於 Process 之中仍具共時性敘述的特色如圖 4 所示為其波形
圖4 B 波形
同樣地將其中的 A 改為變數當然其指定敘述也由「lt=」改為
「 =」如下
第三章 時序邏輯電路設計
3-9
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t2 is Port( Bout integer range 0 to 15 clkin std_logic) End t2 ------------------------------- Architecture ar_t2 of t2 is -- signal A integer range 0 to 15=0 Begin Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 If A=5 Then A=0 End If End If Blt=A End Process End ar_t2
A 為變數其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果並不會立即輸出到
B而先執行 If 敘述將 A 又調整至 0結束 If 敘述之後才
會執行「B=A」敘述所以 B 輸出為 0
由上述可知B 的輸出為 01234012hellip而變數 A 所
呈現的是時序性敘述的特色如圖 5 所示為其波形
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-4
執行這個敘述時若判斷條件成立則執行電路描述但沒有交待
不成立時要做何處置所以要保持原狀
為了不要交待不清可加上「null」也就是什麼也不做的意思
如下
If 判斷條件 Then
電路描述
Else
null
End If
有了 If-Then-Else 敘述整個電路設計就精彩起來了以第 2 章的
加法器 減法器為例我們可設計一個加法器與減法器合併的電路而利
用 ADDSUB 信號做為進行加法運算還是減法運算的開關當
ADDSUB=1時執行加法運算否則執行減法運算如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity ADDSUB is
Port(A Bin std_logic_vector(7 downto 0)
CinADDSUBin std_logic
Coout std_logic
Resultsout std_logic_vector(7 downto 0))
End ADDSUB
Architecture ARCH of ADDSUB is
Begin
Process(ABCinADDSUB)
Variable TMP std_logic_vector(8 downto 0)
Begin
If ADDSUB = 1 Then
TMP = 0 amp A + B + Cin
Else
TMP = 0 amp A - B - Cin
End If
Results lt= TMP(7 downto 0)
第三章 時序邏輯電路設計
3-5
Co lt= TMP(8)
End Process
End ARCH
多重判斷條件
If-Then-Else 敘述也可以使用多重判斷也就是多個判斷條件其語
法格式如下
If 判斷條件 1 Then
電路描述 1
Elsif 判斷條件 2 Then
電路描述 2 Else
電路描述 n
End If
當判斷條件 1 成立時執行電路描述 1若不成立時再看看判斷
條件 2 是否成立若成立時執行電路描述 2若不成立時再看看判
斷條件 3 是否成立以此類推其中原本為「Else If」的關鍵字合
併為「Elsif」而 後一項判斷之後還是為「Else」敘述
巢狀結構敘述
If-Then-Else 敘述支援巢狀結構的敘述也就是 If-Then-Else 敘述之
中有 If-Then-Else 敘述多層次的描述如圖 2 所示
FPGA 設計實務
3-6
圖2 巢狀結構之 If-Then-Else
3-2-1 時脈觸發
時序邏輯電路的動作主要是依時鐘脈波 (簡稱為時脈 )來同步或驅
動必須有效地抓住時脈方能同步或精確驅動如何抓住時脈呢我
們可應用 If-Then-Else 敘述而「抓住時脈」就是時脈觸發如圖 3 所
示分別為正緣觸發時脈與負緣觸發時脈之描述
我們也可以把「clk event and clk= 1」拆開說明clk event 就是偵
測到 clk 信號有變化 (由 1 變成 0 或 0 變成 1)其中「 event」是一種屬
性clk= 1就是 clk 的值變成 1很明顯的就是 0 變成 1也就是時脈
的升緣或正緣另外我們也可以把「 clk event and clk= 1 」改為
「rising_edge(clk)」也就是 clk 的升緣(Rising Edge)更口語化
同樣地我們可很容易地了解「clk event and clk= 0」也可以
「 falling_edge(clk)」代替
第三章 時序邏輯電路設計
3-7
Clk0Process (clk)
Begin
If clk event and clk= 1 Then
End If
End Process
Clk0Process (clk)
Begin
If clk event and clk= 0 Then
End If
End Process
電路動作描述
正緣觸發
電路動作描述
負緣觸發
圖3 時脈之描述
3-2-2 信號與變數徹底研究
在第二章裡曾經提及變數(Variable)只能用於時序性敘述之中如
Process副程式等而信號可用於共時性敘述與時序性敘述換言之
在時序性敘述之中可使用信號或變數來表示某個量但有無差別表
面上看都一樣大部分人並不會區分但在電路設計之中可不能大而
化之關於這點黃國倫老師有深入研究的確信號與變數有些不同
基本上變數會即時反應而信號會在下一個時脈才會反應如下範例
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t1 is Port( Bout integer range 0 to 15 clkin std_logic) End t1 ------------------------------- Architecture ar_t1 of t1 is Signal A integer range 0 to 15=0 begin
FPGA 設計實務
3-8
Process(clk) Begin If rising_edge(clk) Then Alt=A+1 If A=5 Then Alt=0 End If End If Blt=A End Process End ar_t1
A 為信號其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果將直接輸出到 B
不管「Blt=A」敘述是在 If 敘述之前或之後所以 B 輸出為 5
緊接著經由 If 的判斷使 A 變為 0但這個 A 將於下一個時
脈觸發時才會反應到 B
由上述可知B 的輸出為 012345012hellip而信號 A
雖然處於 Process 之中仍具共時性敘述的特色如圖 4 所示為其波形
圖4 B 波形
同樣地將其中的 A 改為變數當然其指定敘述也由「lt=」改為
「 =」如下
第三章 時序邏輯電路設計
3-9
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t2 is Port( Bout integer range 0 to 15 clkin std_logic) End t2 ------------------------------- Architecture ar_t2 of t2 is -- signal A integer range 0 to 15=0 Begin Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 If A=5 Then A=0 End If End If Blt=A End Process End ar_t2
A 為變數其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果並不會立即輸出到
B而先執行 If 敘述將 A 又調整至 0結束 If 敘述之後才
會執行「B=A」敘述所以 B 輸出為 0
由上述可知B 的輸出為 01234012hellip而變數 A 所
呈現的是時序性敘述的特色如圖 5 所示為其波形
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-5
Co lt= TMP(8)
End Process
End ARCH
多重判斷條件
If-Then-Else 敘述也可以使用多重判斷也就是多個判斷條件其語
法格式如下
If 判斷條件 1 Then
電路描述 1
Elsif 判斷條件 2 Then
電路描述 2 Else
電路描述 n
End If
當判斷條件 1 成立時執行電路描述 1若不成立時再看看判斷
條件 2 是否成立若成立時執行電路描述 2若不成立時再看看判
斷條件 3 是否成立以此類推其中原本為「Else If」的關鍵字合
併為「Elsif」而 後一項判斷之後還是為「Else」敘述
巢狀結構敘述
If-Then-Else 敘述支援巢狀結構的敘述也就是 If-Then-Else 敘述之
中有 If-Then-Else 敘述多層次的描述如圖 2 所示
FPGA 設計實務
3-6
圖2 巢狀結構之 If-Then-Else
3-2-1 時脈觸發
時序邏輯電路的動作主要是依時鐘脈波 (簡稱為時脈 )來同步或驅
動必須有效地抓住時脈方能同步或精確驅動如何抓住時脈呢我
們可應用 If-Then-Else 敘述而「抓住時脈」就是時脈觸發如圖 3 所
示分別為正緣觸發時脈與負緣觸發時脈之描述
我們也可以把「clk event and clk= 1」拆開說明clk event 就是偵
測到 clk 信號有變化 (由 1 變成 0 或 0 變成 1)其中「 event」是一種屬
性clk= 1就是 clk 的值變成 1很明顯的就是 0 變成 1也就是時脈
的升緣或正緣另外我們也可以把「 clk event and clk= 1 」改為
「rising_edge(clk)」也就是 clk 的升緣(Rising Edge)更口語化
同樣地我們可很容易地了解「clk event and clk= 0」也可以
「 falling_edge(clk)」代替
第三章 時序邏輯電路設計
3-7
Clk0Process (clk)
Begin
If clk event and clk= 1 Then
End If
End Process
Clk0Process (clk)
Begin
If clk event and clk= 0 Then
End If
End Process
電路動作描述
正緣觸發
電路動作描述
負緣觸發
圖3 時脈之描述
3-2-2 信號與變數徹底研究
在第二章裡曾經提及變數(Variable)只能用於時序性敘述之中如
Process副程式等而信號可用於共時性敘述與時序性敘述換言之
在時序性敘述之中可使用信號或變數來表示某個量但有無差別表
面上看都一樣大部分人並不會區分但在電路設計之中可不能大而
化之關於這點黃國倫老師有深入研究的確信號與變數有些不同
基本上變數會即時反應而信號會在下一個時脈才會反應如下範例
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t1 is Port( Bout integer range 0 to 15 clkin std_logic) End t1 ------------------------------- Architecture ar_t1 of t1 is Signal A integer range 0 to 15=0 begin
FPGA 設計實務
3-8
Process(clk) Begin If rising_edge(clk) Then Alt=A+1 If A=5 Then Alt=0 End If End If Blt=A End Process End ar_t1
A 為信號其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果將直接輸出到 B
不管「Blt=A」敘述是在 If 敘述之前或之後所以 B 輸出為 5
緊接著經由 If 的判斷使 A 變為 0但這個 A 將於下一個時
脈觸發時才會反應到 B
由上述可知B 的輸出為 012345012hellip而信號 A
雖然處於 Process 之中仍具共時性敘述的特色如圖 4 所示為其波形
圖4 B 波形
同樣地將其中的 A 改為變數當然其指定敘述也由「lt=」改為
「 =」如下
第三章 時序邏輯電路設計
3-9
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t2 is Port( Bout integer range 0 to 15 clkin std_logic) End t2 ------------------------------- Architecture ar_t2 of t2 is -- signal A integer range 0 to 15=0 Begin Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 If A=5 Then A=0 End If End If Blt=A End Process End ar_t2
A 為變數其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果並不會立即輸出到
B而先執行 If 敘述將 A 又調整至 0結束 If 敘述之後才
會執行「B=A」敘述所以 B 輸出為 0
由上述可知B 的輸出為 01234012hellip而變數 A 所
呈現的是時序性敘述的特色如圖 5 所示為其波形
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-6
圖2 巢狀結構之 If-Then-Else
3-2-1 時脈觸發
時序邏輯電路的動作主要是依時鐘脈波 (簡稱為時脈 )來同步或驅
動必須有效地抓住時脈方能同步或精確驅動如何抓住時脈呢我
們可應用 If-Then-Else 敘述而「抓住時脈」就是時脈觸發如圖 3 所
示分別為正緣觸發時脈與負緣觸發時脈之描述
我們也可以把「clk event and clk= 1」拆開說明clk event 就是偵
測到 clk 信號有變化 (由 1 變成 0 或 0 變成 1)其中「 event」是一種屬
性clk= 1就是 clk 的值變成 1很明顯的就是 0 變成 1也就是時脈
的升緣或正緣另外我們也可以把「 clk event and clk= 1 」改為
「rising_edge(clk)」也就是 clk 的升緣(Rising Edge)更口語化
同樣地我們可很容易地了解「clk event and clk= 0」也可以
「 falling_edge(clk)」代替
第三章 時序邏輯電路設計
3-7
Clk0Process (clk)
Begin
If clk event and clk= 1 Then
End If
End Process
Clk0Process (clk)
Begin
If clk event and clk= 0 Then
End If
End Process
電路動作描述
正緣觸發
電路動作描述
負緣觸發
圖3 時脈之描述
3-2-2 信號與變數徹底研究
在第二章裡曾經提及變數(Variable)只能用於時序性敘述之中如
Process副程式等而信號可用於共時性敘述與時序性敘述換言之
在時序性敘述之中可使用信號或變數來表示某個量但有無差別表
面上看都一樣大部分人並不會區分但在電路設計之中可不能大而
化之關於這點黃國倫老師有深入研究的確信號與變數有些不同
基本上變數會即時反應而信號會在下一個時脈才會反應如下範例
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t1 is Port( Bout integer range 0 to 15 clkin std_logic) End t1 ------------------------------- Architecture ar_t1 of t1 is Signal A integer range 0 to 15=0 begin
FPGA 設計實務
3-8
Process(clk) Begin If rising_edge(clk) Then Alt=A+1 If A=5 Then Alt=0 End If End If Blt=A End Process End ar_t1
A 為信號其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果將直接輸出到 B
不管「Blt=A」敘述是在 If 敘述之前或之後所以 B 輸出為 5
緊接著經由 If 的判斷使 A 變為 0但這個 A 將於下一個時
脈觸發時才會反應到 B
由上述可知B 的輸出為 012345012hellip而信號 A
雖然處於 Process 之中仍具共時性敘述的特色如圖 4 所示為其波形
圖4 B 波形
同樣地將其中的 A 改為變數當然其指定敘述也由「lt=」改為
「 =」如下
第三章 時序邏輯電路設計
3-9
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t2 is Port( Bout integer range 0 to 15 clkin std_logic) End t2 ------------------------------- Architecture ar_t2 of t2 is -- signal A integer range 0 to 15=0 Begin Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 If A=5 Then A=0 End If End If Blt=A End Process End ar_t2
A 為變數其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果並不會立即輸出到
B而先執行 If 敘述將 A 又調整至 0結束 If 敘述之後才
會執行「B=A」敘述所以 B 輸出為 0
由上述可知B 的輸出為 01234012hellip而變數 A 所
呈現的是時序性敘述的特色如圖 5 所示為其波形
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-7
Clk0Process (clk)
Begin
If clk event and clk= 1 Then
End If
End Process
Clk0Process (clk)
Begin
If clk event and clk= 0 Then
End If
End Process
電路動作描述
正緣觸發
電路動作描述
負緣觸發
圖3 時脈之描述
3-2-2 信號與變數徹底研究
在第二章裡曾經提及變數(Variable)只能用於時序性敘述之中如
Process副程式等而信號可用於共時性敘述與時序性敘述換言之
在時序性敘述之中可使用信號或變數來表示某個量但有無差別表
面上看都一樣大部分人並不會區分但在電路設計之中可不能大而
化之關於這點黃國倫老師有深入研究的確信號與變數有些不同
基本上變數會即時反應而信號會在下一個時脈才會反應如下範例
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t1 is Port( Bout integer range 0 to 15 clkin std_logic) End t1 ------------------------------- Architecture ar_t1 of t1 is Signal A integer range 0 to 15=0 begin
FPGA 設計實務
3-8
Process(clk) Begin If rising_edge(clk) Then Alt=A+1 If A=5 Then Alt=0 End If End If Blt=A End Process End ar_t1
A 為信號其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果將直接輸出到 B
不管「Blt=A」敘述是在 If 敘述之前或之後所以 B 輸出為 5
緊接著經由 If 的判斷使 A 變為 0但這個 A 將於下一個時
脈觸發時才會反應到 B
由上述可知B 的輸出為 012345012hellip而信號 A
雖然處於 Process 之中仍具共時性敘述的特色如圖 4 所示為其波形
圖4 B 波形
同樣地將其中的 A 改為變數當然其指定敘述也由「lt=」改為
「 =」如下
第三章 時序邏輯電路設計
3-9
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t2 is Port( Bout integer range 0 to 15 clkin std_logic) End t2 ------------------------------- Architecture ar_t2 of t2 is -- signal A integer range 0 to 15=0 Begin Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 If A=5 Then A=0 End If End If Blt=A End Process End ar_t2
A 為變數其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果並不會立即輸出到
B而先執行 If 敘述將 A 又調整至 0結束 If 敘述之後才
會執行「B=A」敘述所以 B 輸出為 0
由上述可知B 的輸出為 01234012hellip而變數 A 所
呈現的是時序性敘述的特色如圖 5 所示為其波形
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-8
Process(clk) Begin If rising_edge(clk) Then Alt=A+1 If A=5 Then Alt=0 End If End If Blt=A End Process End ar_t1
A 為信號其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果將直接輸出到 B
不管「Blt=A」敘述是在 If 敘述之前或之後所以 B 輸出為 5
緊接著經由 If 的判斷使 A 變為 0但這個 A 將於下一個時
脈觸發時才會反應到 B
由上述可知B 的輸出為 012345012hellip而信號 A
雖然處於 Process 之中仍具共時性敘述的特色如圖 4 所示為其波形
圖4 B 波形
同樣地將其中的 A 改為變數當然其指定敘述也由「lt=」改為
「 =」如下
第三章 時序邏輯電路設計
3-9
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t2 is Port( Bout integer range 0 to 15 clkin std_logic) End t2 ------------------------------- Architecture ar_t2 of t2 is -- signal A integer range 0 to 15=0 Begin Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 If A=5 Then A=0 End If End If Blt=A End Process End ar_t2
A 為變數其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果並不會立即輸出到
B而先執行 If 敘述將 A 又調整至 0結束 If 敘述之後才
會執行「B=A」敘述所以 B 輸出為 0
由上述可知B 的輸出為 01234012hellip而變數 A 所
呈現的是時序性敘述的特色如圖 5 所示為其波形
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-9
Library IEEE Use IEEEstd_logic_1164all ------------------------------- Entity t2 is Port( Bout integer range 0 to 15 clkin std_logic) End t2 ------------------------------- Architecture ar_t2 of t2 is -- signal A integer range 0 to 15=0 Begin Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 If A=5 Then A=0 End If End If Blt=A End Process End ar_t2
A 為變數其資料型態為 0 到 15 之間的整數初值為 0其分析如下
在 Process 裡有「Blt=A」敘述所以 A 的任何結果反應到 B
剛開始時在 clk 時脈升緣發生之前A 保持為 0所以 B 為 0
第一個 clk 時脈升緣發生時執行「Alt=A+1」使得 A=1所
以 B 為 1
同樣地第二個 clk 時脈到第四個 clk 時脈A 由 2 加到 4在
If 的判斷裡都不成立所以 B 輸出為 2~4
第五個 clk 時脈A 加 1 而變成 5這個結果並不會立即輸出到
B而先執行 If 敘述將 A 又調整至 0結束 If 敘述之後才
會執行「B=A」敘述所以 B 輸出為 0
由上述可知B 的輸出為 01234012hellip而變數 A 所
呈現的是時序性敘述的特色如圖 5 所示為其波形
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-10
圖5 B 波形
既然變數 A 具有時序性敘述的特色所以「B=A」敘述的位置
將影響其結果例如將「B=A」敘述移至「Alt=A+1」敘述之後如下
Process(clk) Variable Ainteger range 0 to 15=0 Begin If rising_edge(clk) Then A=A+1 Blt=A If A=5 Then A=0 End If End If -- Blt=A End Process
則 B 之輸出將變為 01234512hellip請與前面的結果
比較
Case-When 敘述 3-3 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Case-When 敘述屬於順序性敘述其語法格式
Case 控制項目 is
When 值 1 或信號 1 =gt
電路描述 1 When 值 2 或信號 2 =gt
電路描述 2 When others =gt
電路描述 n End Case
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-11
當控制項目為值 1 或信號 1 時則執行電路描述 1當控制項目為
值 2 或信號 2 時則執行電路描述 2以此類推另外必須注意的是
不管怎樣 後一項必須為「others」也就是「以上皆非」的選項
Case-When 敘述常被應用在狀態機的實現待 4-6 節再詳述
Loop 敘述 3-4 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Loop 敘述是一種控制迴圈結構可用於描述重複的電路動作在
VHDL 裡Loop 敘述包括 For-LoopWhile-Loop 及無窮盡的 Loop既
然有無窮盡的 Loop就有跳出迴圈的方法我們可以使用 Exit When 敘
述或結合 If-Then-Else 與 Exit
For-Loop 敘述
For-Loop 敘述是一種時序性敘述 (For-Generate 敘述則是共時性敘
述)可按指定的迴圈數重複執行同樣的動作其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 End Loop [標籤]
標籤是為了增加電路描述的可讀性可有可無
控制變數為自動產生不須宣告習慣上常使用 IJK(大
小寫不拘)為控制變數當然也可隨配合當時的狀況選用較
有意義的變數名稱
範圍是指只要控制變數在範圍內即重複執行迴圈而範圍的
指定方式有兩種
第一種是數值範圍例如「0 to 7」表示從控制變數為 0 開
始每執行一次迴圈控制變數自動加 1一直執行到控制
變數超過 7 為止當然也可採遞減的方式例如「15 downto
6」表示從控制變數為 15 開始每執行一次迴圈控制變
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-12
數自動減 1直到控制變數少於 6 為止
第二種列舉資料型態 (Enumerated Data Type)如下
(關於列舉資料型態與定義資料型態待第 4 章再介紹)
Architecture ARCH of Loop_EX
Type week is SundayMondayTuesdayThursdayFridaySaturday
Begin Process (A)
Begin
For day in week Loop
Case day is
When Sunday =gt
電路描述 1 When Monday =gt
電路描述 2
For-Loop 敘述的用途很廣例如要設計一個 11 位元之同位位元產
生電路如下
Library IEEE
Use IEEEstd_logic_1164all
Entity Parity11 is
Port( Dinin std_logic_vector(0 to 10)
ODDout std_logic)
End Parity11
Architecture ARCH of Parity11 is
Begin
Process(Din)
Variable TMP Boolean
Begin
TMP = false
For I in 0 to Dinlength -1 Loop
If Din(I) = 1 Then
TMP = not TMP
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-13
End If
End Loop
If TMP Then
ODD lt= 1
Else
ODD lt= 0
End If
End Process
End ARCH
其中「Dinlength」是指 Din 資料的長度而「length」是資料屬性
待第 4 章再介紹
Whi l e-Loop 敘述
While-Loop 敘述提供先條件判斷的迴圈敘述只要判斷條件成立
則執行迴圈內的電路描述其語法格式如下
[標籤] While 判斷條件 Loop
電路描述 1 End Loop [標籤]
基本上While-Loop 敘述是用在撰寫測試平台(Test Bench)產生激
勵信號以進行電路模擬而不適用於合成電路
Exi t When 敘述
在 Loop 迴圈裡可利用 Exit When 敘述跳出迴圈其語法格式如下
[標籤] For 控制變數 in 範圍 Loop
電路描述 1 Exit When 判斷條件
End Loop [標籤]
在正常的情況下上面的敘述會按範圍執行迴圈但如果判斷條件
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-14
成立時將不管有沒有超出範圍都會直接跳出迴圈不過Exit-When
敘述也是用在撰寫測試平台(Test Bench)產生激勵信號以進行電路模
擬而不適用於合成電路
Exi t 敘述
對於無窮盡的 Loop 迴圈可利用 If-Then 敘述與 Exit 敘述做為跳
出迴圈的方法其語法格式如下
Loop
電路描述 1 If 判斷條件 Then Exit
End Loop
在正常的情況下上面的迴圈將不斷地執行直到判斷條件成立時
將跳出迴圈不過Exit-When 敘述也是用在撰寫測試平台(Test Bench)
產生激勵信號以進行電路模擬而不適用於合成電路
各式正反器設計 3-5 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
正反器 (Flip-Flop)是時序電路的代表元件傳統上正反器可分為
RS 正反器JK 正反器D 型正反器與 T 型正反器等四種其中 RS 正
反器與 JK 正反器類似或者說JK 正反器是 RS 正反器的改良版幾
乎所有 RS 正反器的功能JK 正反器都能辦到而且 JK 正反器還提供
一項傳統 RS 正反器所不能接受的功能也就是兩輸入端同時為 1 的狀
況JK 正反器的兩輸入端同時為 1相當於 T 型正反器常被用來設計
計數器而 RS 正反器不允許兩輸入端同時為 1D 型正反器提供資料暫
存的功能可用來做為記憶元件或暫存器之用
3-5-1 RS 正反器與 JK 正反器
陽春的 RS 正反器包括 R 與 S 兩個輸入端而輸出端為 Q 與 Q
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-15
其中 Q為 Q 的反相所以也可只視為一個輸出端 Q同樣的情況也
出現在 JK 正反器上如圖 6 所示為 RS 正反器與 JK 正反器的符號
圖6 RS 正反器(左圖)與 JK 正反器(右圖)
再來比較這兩者的真值表如表 1 所示我們將可發現S 接腳相
當於 J 接腳R 接腳相當於 K 接腳除 RS 正反器不允許 S 與 R 同時輸
入 1幾乎與 JK 正反器一樣而 JK 正反器之 J 與 K 接腳同時輸入 1 時
其輸出狀態將反相若原本 Q=0則 Q 將改為 1若原本 Q=1則 Q 將
改為 0所以JK 正反器幾乎可以取代 RS 正反器
表 1 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
S R Q Q J K Q Q
0 0 Q Q 0 0 Q Q
0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0
1 1 不允許 不允許 1 1 Q Q
較實用的 RS 正反器或 JK 正反器不該如此陽春至少要有時脈輸
入 CK以同步正反器的動作RS 或 JK 輸入接腳都受時脈輸入 CK
的控制完整的 RS 正反器或 JK 正反器還會有預設 Preset(簡稱 PR)
及清除 Clear(簡稱 CL)接腳以低態動的的預設接腳及清除接腳為例
當 PR=0 時輸出 Q=1當 CL=0 時輸出 Q=0而 PR 與 CL 接腳並不
受時脈輸入 CK 的控制如圖 7 所示為附預設與清除接腳之 RS 正反器
與 JK 正反器之符號而表 2 為其真值表
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-16
圖7 附預設與清除接腳之 RS 正反器(左圖)與 JK 正反器(右圖)
表 2 附預設與清除接腳 RS 正反器與 JK 正反器之真值表
RS 正反器之真值表 JK 正反器之真值表
PR CL CK S R Q Q PR CL CK J K Q Q
0 1 - - - 1 0 0 1 - - - 1 0
1 0 - - - 0 1 1 0 - - - 0 1
1 1 0 0 Q Q 1 1 0 0 Q Q
1 1 0 1 0 1 1 1 0 1 0 1
1 1 1 0 1 0 1 1 1 0 1 0
1 1 1 1 X X 1 1 1 1 Q Q
「 -」代表任意「X」代表未確定
若要以 VHDL 描述附預設與清除接腳之 RS 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity RSFF1 is
Port( PRCLCKRSin std_logic
QQbarout std_logic)
End RSFF1
Architecture ARCH of RSFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-17
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If S=0 and R=1 Then TMP = 0
Elsif S=1 and R=0 Then TMP = 1
Elsif S=1 and R=1 Then TMP = X
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
只要把上述電路中的 S 改為 JR 改為 K且把「J=1 and K=1」的
結果改為「TMP = not TMP」即為 JK 正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity JKFF1 is
Port( PRCLCKJKin std_logic
QQbarout std_logic)
End JKFF1
Architecture ARCH of JKFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If J=0 and K=1 Then TMP = 0
Elsif J=1 and K=0 Then TMP = 1
Elsif J=1 and K=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-18
End ARCH
3-5-2 T 型正反器
T 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 T 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 T 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 8 所示為附預設與清除接
腳之 T 型正反器而表 3 為其真值表
圖8 附預設與清除接腳之 T 型正反器
表 3 T 型正反器之真值表
PR CL CK T Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 Q Q
1 1 1 Q Q
若要以 VHDL 描述附預設與清除接腳之 T 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity TFF1 is
Port( PRCLCKTin std_logic
QQbarout std_logic)
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-19
End TFF1
Architecture ARCH of TFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
3-5-3 D 型正反器
D 型正反器為單輸入之正反器同樣地其輸出端為 Q 與 Q其中 Q
為 Q 的反相所以也可只視為一個輸出端 Q通常 D 型正反器都會有
一個時脈輸入 CK以同步正反器的動作有些 D 型正反器還會附上不
受時脈控制的預設 PR 及清除 CL 接腳如圖 9 所示為附預設與清除接
腳之 D 型正反器而表 4 為其真值表
圖9 附預設與清除接腳之 D 型正反器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-20
表 4 D 型正反器之真值表
PR CL CK D Q Q
0 1 - - 1 0
1 0 - - 0 1
1 1 0 0 1
1 1 1 1 0
若要以 VHDL 描述附預設與清除接腳之 D 型正反器如下
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( PRCLCKDin std_logic
QQbarout std_logic)
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(PRCLCK)
Variable TMPstd_logic
Begin
If PR=0 Then TMP = 1
Elsif CL=0 Then TMP = 0
Elsif Rising_edge(CK) Then
If D=1 Then TMP = 1
Else TMP = 0
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
Generic 敘述 3-6 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
Generic 敘述的功能是將參數傳入設計裡其格式如下
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-21
Generic ( N integer = 4)
關鍵字 常數名稱 資料型態 初值
若 Generic 敘述是針對整個設計的參數所以要放置在實體定義裡
Entity 列與 Port 列之間例如
Entity MOD1 is
Generic(N integer =4)
Port( CLRCKUDin std_logic
Qout std_logic_vector(N-1 downto 0))
End MOD1
如此一來輸出埠 Q 被定義為 4 位元的匯流排即(3 downto 0)若
要把 Q 變成 16 位元的匯流排只要將 N 改為 16 即可另外如果把這
個電路設計做為零件而在引用此零件時可隨即指定其匯流排寬度
則可在引用此零件時在 Port Map 敘述之前使用 Generic Map 敘述指
定匯流排寬度Generic Map 敘述之格式如下
Generic Map (參數)
其中參數的用途很多如零件的時間參數匯流排寬度等若要傳
遞多個參數則在參數與參數之間加一個逗號分隔例如要設定上升
時間為 1ns下降時間為 1ns如下
Generic Map(tRise =gt 1 ns tFall =gt 1 ns)
其中「 tRise =gt 1ns」就是傳入上升時間為 1ns 的參數而「 tFall =gt
1ns」就是傳入下降時間為 1ns 的參數至於匯流排寬度的指定在此將
延續前面的單元以 D 型正反器為例並應用 For-Loop 敘述首先建
構一個可指定匯流排寬度的 D 型正反器零件然後在主設計之中引用
這個零件而在引用時也透過 Generic Map 敘述指定匯流排寬度如
下所示為可指定匯流排寬度的 D 型正反器零件
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Generic (widpositive)
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-22
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0))
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMP std_logic_vector( wid-1 downto 0)
Begin
If CL=1 Then
TMP = (others =gt 0)
Elsif Rising_Edge(CK) Then
For I in TMPrange Loop
TMP(I) = D(I)
End Loop
End If
Q lt= TMP
End Process
End ARCH
在上述電路描述之中說明如下
在實體區裡的 Entity 列與 Port 列之間插入「Generic (widpositive)」
讓此零件設計接收一個 wid 參數這個參數的資料型態是正整數
(positive)如此一來引用此零件時所下的參數將傳輸到整
個在零件設計中的 wid
基本上這個零件(DFF1)是一個具有清除功能的 D 型正反器而
其 CL 接腳為高態動作不受時脈影響也就是當 CL=1時此
正反器的輸出立即變為 0
「TMP = (others =gt 0) 」敘述是將 TMP 的內容全部變為 0其
中「others =gt0」的意思是把其它非 0 的位元全變為 0再放入
TMP 之中所以在此看不出 TMP 有多少位元也不管它有多少
位元可說是高招
「For I in TMPrange Loop」敘述是按 TMP 範圍為迴圈數以執
行其下的描述「TMP 範圍」很清楚地定義在 Process 下面的
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-23
Variable 列裡其範圍為「wid-1 downto 0」所以也受控於傳入
的匯流排寬度參數
除了 DFF1 零件的描述外在專案裡的主要設計檔(NewDesignVHD)
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity NewDesign is
Port( CLCKin std_logic
Dinin std_logic_vector(7 downto 0)
Doutout std_logic_vector(7 downto 0))
End NewDesign
Architecture ARCH of NewDesign is
Component DFF1
Generic (widpositive)
Port( CLCKin std_logic
Din std_logic_vector( wid-1 downto 0)
Qout std_logic_vector( wid-1 downto 0) )
End Component
Constant wid8 positive = 8
Begin
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
End ARCH
在上述電路描述之中主要是展示如何使用 Generic Map 敘述將
匯流排寬度的參數傳入所引用的零件說明如下
在架構區的開頭首先宣告 DFF1 零件而在 Component 列與 Port 列
之間置入「Generic (widpositive)」敘述讓此零件接收一個正整
數的參數 wid
在 Component 零件宣告完畢後繼續宣告一個 wid8 常數其初
值為 8這個常數就是匯流排寬度
在 Begin 列之後標示「DFF8」標籤的列實際上與其下一列
屬同一敘述可寫成同一列標籤右邊列出所要引用零件的名稱
(即 DFF1)然後是「Generic Map(wid8)」敘述將匯流排寬度之
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-24
參數傳入此零件 後才是 Port Map 接腳應對
DFF8 DFF1 Generic Map(wid8)
Port Map (CLCKDinDout)
計數器設計 3-7 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
計數器 (Counter)是一種可計數輸入脈波的裝置而這種裝置可利用
T 型正反器或 JK 正反器串接而成如圖 10 所示為 4 位元的上數計數器
圖10 4 位元上數計數器
其中所有正反器的輸入端都連接 1而第一個正反器( 左邊的 U0)
的時脈輸入 CK連接所要計數的輸入脈波而輸出 0Q 連接到第二個正
反器(U1)的輸入 CK以此類推
通常電路的信號流程或零件排列順序是由左而右相對於數字的順
序是由右而左 右邊的數字位元是 低位元(LSBLeast Significant Bit
之簡稱) 左邊的數字位元是 高位元(MSBMost Significant Bit 之簡
稱) 右邊的數字位元代表電路的 左邊輸出 左邊的數字位元代表
電路的 右邊輸出以此類推
這裡所使用的 T 型正反器是升緣觸發的時脈輸入當輸入信號由低
態變為高態的瞬間該正反器的輸出將轉態若一開始時這個計數器
的輸出是0000第一個脈波輸入時U0 的 CK 接收到一個升緣信號
而使其輸出轉態Q0 由 0 變 1 0Q 由 1 變 0而 0Q 連接到 U1 的 CK
就是 U1 的 CK 接收到一個降緣信號將不會有所反應因此 1Q 不變
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-25
2Q 不變 3Q 也不變整個電路的輸出為0001
當第二個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 0 變 1 1Q 由 1 變 0 1Q 由 1 變 0所以 2Q 不變 3Q 也
不變整個電路的輸出為0010
當第三個脈波輸入時U0 的輸出轉態Q0 由 0 變 1 0Q 由 1 變 0
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個降緣信號其輸出
Q1 不變 1Q 不變 1Q 不變 0所以 2Q 不變 3Q 也不變整個電路的輸
出為0011
當第四個脈波輸入時U0 的輸出轉態Q0 由 1 變 0 0Q 由 0 變 1
而 0Q 連接到 U1 的 CK就是 U1 的 CK 接收到一個升緣信號而使其輸
出轉態Q1 由 1 變 0 1Q 由 0 變 1 1Q 連接到 U3 的 CK就是 U3 的
CK 接收到一個升緣信號而使其輸出轉態Q2 由 0 變 1 2Q 由 1 變 0
2Q 由 1 變 0所以 3Q 也不變整個電路的輸出為0100
以此類推經過 15 個脈波的輸入後電路的輸出由 0000變為
1111再輸入一個脈波後電路的輸出又恢復為0000
若採用降緣觸發的 T 型正反器則脈波輸入對電路的影響將變成
反向計數也就是由1111變為0000的倒數(或稱為下數)計數若同樣
採用正緣觸發的 T 型正反器但其連接方式改由前一級的輸出 Q連
接到下一級的 CK也會倒數計數不管怎樣這種由前一級的輸出
連接到這一級的 CK稱之為漣波計數器 (Ripple Counter)或非同步計數
器 (Asynchronous Counter)
3-7-1 二進位計數器設計
從圖 8 中可發現漣波計數器很規律若要以 VHDL 設計漣波計數
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-26
器可使用 For-Generate 敘述在以 Component 與 Port Map 敘述即可
快速搭接 T 型正反器電路因此在專案裡必須建構一個 T 型正反器
如下所示
Library IEEE
Use IEEEstd_logic_1164all
Entity DFF1 is
Port( CLCKTin std_logic
QQbarout std_logic )
End DFF1
Architecture ARCH of DFF1 is
Begin
Process(CLCK)
Variable TMPstd_logic
Begin
If CL=1 Then TMP = 0
Elsif Rising_Edge(CK) Then
If T=1 Then TMP = not TMP
Else null
End If
End If
Q lt= TMP
Qbar lt= not TMP
End Process
End ARCH
在圖 8 裡所有清除接腳 CL 都接地也就是不使用的意思有點
可惜在此將把這些接腳相連接成為外部的清除控制接腳我們可藉
由此清除所有正反器如下所示為此計數器電路的描述
Library IEEE
Use IEEEstd_logic_1164all
Entity Counter4B is
Port( CL PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End Counter4B
Architecture ARCH of Counter4B is
Component DFF1
Port( CLCKTin std_logic
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-27
QQbarout std_logic))
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1 For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) 1 Q(I) TMP(I+1))
End Generate
End ARCH
上述電路的重點在於 For-Generate 敘述所造成的結果如下說明
當 I=0 時產生 U0 及其連接線如圖 11 所示
圖11 I=0 時所建構的電路
當 I=1 時產生 U1 及其連接線如圖 12 所示
圖12 I=1 時所建構的電路
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-28
當 I=2 時產生 U2 及其連接線如圖 13 所示
圖13 I=2 時所建構的電路
當 I=3 時產生 U3 及其連接線如圖 14 所示
圖14 I=3 時所建構的電路
專案設計
認識二進位計數器的工作原理以及描述的方式後請按下列步驟
設計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-1Counter4B)在中間欄位裡指定專
案名稱(Counter4B)再按 鈕切換到下一個對話盒若
所指定的資料夾不存在則會出現確認對話盒按 鈕關
閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-29
Step 2
在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
Step 5 按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
Counter4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-30
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 100ns再按 鈕使該段為 1再
按 + 鍵顯示整個波形如圖 15 所示
圖15 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-31
按 + 鍵顯示整個波形如圖 16 所示
圖16 模擬波形
Step 11
如圖 16 所示之波形很清楚地看出隨著 PulseIn 的升緣輸
出逐一增加完全符合預期
3-7-2 二進位上下數計數器設計
基本上若使用升緣觸發的 T 型正反器將前級的輸出 Q 連接到本
級的 CK則此電路將執行下數的動作若將前級的反相輸出 Q連接到
本級的 CK則此電路將執行上數的動作在 3-7-1 節中利用後者的連
接方式以建構上數計數器而在 3-7-1 節中也曾提及若改採用降緣
觸發的 T 型正反器則前級的反相輸出 Q連接到本級的 CK將執行下
數的動作當然找不到升緣觸發與降緣觸發同時存在的 T 型正反器
若要把升緣觸發的 T 型正反器改為降緣觸發 簡單的方式就是在進
入 CK 之前先串接一個反閘就相當於降緣觸發而整個計數器也將
變為下數計數器如圖 17 所示
圖17 下數計數器
在設計同時擁有上數與下數功能的計數器之前先認識一下互斥或閘
的功能如表 5 所示為其真值表
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-32
表 5 互斥或閘之真值表
輸 入 輸 出
A B Y
0 0 0
0 1 1
1 0 1
1 1 0
在表 5 裡若將 B 輸入 0時則此互斥或閘的輸出 Y 與輸入 A 完全
一樣此互斥或閘相當於一個緩衝器若將 B 輸入 1時則此互斥或閘
的輸出 Y 與輸入 A 相反此互斥或閘相當於一個反閘因此在圖 17
中的反閘改用互斥或閘其中的 B 腳全部連接起來做為外部控制上
下數的 UD 接腳如圖 18 所示當 UD=0時此電路為上數計數器當
UD=1時則此電路變成下數計數器如此一來這就是一個上 下數計
數器了
圖18 上 下數計數器
當然在 VHDL 裡大可不必為此建構一個互斥或閘只要應用互
斥或運算 xor 即可且原本在 3-7-1 節中的 D 型正反器(DFF1VHD3-23
頁)直接套用也不必修改而在主電路裡修改如下
Library IEEE
Use IEEEstd_logic_1164all
Entity UDC_4B is
Port( CL UDPulseInin std_logic
Qout std_logic_vector(3 downto 0))
End UDC_4B
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-33
Architecture ARCH of UDC_4B is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal TMP std_logic_vector(4 downto 0)
Begin
TMP(0) lt= PulseIn
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP(I) xor UD 1 Q(I) TMP(I+1))
End Generate
End ARCH
專案設計
認識上 下計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-2UDC_4B)在中間欄位裡指定專案
名稱(UDC_4B)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之 DFF1 描述一個 D 型正反器電
路再按 + 鍵在隨即出現的對話盒裡指定存
為 DFF1VHD 檔
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-34
Step 5
按 + 鍵在隨即出現的對話盒裡選取 VHDL File
選項指定開啟 VHDL 檔案再按 鈕即可開啟該檔
案並進入文字編輯環境
Step 6
在文字編輯環境裡按前述之四位元計數器電路再按
+ 鍵 在 隨 即 出 現 的 對 話 盒 裡 指 定 存 為
UDC_4BVHD 檔
Step 7 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 8 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-35
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1再
選取 UD 信號波形的 0 到 26us再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 19 所示
圖19 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 20 所示
圖20 模擬波形
Step 11
如圖 20 所示之波形雖然波形有點小但還是可以看出 26us
之前UD 信號為高態輸出 Q 波形呈現下數功能26us 之後
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-36
UD 信號為低態輸出 Q 波形呈現上數功能完全符合預期
3-7-3 除 N 計數器設計
在前面的單元裡我們所介紹的計數器多屬於二進位式的計數器
而其計數範圍都限於 2n例如 4 位元計數器之計數範圍為 0 到 15(即 24)
若要計數非 2n就需要額外的電路例如要計數 12則必須於 12(即 1100)
時將計數器歸零傳統的方法是將 Q3 與 Q2 信號引入及閘而及閘的
輸出接到各正反器的 CL 接腳做為清除信號之用如圖 21 所示
圖21 除 12 計數器
在 VHDL 的電路設計裡只要把主電路裡稍微修改則可如下
Library IEEE
Use IEEEstd_logic_1164all
Entity MOD12 is
Port( PulseInin std_logic
Qout std_logic_vector(3 downto 0))
End MOD12
Architecture ARCH of MOD12 is
Component DFF1
Port( CLCKTin std_logic
QQbarout std_logic)
End Component
Signal CL std_logic
Signal TMP1 std_logic_vector(4 downto 0)
Signal TMP2 std_logic_vector(3 downto 0)
Begin
TMP1(0) lt= PulseIn
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-37
LP1For I in 0 to 3 Generate
U DFF1 Port Map (CL TMP1(I) 1 TMP2(I) TMP1(I+1))
End Generate
CL lt= TMP2(3) and TMP2(2)
Q lt= TMP2
End ARCH
表面上看起來好像沒問題實際上風險很大這種非同步電路裡
傳輸延遲會累積而造成電路出現很多雜訊甚至錯誤動作
圖22 除 12 計數器模擬波形
如圖 22 所示0 變 1 時沒什麼雜訊1 變 2 時就有雜訊2 變 3
時沒什麼雜訊3 變 4 時就有雜訊而比較嚴重的是 11 之後應該是
0結果是 8這是因為 Q(3)與 Q(2)都為 1時清除信號 CL=1而 U2
先反應(被清除使 Q(2)= 1)當 U3 來不及反應時清除信號就變為0
這是我們始料未及之處
除了剛才所發現的困擾外這種設計方法比較沒有彈性例如計數
量改變時就要大費周章重新設計而 VHDL 設計所帶來的好處也沒
被展現實際上上數計數器可視為加 1 的運算每個脈波輸入進行
加 1 的運算同理下數計數器可視為減 1 的運算而 VHDL 在處理加
減運算並不困難至於要計數多少可直接把計數量當成判斷的條件
如此一來整個電路設計就簡單了
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity MOD_n is
Generic(countsstd_logic_vector(3 downto 0)= 1100)
Port( PulseInCLin std_logic
Qout std_logic_vector(3 downto 0))
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-38
End MOD_n
Architecture ARCH of MOD_n is
Constant widinteger range 0 to 15=4
Begin
Process(PulseInCL)
Variable TMP std_logic_vector(3 downto 0)
Begin
If CL=1 Then TMP = (TMPrange =gt 0)
Elsif Rising_Edge(PulseIn) Then
TMP = TMP + 1
If TMP=counts Then TMP = (TMPrange =gt 0)
End If
End If
Q lt= TMP
End Process
End ARCH
上述電路的說明如下
由於使用標準邏輯陣列的加法運算必須引用
std_logic_unsigned 套件
清除動作優先所以先以 If-Then 敘述判斷是否要清除 TMP 的
內容同樣地在此應用「TMP = (TMPrange =gt 0)」敘述將
TMP 的內容全部填入 0
若沒有清除動作才根據 PulseIn 脈波的升緣進行 TMP+1的
運算
緊接於 TMP+1之後再判斷 TMP 的值是否達到計數的上限若
達到計數的上限則將 TMP 歸零同樣是應用「TMP = (TMPrange
=gt 0)」敘述
結束 Process 之前把 TMP 的值放入輸出接腳 Q
專案設計
認識採用算術運算的計數器工作原理以及描述的方式後請按下
列步驟設計這個計數器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-39
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-3MOD_n)在中間欄位裡指定專案
名稱(MOD_n)再按 鈕切換到下一個對話盒若所指
定的資料夾不存在則會出現確認對話盒按 鈕關閉此
對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述之計數器(3-37 頁)電路輸入再
按 + 鍵在隨即出現的對話盒裡將它存為
MOD_nVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-40
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
指向 Q 信號按滑鼠右鍵拉下選單再選取 Properties 命令
在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 PulseIn 信號波形再按 鈕在隨即出現的對話盒裡
按 鈕關閉對話盒即可產生一個時脈信號
Step 8
選取 CL 信號波形的 0 到 200ns再按 鈕使該段為 1按
+ 鍵顯示整個波形如圖 23 所示
圖23 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-41
按 + 鍵顯示整個波形如圖 24 所示
圖24 模擬波形
Step 11
如圖 24 所示之波形很清楚地從 0 計數到 11 後再從 0 開
始計數完全符合預期
3-7-4 BCD 計數器設計
在 2-8-3 節裡曾介紹過 BCD 碼對七節顯示器之解碼器對人們而言還
是比較習慣 BCD 碼因此計數器也可以為 BCD 碼的計數器而 BCD 碼
的特色就是「逢十進位」基本上BCD 碼的數字只有 10 個即0000到
1001若出現1010時則進位為00010000相當於十進位的 10
在此將根據「逢十進位」的特性設計一個三位數之 BCD 計數器其計數
範圍為 000 到 999(九百九十九)且可直接以十進位數字設定計數量在此將
整個電路分為兩部分第一部分是十進位數字轉成 BCD 碼第二部分則是
BCD 計數以下就分別介紹這些電路的描述與工作原理
十進位數字轉成 BCD 碼
若所要指定的計數量為 n(在此將其初值設定為 168)則我們可先在
實體區利用 Generic 敘述指定其值如下
Generic( ninteger range 0 to 999 = 168)
在結構區裡分別將 n 的個位數十位數與百位數轉換成 n0n1
及 n2 等三個 std_logic_vector(3 downto 0)以做為計數時的判斷值而
在轉換的過程裡需先將 n 解析出百位數(Tmp2)十位數(Tmp1)及個位
數(Tmp0)其中 Tmp2~Tmp0 為臨時的信號屬於 0 到 9 之間的整數
因此在 Architecture 列與 Begin 列之間宣告下列信號
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-42
Signal n2n1n0 std_logic_vector(3 downto 0)
整個轉換的描述如下
Tmp2 lt= n100 -- 萃取出百位數在此為「1」
Tmp1 lt=(n10) rem 10 -- 萃取出十位數在此為「6」
Tmp0 lt=n rem 10 -- 萃取出個位數在此為「8」
Process(Tmp2Tmp1Tmp0)
Variable Outputstd_logic_vector(3 downto 0)
Variable Ainteger range 0 to 9
Begin
A=Tmp0
Dig0 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n0 lt= Output
----------------------------------------------------
A=Tmp1
Dig1 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n1 lt= Output
----------------------------------------------------
A=Tmp2
Dig2 For I in 0 to 3 Loop
If ((A mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
A = A2
End Loop
n2 lt= Output
End Process
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-43
首先將三個數分離如下說明
「Tmp2 lt= n100」敘述可將百位數抽出放入 Tmp2 之中以
n=168 為例n100=1所以百位數為 1Tmp2=1
「Tmp1 lt= (n10) rem 10」敘述可將十位數抽出放入 Tmp1
之中以 n=168 為例n10=16再把 16 除 10 取餘數(rem 為取
餘數之運算子)所以十位數為 6Tmp1=6
「Tmp0 lt= n rem 10」敘述可將個位數抽出放入 Tmp0 之中
以 n=168 為例n 除以 10 取餘數則為 8所以個位數為 8
Tmp0=8
緊接著將 Tmp2Tmp1 及 Tmp0 帶入 Process同樣分三次進行十進
位數字轉換二進位數字這個轉換動作是依據傳統手工轉換的方法也
就是連除法其轉換流程如圖 25 所示
除 2 之餘數
=1
除 2
Output(I)= 1 Output(I)= 0
4 次=
結 束
開 始
yes no
no
yes
圖25 十進位數字轉換二進位數字之轉換流程
首先進行個位數的轉換將個位數(Tmp0)放入 A 變數然後按圖 25
的流程進行轉換其中的「If ((A mod 2)=1) Then Output(I)= 1」敘述
只對 A 除 2 的結果(餘數)進行判斷並沒有把 A 除 2若餘數為 1則
該位元為 1否則該位元為 0而在判斷之後才進行真正的除 2 動作
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-44
完成 4 位元的轉換後將轉換結果(Output)放入 n0 裡
同樣的操作Tmp0 轉換完成後進行 Tmp1 的轉換而 Tmp1 轉換完
成後進行 Tmp2 的轉換直到 Tmp2 轉換完成整個轉換步驟才完成
BCD 計數
在計數器的電路描述裡因以時脈為主要的驅動信號也就是時脈
升緣的判斷應優先處理發現時脈的升緣之後就將個位數 (在此為
Digit0 變數)的計數值加 1緊接著判斷是否達到計數量的上限判斷是
百位數十位數與數位數必須都等於預設的計數量(即 n2n1 與 n0)
如下
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
如果達到預設的計數量就將計數量歸零如下
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
接下來以「Elsif」敘述進行未達到預設的計數量時就判斷個位
數是否為1010也就是 10 的意思若是 10則進位(Digit1+1)且將
個位數歸零如下
Elsif Digit0=1010 Then
Digit0 = 0000 -- 個位數歸零
Digit1 = Digit1 + 1 -- 十位數加1
十位數加 1就有可能使十位數超過 BCD 碼的範圍因此需再判
斷十位數是否為1010也就是 10 的意思若是 10則進位(Digit2+1)
且將十位數歸零如下
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
後再把計數量連接到輸出入埠即可整個電路描述如下
BCDcountProcess(CK)
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-45
Variable Digit2std_logic_vector(3 downto 0) = 0000
Variable Digit1std_logic_vector(3 downto 0) = 0000
Variable Digit0std_logic_vector(3 downto 0) = 0000
Begin
If Rising_Edge(CK) Then
Digit0 = Digit0 + 1
If (Digit0=n0) and (Digit1=n1) and (Digit2=n2) Then
Digit0 = 0000
Digit1 = 0000
Digit2 = 0000
Elsif Digit0=1010 Then
Digit0 = 0000
Digit1 = Digit1 + 1
If Digit1=1010 Then
Digit1 = 0000
Digit2 = Digit2 + 1
End If
End If
End If
Y0 lt= Digit0
Y1 lt= Digit1
Y2 lt= Digit2
End Process BCDcount
在 本 單 元 裡 所 要 設 計 的 電 路 裡 還 是 需 要 零 件 庫 特 別 是
std_logic_unsigned可不能漏掉而在 Architecture 列與 Begin 列之間
也宣告兩組信號其中 Tmp2Tmp1 及 Tmp0 信號以做為十進位數字
之暫存信號而 n2 n1 n0 信號以做為計數之範圍 (資料型態為
std_logic_vector)以做為計數範圍判斷之用如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDcounter is
Generic(ninteger range 0 to 999=168)
Port( CKin std_logic
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDcounter
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-46
Architecture ARCH of BCDcounter is
Signal Tmp2 Tmp1 Tmp0 integer range 0 to 9
Signal n2n1n0 std_logic_vector(3 downto 0)
Begin
將上面的描述加上 3-40 頁與 3-43 頁的描述就是完整的電路設
計了
專案設計
認識 BCD 計數器的工作原理以及描述的方式後請按下列步驟設
計這個計數器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-7ch3-7-4BCDcounter)在中間欄位裡指定專
案名稱(BCDcounter)再按 鈕切換到下一個對話盒
若所指定的資料夾不存在則會出現確認對話盒按 鈕
關閉此對話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-47
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 20us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕 關 閉 對 話 盒 即 可 產 生 一 個 時 脈 信 號 按
+ 鍵顯示整個波形如圖 26 所示
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-48
圖26 激勵信號設定完成
Step 8
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 9
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 27 所示
圖27 模擬波形
Step 10
如圖 27 所示之波形波形很小(時間太長)所以百位數與十位
數可以看得出來從 0 計數到 16再從 0 開始計數但個位
數看不清楚因此指向 160 左右的位置按住鍵再將滑鼠滾
輪往前推以放大顯示如圖 28 所示
圖28 放大關鍵波形
Step 11
如圖 28 所示之波形很清楚地從 167 之後就歸零完全符合
預期
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-49
BCD 加法器設計 3-8 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在 2-10 節裡所介紹的加法器屬於二進位的加法器當然人們比
較習慣的還是十進位數字在 3-7-4 節裡我們也介紹了 BCD 碼的計數
器對 BCD 碼也有一定程度的認識在此將以一個兩位數的 BCD 加法
器為例介紹其工作原理與電路描述
基本上BCD 加法器分為兩部分第一部分是整數加法把輸入的
兩個整數相加其敘述如下
Sum = A+B
不過其中 A 與 B 並不是任意的整數由於本設計的規格是進行兩
位數的加法所以 A 與 B 是 0 到 99 之間的整數我們將在實體裡宣告
如下
Port( ABin integer range 0 to 99
而兩數相加後的和 大可能為 198為了後續處理我們將在
Process 列與 Begin 列之間宣告一個 Sum 變數如下
Variable Suminteger range 0 to 200
待相加之後再將其和(Sum)分成個位數十位數與百位數並分別
將它們轉為 std_logic_vector整個電路描述如下
Library IEEE
Use IEEEstd_logic_1164all
Use IEEEstd_logic_unsignedall
Entity BCDadder is
Port( ABin integer range 0 to 99
Y2Y1Y0out std_logic_vector(3 downto 0))
End BCDadder
Architecture ARCH of BCDadder is
Begin
Process(AB)
Variable Suminteger range 0 to 200
Variable Outputstd_logic_vector(3 downto 0)
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-50
Variable TMPinteger range 0 to 9
Begin
Sum = A+B
TMP = Sum rem 10
Dig0 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y0 lt= Output
----------------------------------------------------
TMP = (Sum10) rem 10
Dig1 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y1 lt= Output
----------------------------------------------------
TMP = Sum100
Dig2 For I in 0 to 3 Loop
If ((TMP mod 2)=1) Then Output(I)= 1
Else Output(I)= 0
End If
TMP = TMP2
End Loop
Y2 lt= Output
End Process
End ARCH
專案設計
認識 BCD 加法器的工作原理以及描述的方式後請按下列步驟設
計這個加法器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-51
(dalterach3ch3-8BCDadder)在中間欄位裡指定專案名稱
(BCDadder)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 BCDcounterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-52
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 2us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Unsigned
Decimal 選項採十進位顯示按 鈕關閉對話盒
Step 7
選取 A 信號波形再按 鈕在隨即出現的對話盒裡將
Start Value 欄位設定為 25Increment by 欄位設定為 3如
圖 29 所示按 鈕關閉對話盒即可產生 2528hellip等
之激勵信號
圖29 設定計數式激勵信號
Step 8
同樣的方法將 B 信號波形之激勵信號設定為 5051hellip按
+ 鍵顯示整個波形如圖 30 所示
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-53
圖30 激勵信號設定完成
Step 9
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
Step 10
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 31 所示
圖31 模擬波形
Step 11
如圖 31 所示之波形0 到 1us 之間的波形分析如下
0 到 100ns25+50=75正確
100ns 到 200ns25+50=75正確
200ns 到 300ns28+51=79正確
300ns 到 400ns31+52=83正確
400ns 到 500ns34+53=87正確
500ns 到 600ns37+54=91正確
600ns 到 700ns40+55=95正確
700ns 到 800ns43+56=99正確
800ns 到 900ns46+57=103正確
900ns 到 10us49+58=107正確
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-54
移位暫存器設計 3-9 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
基本上移位暫存器 (Shift Register)是由 D 型正反器所組成如圖
32 所示為 4 位元的移位暫存器
圖32 基本四位元移位暫存器電路
移位暫存器提供資料旋轉 (或移位 )的功能此外我們也可規劃串
列輸入並列輸出(Serial In Parallel Out)並列輸入串列輸出(Parallel In
Serial Out)串列輸入串列輸出(Serial In Serial Out)並列輸入並列輸出
(Parallel In Parallel Out)等功能在本單元裡所要介紹的移位暫存器只提
供 4 個功能資料左旋(Rotate Left簡稱 RL)資料右旋 (Rotate Right
簡稱 RR)串列輸入並列輸出(簡稱 SIPO)並列輸入串列輸出(PISO)
而功能的選擇由 OP 信號決定如表 6 所示
表 6 移位暫存器功能
OP 功 能
00 並列輸入並列輸出 (PIPO)
01 資料右旋 (RR)
10 資料左旋 (RL)
11 串列輸入串列輸出 (SISO)
當 Load=1時即可由 Pi 接腳載入並列資料當 Load=0時才可
按 OP 信號進行指定的功能而這些功能將依據時脈 CK 的升緣觸發
很明顯的我們可依據圖 33 來宣告零件庫與定義實體如下
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-55
圖33 本單元所要設計的移位暫存器
Library IEEE
Use IEEEstd_logic_1164all
Entity SRegister is
Port( CKSiLoadin std_logic
OPin std_logic_vector(1 downto 0)
Piin std_logic_vector(7 downto 0)
Soout std_logic
Poout std_logic_vector(7 downto 0))
End SRegister
在此所要展現四個功能如下說明
並列輸入並列輸出(OP=00)
此功能是隨時脈的升緣將並列輸入資料載入暫存器再由暫存器送至
並列埠輸出所以其描述包括兩個動作首先載入並列輸入的資料到暫
存器再由暫存器送到並列埠輸出即可如下
RegT = Pi
Po lt= RegT
資料右旋(OP=01)
此功能是隨時脈的升緣將暫存器內資料向右旋轉也就是由 MSB(B7)
向 LSB(B0)移位而 LSB 再移入 MSB如圖 34 所示
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-56
圖34 資料右旋示意圖
為了描述這個動作可利用amp連接運算符號將 RegT(0)與 RegT(7 downto 1)
連接再送回 RegT即完成右旋的動作 後再將 RegT 經由 Po 輸出
如下
RegT = RegT(0) amp RegT(7 downto 1)
Po lt= RegT
資料左旋(OP=10)
此功能是隨時脈的升緣將暫存器內資料向左旋轉也就是由 LSB(B0)
向 MSB(B7)移位而 MSB 再移入 LSB如圖 35 所示
圖35 資料左旋示意圖
為了描述這個動作還是利用amp連接運算符號將 RegT(6 downto 0)與
RegT(7)連接再送回 RegT即完成左旋的動作 後再將 RegT 經由 Po
輸出如下
RegT = RegT(6 downto 0) amp RegT(7)
Po lt= RegT
串列輸入串列輸出(OP=11)
此功能是隨時脈的升緣將 MSB 經由 So 輸出再將暫存器內的資料左移
而串列輸入 Si 的資料移入 LSB如圖 36 所示而整個動作的描述如下
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-57
圖36 串列輸入串列輸出示意圖
So lt= RegT(7)
RegT RegT(6 downto 0) amp Si
Po lt= RegT
了解這四個功能及其電路描述後再把整個電路設計的結構部分列
出如下
Architecture ARCH of SRegister is Begin Process(CKOPLoad) Variable RegT std_logic_vector(7 downto 0) Begin If Load=1 Then RegT =Pi Elsif Rising_Edge(CK) Then Case OP is When 00 =gt -- PiPo RegT = Pi Po lt= RegT When 01 =gt -- RR RegT = RegT(0) amp RegT(7 downto 1) Po lt= RegT When 10 =gt -- RL RegT = RegT(6 downto 0) amp RegT(7) Po lt= RegT When others =gt-- SiSo So lt= RegT(7) RegT RegT(6 downto 0) amp Si Po lt= RegT End Case End If End Process End ARCH
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-58
專案設計
認識移位暫存器的工作原理以及描述的方式後請按下列步驟設
計這個移位暫存器
Step 1
在 Quartus II 裡啟動 FileNew Project Wizard 命令螢幕出現
專案精靈在 上面的欄位裡指定此專案所要存放的位置
(dalterach3ch3-9SRegister)在中間欄位裡指定專案名稱
(SRegister)再按 鈕切換到下一個對話盒若所指定
的資料夾不存在則會出現確認對話盒按 鈕關閉此對
話盒即可自動建立此資料夾並切換到下一個對話盒
Step 2 在此不需指定零件庫所以按 鈕切換到下一個對話
盒指定所要設定的晶片(即 EP3C10E144C8)再按
鈕結束專案精靈
Step 3 緊接著開啟新的 VHDL 檔案按 + 鍵在隨即出
現的對話盒裡選取 VHDL File 選項指定開啟 VHDL 檔案
再按 鈕即可開啟該檔案並進入文字編輯環境
Step 4
在文字編輯環境裡按前述電路輸入再按 +
鍵在隨即出現的對話盒裡指定存為 SRegisterVHD 檔
Step 5 按 + 鍵即可進行初始編譯這個電路不難很快
地完成編譯並開啟 Compilation Report 頁以記錄編譯結
果另外也將出現一個確認對話盒
Step 6 編譯過程中沒有錯誤雖有警告訊息但不會影響結果按
鈕關閉對話盒即可
電路模擬
完成一次編譯後接續按下列步驟進行電路模擬
Step 1
按 + 鍵開啟新檔在隨即出現的對話盒裡選取
Vector Waveform File 選項指定開啟波形檔再按
鈕即可開啟波形視窗
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-59
Step 2
指向波形視窗左邊區塊裡按滑鼠右鍵拉下選單再選取
InsertInsert Node or Bus 命令在隨即開啟的對話盒裡按
鈕開啟 Node Finder 對話盒按其右上角的
鈕即可將電路圖中的輸出入埠列入左邊 Nodes Found 區
塊即為搜尋到的節點再按中間的 鈕即可將所有節
點複製到右邊的 Selected Nodes 區塊做為所要追蹤的節點
Step 3
按 鈕關閉對話盒退回前一個對話盒再按
鈕關閉對話盒則所選取的節點信號將出現在波形視窗裡
Step 4
啟動 EditEnd Time 命令在隨即出現的對話盒裡將 Time 欄位
裡的模擬時間長度設定為 5us再按 鈕關閉對話盒即可
Step 5
啟動 EditGrid Size 命令在隨即出現的對話盒裡將 Period
欄位裡的模擬格點間距設定為 100ns再按 鈕關閉對
話盒即可再按 + 鍵顯示整個波形
Step 6
選取全部信號按滑鼠右鍵拉下選單再選取 Properties 命
令在隨即開啟的對話盒裡選取 Radix 欄位裡的 Binary 選
項採二進位顯示按 鈕關閉對話盒
Step 7
選取 CK 信號波形再按 鈕在隨即出現的對話盒裡按
鈕關閉對話盒即可產生週期為 100ns 之時脈
Step 8
選取 Load 信號波形之 0~200ns再按 鈕將該段設定為 1
Step 9
選取 OP 信號波形再按 鈕開啟如圖 37 所示之對話盒在
Counting 頁裡Start value 欄位保持為 00Increment by 欄位保
持為 1切換到 Timing 頁在 Count every 欄位裡設定為 125us
也就是每 125us 加 1再按 鈕關閉對話盒
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-60
圖37 設定計數式激勵信號
Step 10
選取 Pi 信號波形按 鈕在隨即出現的對話盒裡選取
Every grid interval 選項再按 鈕關閉對話盒以產
生亂數之激勵信號設定同樣地將 Si 信號波形也設定為亂
數 後按 + 鍵顯示整個波形如圖 38 所示
Step 11
一切都備妥按 + 鍵然後在隨即出現的存檔對
話盒裡直接按 鈕存檔
圖38 激勵信號設定完成
Step 12
若要進行模擬則按波形視窗上方中間的 鈕程式即進行
模擬若沒問題將出現確認對話盒按 鈕關閉對
話盒同時也產生 Simulation Report 頁其中為模擬的結果
按 + 鍵顯示整個波形如圖 39 所示
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-61
圖39 模擬波形
Step 13
首先分析 0 到 125us 之間的波形也就是 OP 信號為00將
波形放大足以看清楚這段如圖 40 所示
圖40 顯示 OP=00之模擬波形
Step 14
在圖 40 裡約 0 到 200ns 之間Load 信號為1電路將 Pi 信
號載入暫存器但沒有輸出到 Po所以 Po 保持為0000
在 250ns 時(標示虛線)偵測到 CK 時脈的升緣此時 Pi 信
號(01000000)將由 Po 輸出同樣地分別在 350ns450ns
550ns 等位置都是 CK 時脈的升緣而在這些點上也正是
Po 的內容改變為輸出 Pi 信號值表示當 OP 信號為00時
Pi 信號將送至 Po 端輸出
Step 15
再移至 125us 之後的波形也就是 OP 信號為01將波形放
大足以看清楚這段如圖 41 所示
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-62
圖41 顯示 OP=01之模擬波形
Step 16
在圖 41 裡在 135us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11111101變成11111110資料右旋了在
145us 處Po 信號由11111110變成01111111同樣地分
別在 155us165us 等位置Po 的輸出值都分別右旋一位
表示當 OP 信號為01時Po 信號確實右旋
Step 17
再移至 250us 之後的波形也就是 OP 信號之值為10將波
形放大足以看清楚這段如圖 42 所示
圖42 顯示 OP=10之模擬波形
Step 18
在圖 42 裡在 255us 時(標示虛線)偵測到 CK 時脈的升緣
此時 Po 信號由11011111變成10111111資料左旋了在
265us 處Po 信號由10111111變成01111111同樣地分
別在 275us285us 等位置Po 的輸出值都分別左旋一位
表示當 OP 信號為01時Po 信號確實左旋
Step 19
再移至 375us 之後的波形也就是 OP 信號之值為11將波
形放大足以看清楚這段如圖 43 所示
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
第三章 時序邏輯電路設計
3-63
圖43 顯示 OP=11之模擬波形
Step 20
在圖 43 裡在 385us 時(標示虛線)Po 信號之值為11111011
Si 信號之值為1偵測到 CK 時脈的升緣後Po 信號的 MSB(值
為1)移入 So 端且 Po 信號全部左移Si 信號(1)填入 Po 的 LSB
使 Po 信號之值變成11110111同樣地分別在 395us405us
等位置也有同樣的移入串列信號移出串列信號動作表示
OP 信號之值為11時這個移位暫存器確實進行 SiSo
即時練習 3-10 FFFPPP GGGAAA 設設設 計計計 實實實 務務務
在本章裡以時序性敘述為主要闡述的對象並以幾種較具代表性
的時序電路元件特別是正反器大部分時序電路都是以正反器為基礎
所建構的例如計數器就是以 JK 正反器或 T 型正反器為基礎零件而
暫存器記憶體就是以 D 型正反器為基礎零件在此請試著回答下列問
題以確認對本單元已有相當的認識
( )1 下列何者為Process結構的功能 (A) 每個Process結構可視為一個特
定功能的電路區塊 (B) Process結構與Process結構之間為時序性敘述
(C) Process 結構內部為共時性敘述 (D) 以上皆非
( )2 在 Process 裡的敏感信號列具有什麼功能 (A) 避免錯誤動作發生
(B) 該 Process 所能接受的信號種類 (C) 防止信號變化時所引起的雜
訊 (D) 觸發 Process 內部動作
( )3 在電路敘述之中「null」提供什麼功能 (A) 停止執行 (B) 什麼
事都不做 (C) 暫停一切動作 (D) 以上皆非
( )4 關於 If-Then-Else 敘述下列何者正確 (A) 此為時序性敘述
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器
FPGA 設計實務
3-64
(B) 必須在 Process 或副程式中才能使用 (C) 可使用巢狀結構
敘述 (D) 以上皆是
( )5 關於「clkeven and clk=1」敘述下列何者正確
(A) 偵測 clk 信號的降緣 (B) 當 clk 信號有所變化時則將它
設定為 1 (C) 等同「Rising_Edge(clk)」敘述 (D) 以上皆是
( )6 下列何者不是時序性敘述 (A) For-Loop 敘述 (B) For-Generate
敘述 (C) If-Then-Else 敘述 (D) Case-When 敘述
( )7 RS 正反器與 JK 正反器之不同為何 (A) 完全一樣沒有不同
(B) RS 正反器不能用於計數器JK 正反器用於計數器 (C) 當輸入
11時RS 正反器不允許JK 正反器將切換輸出 (D) 當輸入00
時RS 正反器將切換輸出但 JK 正反器不允許
( )8 下列哪種正反器不必接任何邏輯閘即可完成取代 T 型正反器
(A) D 型正反器 (B) RS 正反器 (C) JK 正反器 (D) 以
上皆可
( )9 Generic敘述與Generic Map敘述的功能為何 (A) 傳遞參數 (B) 映
對連接接腳 (C) 宣告變數 (D) 宣告信號
( )10 若要使用降緣觸發之 T 型正反器建構一個四位元上數計數器正反器
與正反器之間應如何連接 (A) 前級輸出接到本級之時脈輸
入 (B) 前級反相輸出接到本級之時脈輸入 (C) 前級輸出連接
一個反閘反閘的輸出再到本級之時脈 (D) 以上皆非
1 在 3-7-4 節之 BCD 計數器裡先將整數轉換為 std_logic_vector再進行計數
器功能若要先進行計數再轉換為 std_logic_vector應如何修改
2 試修改 3-7-4 節之 BCD 計數器使之具有上下數功能的 BCD 計數器
3 試修改 3-8 節之 BCD 加法器使之為為 BCD 加減法器
4 試設計一個能將 8 位元並列資料左右翻轉後並列輸出的暫存器