+ All Categories
Home > Documents > 時序邏輯電路設計 -...

時序邏輯電路設計 -...

Date post: 30-Aug-2019
Category:
Upload: others
View: 8 times
Download: 0 times
Share this document with a friend
64
時序邏輯電路設計 本章內容豐富,可分為下列兩部分: VHDL 部分: 認識 Process 敘述。 認識 Generic 敘述、If-Then-Else 敘述、Case-When 敘述及 Loop 敘述。 電路設計與模擬部分: 應用 VHDL 設計/模擬各式正反器。 應用 VHDL 設計/模擬計數器、BCD 加法器與移位暫存器等。
Transcript
Page 1: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

時序邏輯電路設計 本章內容豐富可分為下列兩部分

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 2: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 3: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 4: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 5: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 6: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 7: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 8: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與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 位元並列資料左右翻轉後並列輸出的暫存器

Page 9: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 10: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 11: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 12: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 13: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 14: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 15: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 16: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 17: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 18: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 19: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 20: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 21: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 22: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 23: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 24: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 25: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 26: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 27: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 28: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 29: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 30: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 31: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 32: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 33: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 34: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 35: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 36: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 37: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 38: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 39: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 40: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 41: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 42: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 43: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 44: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 45: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 46: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 47: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 48: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 49: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 50: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 51: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 52: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 53: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 54: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 55: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 56: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 57: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 58: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 59: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 60: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 61: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 62: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 63: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

第三章 時序邏輯電路設計

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 位元並列資料左右翻轉後並列輸出的暫存器

Page 64: 時序邏輯電路設計 - b2.hlvs.ylc.edu.twb2.hlvs.ylc.edu.tw/ezfiles/3/1003/img/106/20140421084907.pdf · 第三章 時序邏輯電路設計 3-3 變數的宣告 在Process 列與Begin

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 位元並列資料左右翻轉後並列輸出的暫存器


Recommended