<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 從VHDL代碼到真實(shí)硬件:設(shè)計(jì)有限狀態(tài)機(jī)

          從VHDL代碼到真實(shí)硬件:設(shè)計(jì)有限狀態(tài)機(jī)

          作者: 時(shí)間:2024-09-02 來源:EEPW編譯 收藏

          學(xué)習(xí)如何通過創(chuàng)建一個(gè),在VHDL中實(shí)現(xiàn)。編譯后,它將在連接到帶有輸入開關(guān)和LED顯示器的自定義PCB的Altera CPLD開發(fā)板上運(yùn)行。

          本文引用地址:http://www.ex-cimer.com/article/202409/462551.htm

          本項(xiàng)目是我“從到真實(shí)硬件”系列的第二部分,在該系列中,我們使用基于硬件的方法和可編程邏輯IC設(shè)計(jì)簡(jiǎn)單的電子系統(tǒng)。這些系統(tǒng)為重要設(shè)計(jì)概念提供了極好的介紹,這些概念也可以應(yīng)用于更復(fù)雜的項(xiàng)目。

          項(xiàng)目概述

          在這個(gè)項(xiàng)目中,我將介紹(FSM)的開發(fā)。具體來說,我將構(gòu)建一個(gè),帶有四個(gè)輸出LED和一個(gè)四位DIP開關(guān)模式輸入

          邏輯將使用VHDL(一種硬件描述編程語言)編寫,并上傳到復(fù)雜可編程邏輯(CPLD)芯片。CPLD是一種可重復(fù)編程的現(xiàn)成邏輯門IC,類似于FPGA。

          本項(xiàng)目將使用與我之前設(shè)計(jì)的8位算術(shù)邏輯單元(ALU)相同的硬件和軟件設(shè)置:

          1.png

          Altera Max II EPM240 CPLD開發(fā)板,

          英特爾的Quartus Prime Lite版IDE。

          如果您想復(fù)習(xí)可編程邏輯集成電路和Quartus Prime套件的基礎(chǔ)知識(shí),您需要查看之前的項(xiàng)目。

          什么是有限狀態(tài)機(jī)?

          在深入設(shè)計(jì)之前,我們先快速回顧一下有限狀態(tài)機(jī)。有限狀態(tài)機(jī)是順序邏輯電路的抽象數(shù)學(xué)模型,在任何給定時(shí)刻,它只能在有限數(shù)量的狀態(tài)中運(yùn)行。

          FSM可以在每個(gè)時(shí)鐘周期在其狀態(tài)之間轉(zhuǎn)換一次。下一個(gè)狀態(tài)基于外部輸入和當(dāng)前狀態(tài)(這意味著它使用了記憶邏輯)。

          有限狀態(tài)機(jī)可用于檢測(cè)或生成序列,是電梯、交通燈、自動(dòng)售貨機(jī)和電子鎖等系統(tǒng)的基礎(chǔ)。

          二進(jìn)制計(jì)數(shù)器

          有限狀態(tài)機(jī)(FSM)的一種特殊實(shí)現(xiàn)是二進(jìn)制計(jì)數(shù)器。這些電路的設(shè)計(jì)目標(biāo)是迭代并顯示所需的二進(jìn)制數(shù)序列,通常使用一系列相互連接的觸發(fā)器構(gòu)建。二進(jìn)制計(jì)數(shù)器的每個(gè)新狀態(tài)都必須由輸入脈沖觸發(fā),該脈沖可以來自外部源或電路自己的時(shí)鐘信號(hào)。

          有了這些背景知識(shí),讓我們深入了解一下的代碼。

          FSM二進(jìn)制計(jì)數(shù)器的

          我們將在VHDL文件的頂部聲明幾個(gè)庫,開始為二進(jìn)制計(jì)數(shù)器編寫代碼:

           2.png

          港口定義

          接下來,我們將為我們的電路創(chuàng)建一個(gè)名為fsm的實(shí)體,并定義其輸入和輸出端口:

          3.png

          在此代碼片段中,我們定義了:

           4.png

          流程和數(shù)據(jù)類型定義

          既然我們已經(jīng)定義了FSM實(shí)體,我們就可以為我們的電路創(chuàng)建一個(gè)架構(gòu)。這個(gè)架構(gòu)將有三個(gè)過程:

          狀態(tài)記憶。

          下一個(gè)狀態(tài)邏輯。

          輸出邏輯。

          在創(chuàng)建這些進(jìn)程之前,我們需要為我們的狀態(tài)定義一個(gè)新的數(shù)據(jù)類型,并為該數(shù)據(jù)類型定義兩個(gè)信號(hào)變量,用于記憶當(dāng)前狀態(tài)和下一個(gè)狀態(tài)(將它們視為寄存器)。

          狀態(tài)記憶過程

          現(xiàn)在我們可以創(chuàng)建第一個(gè)名為STATE_MEMORY的進(jìn)程。使用IF語句,它會(huì)在CLK信號(hào)的每個(gè)上升沿將下一個(gè)狀態(tài)的值寫入當(dāng)前狀態(tài)變量。

          下一個(gè)狀態(tài)邏輯過程

          我們將使用SEL輸入端口和CURRENT_STATE信號(hào)創(chuàng)建一個(gè)名為NEXT_STATE_LOGIC的進(jìn)程。在這個(gè)進(jìn)程中,我們?yōu)楫?dāng)前狀態(tài)調(diào)用一個(gè)CASE-WHEN語句。我們?cè)诘谝粋€(gè)CASE-WHEN語句的每個(gè)WHEN子句中嵌套其他CASE-WHEN語句以用于模式。

          這樣,我們就有了一個(gè)架構(gòu),它首先檢查FSM的當(dāng)前狀態(tài),然后從SEL端口讀取值。當(dāng)這個(gè)過程完成時(shí),最后一個(gè)嵌套的WHEN子句將根據(jù)我們的代碼(對(duì)正在計(jì)數(shù)的序列)將正確的下一個(gè)狀態(tài)值寫入NEXT_STATE信號(hào)

          下面的代碼塊顯示了一個(gè)簡(jiǎn)單的向上計(jì)數(shù)器,當(dāng)SEL端口值等于“0000”時(shí),該計(jì)數(shù)器處于活動(dòng)狀態(tài)。為了簡(jiǎn)潔起見,這里只顯示了一些重復(fù)的case語句,但完整的代碼將在下面提供。

          5.png

          跳過案例,C3到C13是相似的,我們到達(dá)NEXT_STATE_LOGIC過程的末尾,我們有:

           6.png

          輸出邏輯流程

          最后,為了在4位LED顯示屏上輸出當(dāng)前狀態(tài),我們需要編寫另一個(gè)名為OUTPUT_LOGIC的進(jìn)程。它枚舉了我們之前定義的每種狀態(tài)類型,并配以相應(yīng)的4位二進(jìn)制數(shù)。

          這同樣是通過使用CURRENT_STATE信號(hào)并調(diào)用另一個(gè)CASE-WHEN語句來完成的。CNT輸出表示當(dāng)前狀態(tài)作為其4位二進(jìn)制對(duì)應(yīng)物:

           7.png

          編譯代碼

          編寫代碼后,我們首先需要編譯它。然后,我們必須使用Quartus的Pin Planner工具,將我們?cè)诔绦蛑卸x的端口分配到Altera CPLD的物理引腳上,使用表1中顯示的映射。

          表1. 端口到引腳映射

           8.png

          上傳到開發(fā)板

          接下來,我們需要再次編譯代碼,然后才能最終將其上傳到開發(fā)板上。此過程是使用通過JTAG連接到Altera MAX II的USB Blaster進(jìn)行的,如圖1所示。

          Altera板和USB Blaster連接

          9.png

          圖1. Altera板和USB Blaster連接。圖片由Kristijan Nelkovski提供

          添加外部觸發(fā)器

          將代碼上傳到Altera板后,我們需要添加一個(gè)時(shí)鐘信號(hào)——某種類型的外部觸發(fā)器,使我們的計(jì)數(shù)器能夠遍歷其狀態(tài)。在這里,我要稍微作弊一下,使用運(yùn)行默認(rèn)Arduino Blink草圖的Raspberry Pi Pico,它充當(dāng)我們電路的粗糙時(shí)鐘源。

          您可以使用任何其他MCU開發(fā)板來實(shí)現(xiàn)此功能;只需確保向Altera MAX II發(fā)送3.3 V邏輯電平信號(hào)即可。Raspberry Pi Pico本身輸出3.3 V邏輯信號(hào)。

          在我們的電路中,Blink草圖將提供0.5 Hz的時(shí)鐘信號(hào)(您可以在Arduino代碼的延遲部分更改頻率)。它不會(huì)讓LED閃爍一秒鐘,然后再熄滅一秒鐘,而是告訴我們的同步電路何時(shí)切換到其下一個(gè)狀態(tài),如我們的中所定義。

          PCB電路圖

          圖2中的示意圖顯示了項(xiàng)目的完整電路圖。在這里,每個(gè)LED都通過限流電阻連接到輸出引腳,連接到輸入引腳的DIP開關(guān)的每個(gè)觸點(diǎn)都通過電阻網(wǎng)絡(luò)下拉到地。然后,時(shí)鐘引腳連接到運(yùn)行Blink的微控制器板上的假定LED引腳。

          4位二進(jìn)制計(jì)數(shù)器項(xiàng)目的電路原理圖

           10.png

          圖2:4位二進(jìn)制計(jì)數(shù)器項(xiàng)目的電路示意圖。圖片由Kristijan Nelkovski提供

          在將所有東西連接起來并為電路提供足夠的電源后,我們的FSM計(jì)數(shù)器應(yīng)根據(jù)通過DIP開關(guān)選擇的計(jì)數(shù)模式,開始在其四個(gè)LED上迭代不同的二進(jìn)制序列。

          設(shè)計(jì)其他計(jì)數(shù)序列

          對(duì)于SEL輸入的其他值,您可以創(chuàng)建任意4位數(shù)字序列。在本文末尾的完整代碼下載中,我包含了16種計(jì)數(shù)模式,可以使用表2中描述的4位SEL輸入進(jìn)行選擇。

          表2. 計(jì)數(shù)模式的SEL控制

           11.png

          注意:從技術(shù)上講,斐波那契數(shù)列應(yīng)該重復(fù)出現(xiàn)1,但在這個(gè)簡(jiǎn)單的項(xiàng)目中,這些序列中只有一個(gè)1。

          物料清單

          表3包含項(xiàng)目物料清單(BOM)。

           12.png

          表3. 4位計(jì)數(shù)器物料清單。

          輪到你了!

          在這個(gè)項(xiàng)目中,我們使用VHDL硬件描述語言創(chuàng)建了一個(gè)有限狀態(tài)機(jī)電路,并在CPLD開發(fā)板上運(yùn)行。本系列文章的目標(biāo)是介紹可編程邏輯,并使用真實(shí)硬件而不是電路圖和計(jì)算機(jī)模擬來深入了解FPGA組件的實(shí)際使用。

          如果你復(fù)制這個(gè)項(xiàng)目,你可以隨時(shí)修改代碼,切換計(jì)數(shù)模式,或者根據(jù)需要添加和刪除不同的序列。在下面的評(píng)論中分享你的想法和修改!




          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();