
零基礎(chǔ)學(xué)FPGA(??)?步?腳印之基于FIFO的串?發(fā)送機(jī)
設(shè)計(jì)全流程及常見錯(cuò)誤詳解
今天要寫的是?段基于的串?發(fā)送機(jī)設(shè)計(jì),之前也寫過串?發(fā)送的電路,這次寫的與上次的有?分類似。這段代碼也是我看過別?寫過的
之后,消化?下再根據(jù)??的理解寫出來的,下?是我寫這段代碼的全部流程和思路,希望對(duì)剛開始接觸的朋友來說有?點(diǎn)點(diǎn)的幫助,也希
望有經(jīng)驗(yàn)的朋友給予寶貴的建議。
?先來解釋?下的含義,就是FirstInputFirstOutput的縮寫,就是先?先出的意思,按照我的理解就是,先進(jìn)去的數(shù)據(jù)先出,例如?個(gè)
數(shù)組的?位先進(jìn),那么讀出來的時(shí)候也就?位先出。下?是百度百科的解釋。
FIFO?般?于不同時(shí)鐘域之間的數(shù)據(jù)傳輸,?如FIFO的?端是AD數(shù)據(jù)采集,另?端是計(jì)算機(jī)的PCI總線,假設(shè)其AD采集的速率為16位
100KSPS,那么每秒的數(shù)據(jù)量為100K×16bit=1.6Mbps,?PCI總線的速度為33MHz,總線寬度32bit,其最?傳輸速率為1056Mbps,在兩個(gè)不
同的時(shí)鐘域間就可以采?FIFO來作為數(shù)據(jù)緩沖。另外對(duì)于不同寬度的數(shù)據(jù)接?也可以?FIFO,例如單?機(jī)位8位數(shù)據(jù)輸出,?DSP可能是
16位數(shù)據(jù)輸?,在單?機(jī)與DSP連接時(shí)就可以使?FIFO來達(dá)到數(shù)據(jù)匹配的?的。
下?我們開始設(shè)計(jì)。
這次設(shè)計(jì)我們要設(shè)計(jì)?個(gè)串?發(fā)送機(jī),想?下的話,我們要發(fā)送數(shù)據(jù),總得有?個(gè)數(shù)據(jù)產(chǎn)?模塊和數(shù)據(jù)發(fā)送模塊吧。好,那么在我們的
腦海?就出現(xiàn)了這兩個(gè)模塊。由于我們這次是借?Altera公司提供的IP核FIFO來完成,所以要加?這個(gè)模塊,這個(gè)模塊作為?個(gè)數(shù)據(jù)緩沖
器,需要我們例化,等會(huì)我們按照思路來例化它。
好,模塊出來了,我們將這三個(gè)模塊分別定義為dataoutput塊,fifo_ctrl塊和uart_ctrl塊。現(xiàn)在考慮連線。我個(gè)?感覺在設(shè)計(jì)之前,把要
設(shè)計(jì)的東西在草稿紙上將?體框圖畫出來,具體到每?根連線,這樣根據(jù)圖來寫代碼要?直接?腦?構(gòu)圖要?便的多。三個(gè)模塊,先考慮時(shí)
鐘和復(fù)位信號(hào)線,三個(gè)模塊都有,然后,數(shù)據(jù)產(chǎn)?模塊要將產(chǎn)?的數(shù)據(jù)發(fā)給FIFO模塊,所以要有數(shù)據(jù)寫?線,我們定義它為wr-datain,數(shù)
據(jù)寫?FIFO塊后總要輸出,這些數(shù)據(jù)就是我們要發(fā)送的數(shù)據(jù),所以定義輸出數(shù)據(jù)線tx_data,先不管FIFO,我們?cè)賮矶x數(shù)據(jù)發(fā)送模塊的連
線,數(shù)據(jù)發(fā)送總要有個(gè)啟動(dòng)信號(hào),所以我們定義變量tx_start,之后,還要有?個(gè)輸出端給PC機(jī),我們定義這個(gè)輸出端位rs232,對(duì)于FIFO
模塊的例化過程很簡(jiǎn)單就不做過多的說明,只把接?說?下,F(xiàn)IFO模塊除了時(shí)鐘,復(fù)位信號(hào)外,還有數(shù)據(jù)輸?端?,這個(gè)端?要和之前的數(shù)
據(jù)產(chǎn)?模塊的數(shù)據(jù)輸出端?相連,還有寫請(qǐng)求端?,?電平有效,數(shù)據(jù)發(fā)送模塊每隔1秒鐘產(chǎn)??個(gè)16位的數(shù)據(jù),并發(fā)送寫請(qǐng)求命令給
FIFO,還有讀請(qǐng)求命令,?電平有效數(shù)據(jù)發(fā)送模塊在發(fā)送數(shù)據(jù)時(shí)要發(fā)送?個(gè)讀請(qǐng)求給FIFO,從中讀取數(shù)據(jù)后再發(fā)送給PC機(jī),還有空信號(hào)
empty,只要檢測(cè)到FIFO中有數(shù)據(jù),empty就為低電平,我們可?這個(gè)信號(hào)來啟動(dòng)數(shù)據(jù)發(fā)送模塊。這樣?來,我們的整體框架就出來了有了
這個(gè)整體框架,再寫代碼就容易多了。
下?是RTL視圖
下?我們來寫代碼
按照這個(gè)框架,先把接?定義出來,中間的連線?wire型
設(shè)計(jì)完端?之后我們就來設(shè)計(jì)底層模塊,先設(shè)計(jì)數(shù)據(jù)產(chǎn)?模塊dataoutput
這個(gè)部分主要是產(chǎn)?數(shù)據(jù),可??個(gè)分頻電路實(shí)現(xiàn)每1s發(fā)送?次的數(shù)據(jù),產(chǎn)?這16位數(shù)據(jù)的時(shí)候,需要16個(gè)時(shí)鐘,每個(gè)時(shí)鐘數(shù)據(jù)?加
1,總體來說?較簡(jiǎn)單
寫完?個(gè)模塊之后養(yǎng)成好習(xí)慣,馬上把端?例化
數(shù)據(jù)產(chǎn)?以后就要進(jìn)?緩沖器FIFO,由于這段代碼我們是調(diào)?的,所以只要例化接?就好了,只需要將產(chǎn)?的fifo_ctrl_inst?件中例化
好的代碼拷貝粘貼就好
最后我們要寫數(shù)據(jù)發(fā)送部分
之前已經(jīng)講過,數(shù)據(jù)發(fā)送部分還要包括兩個(gè)?模塊,?個(gè)是波特率匹配模塊,?個(gè)是發(fā)送模塊,既然?包括兩個(gè)?模塊,那么我們還要
構(gòu)建?個(gè)框圖
按照之前的例?,當(dāng)FIFO當(dāng)中有數(shù)據(jù)時(shí)empty就會(huì)拉低,我們把它取反后送給發(fā)送模塊,告訴發(fā)送模塊準(zhǔn)備發(fā)送,這樣,發(fā)送模塊就會(huì)
產(chǎn)??個(gè)波特率計(jì)數(shù)器啟動(dòng)信號(hào)bps_start給波特率匹配模塊,波特率匹配模塊收到信號(hào)后?馬開始匹配計(jì)數(shù),并產(chǎn)?采集信號(hào),將采集信號(hào)
傳給發(fā)送模塊,發(fā)送模塊根據(jù)采集信號(hào),將數(shù)據(jù)?位?位發(fā)送出去。知道了這個(gè)原理之后,我們構(gòu)建起這樣?個(gè)框架
根據(jù)這個(gè)框圖,我們定義端?和線
定義完端?之后,開始寫發(fā)送模塊,?邊沿脈沖檢測(cè)法檢測(cè)啟動(dòng)信號(hào)tx_start信號(hào)的上升沿來啟動(dòng)發(fā)送部分,波特率配置模塊具體代碼在
前?也?章中有給出,就不在說明,寫完之后例化端?,這兩個(gè)模塊作為數(shù)據(jù)發(fā)送模塊的?模塊,要在數(shù)據(jù)發(fā)送模塊下例化
這樣?來,我們整個(gè)設(shè)計(jì)就完成了,看上去很簡(jiǎn)單,但是從我??實(shí)踐的?度來說還是有點(diǎn)挑戰(zhàn)的,包括中間出現(xiàn)的各種問題,下?就
來分享?下我在做這個(gè)設(shè)計(jì)時(shí)遇到的問題
1.例化問題
在例化端?時(shí),要注意括號(hào)??的才是本層模塊的端?,也就是說在本層模塊上?已經(jīng)定義過的變量,括號(hào)外?的才是被調(diào)?模塊的端
?,也在下層模塊的頂部被聲明,我在寫這段程序的時(shí)候?qū)?者顛倒了,導(dǎo)致連線不成功,最終是通過查看RTL視圖知道了哪根線有問題才
修改成功的
2.同?個(gè)變量不能在多個(gè)always語句中被賦值
我們可能習(xí)慣這么寫
always@(podgeclkornegedgerst_n)
if(!rst_n)num<=1'b0;
elnum<=num+1'b1;
那么,num的值在其他always語句中就不允許再被賦值或者清零,我在寫的時(shí)候在其他always語句中將num清零了,導(dǎo)致編譯不成功
3.定義變量之前不要出現(xiàn)該變量,即使后??定義了
例如,我先進(jìn)性num的運(yùn)算,之后再定義num,reg[3:0]num,這樣寫的話雖然編譯沒有錯(cuò)誤,但是在調(diào)?modelsim仿真的時(shí)候它會(huì)出
現(xiàn)編譯錯(cuò)誤,所以為了規(guī)范,不要這樣寫
4.在邊沿脈沖檢測(cè)的時(shí)候,我習(xí)慣于檢測(cè)下降沿,?這?是檢測(cè)tx_en的上升沿,所以我在復(fù)位清零的時(shí)候錯(cuò)誤的將兩級(jí)寄存器賦值為
0,實(shí)際上在檢測(cè)上升沿時(shí)要對(duì)兩級(jí)寄存器復(fù)位時(shí)置?,再把最后?級(jí)寄存器取反后與上?級(jí)相與。
5.在發(fā)送數(shù)據(jù)部分,由于受到上次寫接收部分程序的影響,沒有將起始位發(fā)送出去,因?yàn)樵诮邮詹糠郑遣恍枰邮掌鹗嘉坏模菑牡?/p>
?位開始,?在發(fā)送部分只有先發(fā)送起始位才能和上位機(jī)握?通信,還有在發(fā)送完數(shù)據(jù)后要發(fā)送停?位,其他情況下都發(fā)送?電平來阻?通
信的進(jìn)?
6.最后?個(gè)問題是最棘?的問題,我找了好??半天也沒發(fā)現(xiàn),最后還是根據(jù)源代碼找出來的,不過我還是不知道將這兩條語句顛倒了
對(duì)程序有什么影響,只知道顛倒后數(shù)據(jù)會(huì)?直在發(fā)送,不會(huì)像預(yù)設(shè)?樣,每隔?秒發(fā)送?次,?今還是搞不清楚,希望?神指點(diǎn)迷津
總之我覺得語法上的錯(cuò)誤到不?于太難,寫的多了就不會(huì)出錯(cuò)了,關(guān)鍵是邏輯上的錯(cuò)誤很隱蔽,也很難發(fā)現(xiàn),可以通過RTL視圖來檢測(cè)
連線上是否正確,還可以借助仿真?具,但是我現(xiàn)在仿真?具?的還不熟,就?如這段代碼,在板?上運(yùn)?時(shí)正確的,但是我?軟件仿真時(shí)
輸出端?直是?電平不變,也不知道為什么。反正要學(xué)的東西還很多,這點(diǎn)?平還是遠(yuǎn)遠(yuǎn)不夠,繼續(xù)加油吧!
今天就到此為?了,謝謝?家!
本文發(fā)布于:2023-03-03 21:05:35,感謝您對(duì)本站的認(rèn)可!
本文鏈接:http://www.newhan.cn/zhishi/a/16778487359106.html
版權(quán)聲明:本站內(nèi)容均來自互聯(lián)網(wǎng),僅供演示用,請(qǐng)勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)刪除。
本文word下載地址:一步一腳印.doc
本文 PDF 下載地址:一步一腳印.pdf
| 留言與評(píng)論(共有 0 條評(píng)論) |