<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>

新聞中心

EEPW首頁(yè) > 嵌入式系統 > 牛人業(yè)話(huà) > 零基礎學(xué)FPGA(十一)一步一腳印之基于FIFO的串口發(fā)送機設計全流程及常見(jiàn)錯誤詳解

零基礎學(xué)FPGA(十一)一步一腳印之基于FIFO的串口發(fā)送機設計全流程及常見(jiàn)錯誤詳解

—— 零基礎學(xué)FPGA(十二)一步一腳印之基于FIFO的串口發(fā)送機設計全流程及常見(jiàn)錯誤詳解
作者: 時(shí)間:2015-01-29 來(lái)源:網(wǎng)絡(luò ) 收藏

  記得在上幾篇博客中,有幾名網(wǎng)友提出要加進(jìn)去錯誤分析這一部分,那我們就從今天這篇文章開(kāi)始加進(jìn)去我在消化這段代碼的過(guò)程中遇到的迷惑,與大家分享。

本文引用地址:http://dyxdggzs.com/article/269209.htm

  今天要寫(xiě)的是一段基于的串口發(fā)送機設計,之前也寫(xiě)過(guò)串口發(fā)送的電路,這次寫(xiě)的與上次的有幾分類(lèi)似。這段代碼也是我看過(guò)別人寫(xiě)過(guò)的之后,消化一下再根據自己的理解寫(xiě)出來(lái)的,下面是我寫(xiě)這段代碼的全部流程和思路,希望對剛開(kāi)始接觸的朋友來(lái)說(shuō)有一點(diǎn)點(diǎn)的幫助,也希望有經(jīng)驗的朋友給予寶貴的建議。

  首先來(lái)解釋一下的含義,就是First Input First Output的縮寫(xiě),就是先入先出的意思,按照我的理解就是,先進(jìn)去的數據先出,例如一個(gè)數組的高位先進(jìn),那么讀出來(lái)的時(shí)候也就高位先出。下面是百度百科的解釋。

  FIFO一般用于不同時(shí)鐘域之間的數據傳輸,比如FIFO的一端是AD數據采集,另一端是計算機的PCI總線(xiàn),假設其AD采集的速率為16位 100K SPS,那么每秒的數據量為100K×16bit=1.6Mbps,而PCI總線(xiàn)的速度為33MHz,總線(xiàn)寬度32bit,其最大傳輸速率為1056Mbps,在兩個(gè)不同的時(shí)鐘域間就可以采用FIFO來(lái)作為數據緩沖。另外對于不同寬度的數據接口也可以用FIFO,例如單片機位8位數據輸出,而DSP可能是16位數據輸入,在單片機與DSP連接時(shí)就可以使用FIFO來(lái)達到數據匹配的目的。

  下面我們開(kāi)始設計。

  這次設計我們要設計一個(gè)串口發(fā)送機,想一下的話(huà),我們要發(fā)送數據,總得有一個(gè)數據產(chǎn)生模塊和數據發(fā)送模塊吧。好,那么在我們的腦海里就出現了這兩個(gè)模塊。由于我們這次是借用Altera公司提供的IP核FIFO來(lái)完成,所以要加入這個(gè)模塊,這個(gè)模塊作為一個(gè)數據緩沖器,需要我們例化,等會(huì )我們按照思路來(lái)例化它。

  好,模塊出來(lái)了,我們將這三個(gè)模塊分別定義為dataoutput塊,fifo_ctrl塊和uart_ctrl塊?,F在考慮連線(xiàn)。我個(gè)人感覺(jué)在設計之前,把要設計的東西在草稿紙上將大體框圖畫(huà)出來(lái),具體到每一根連線(xiàn),這樣根據圖來(lái)寫(xiě)代碼要比直接用腦子構圖要方便的多。三個(gè)模塊,先考慮時(shí)鐘和復位信號線(xiàn),三個(gè)模塊都有,然后,數據產(chǎn)生模塊要將產(chǎn)生的數據發(fā)給FIFO模塊,所以要有數據寫(xiě)入線(xiàn),我們定義它為wr-datain,數據寫(xiě)入FIFO塊后總要輸出,這些數據就是我們要發(fā)送的數據,所以定義輸出數據線(xiàn)tx_data,先不管FIFO,我們再來(lái)定義數據發(fā)送模塊的連線(xiàn),數據發(fā)送總要有個(gè)啟動(dòng)信號,所以我們定義變量tx_start,之后,還要有一個(gè)輸出端給PC機,我們定義這個(gè)輸出端位rs232,對于FIFO模塊的例化過(guò)程很簡(jiǎn)單就不做過(guò)多的說(shuō)明,只把接口說(shuō)一下,FIFO模塊除了時(shí)鐘,復位信號外,還有數據輸入端口,這個(gè)端口要和之前的數據產(chǎn)生模塊的數據輸出端口相連,還有寫(xiě)請求端口,高電平有效,數據發(fā)送模塊每隔1秒鐘產(chǎn)生一個(gè)16位的數據,并發(fā)送寫(xiě)請求命令給FIFO,還有讀請求命令,高電平有效數據發(fā)送模塊在發(fā)送數據時(shí)要發(fā)送一個(gè)讀請求給FIFO,從中讀取數據后再發(fā)送給PC機,還有空信號empty,只要檢測到FIFO中有數據,empty就為低電平,我們可用這個(gè)信號來(lái)啟動(dòng)數據發(fā)送模塊。這樣一來(lái),我們的整體框架就出來(lái)了有了這個(gè)整體框架,再寫(xiě)代碼就容易多了。

  下面是RTL視圖


360桌面截圖20140714200658.jpg


  下面我們來(lái)寫(xiě)代碼

  按照這個(gè)框架,先把接口定義出來(lái),中間的連線(xiàn)用wire型


360桌面截圖20140714202033.jpg


  設計完端口之后我們就來(lái)設計底層模塊,先設計數據產(chǎn)生模塊dataoutput

  這個(gè)部分主要是產(chǎn)生數據,可用一個(gè)分頻電路實(shí)現每1s發(fā)送一次的數據,產(chǎn)生這16位數據的時(shí)候,需要16個(gè)時(shí)鐘,每個(gè)時(shí)鐘數據自加1,總體來(lái)說(shuō)比較簡(jiǎn)單


360桌面截圖20140714202504.jpg


  寫(xiě)完一個(gè)模塊之后養成好習慣,馬上把端口例化


360桌面截圖20140714203301.jpg


  數據產(chǎn)生以后就要進(jìn)入緩沖器FIFO,由于這段代碼我們是調用的,所以只要例化接口就好了,只需要將產(chǎn)生的fifo_ctrl_inst文件中例化好的代碼拷貝粘貼就好


360桌面截圖20140714203514.jpg


  最后我們要寫(xiě)數據發(fā)送部分

  之前已經(jīng)講過(guò),數據發(fā)送部分還要包括兩個(gè)子模塊,一個(gè)是波特率匹配模塊,一個(gè)是發(fā)送模塊,既然又包括兩個(gè)子模塊,那么我們還要構建一個(gè)框圖

  按照之前的例子,當FIFO當中有數據時(shí)empty就會(huì )拉低,我們把它取反后送給發(fā)送模塊,告訴發(fā)送模塊準備發(fā)送,這樣,發(fā)送模塊就會(huì )產(chǎn)生一個(gè)波特率計數器啟動(dòng)信號bps_start給波特率匹配模塊,波特率匹配模塊收到信號后立馬開(kāi)始匹配計數,并產(chǎn)生采集信號,將采集信號傳給發(fā)送模塊,發(fā)送模塊根據采集信號,將數據一位一位發(fā)送出去。知道了這個(gè)原理之后,我們構建起這樣一個(gè)框架


360桌面截圖20140714204221.jpg


  根據這個(gè)框圖,我們定義端口和線(xiàn)


360桌面截圖20140714204322.jpg


  定義完端口之后,開(kāi)始寫(xiě)發(fā)送模塊,用邊沿脈沖檢測法檢測啟動(dòng)信號tx_start信號的上升沿來(lái)啟動(dòng)發(fā)送部分,波特率配置模塊具體代碼在前面也文章中有給出,就不在說(shuō)明,寫(xiě)完之后例化端口,這兩個(gè)模塊作為數據發(fā)送模塊的子模塊,要在數據發(fā)送模塊下例化


360桌面截圖20140714205127.jpg



360桌面截圖20140714204858.jpg


  這樣一來(lái),我們整個(gè)設計就完成了,看上去很簡(jiǎn)單,但是從我自己實(shí)踐的角度來(lái)說(shuō)還是有點(diǎn)挑戰的,包括中間出現的各種問(wèn)題,下面就來(lái)分享一下我在做這個(gè)設計時(shí)遇到的問(wèn)題

  1.例化問(wèn)題

  在例化端口時(shí),要注意括號里面的才是本層模塊的端口,也就是說(shuō)在本層模塊上面已經(jīng)定義過(guò)的變量,括號外面的才是被調用模塊的端口,也在下層模塊的頂部被聲明,我在寫(xiě)這段程序的時(shí)候將二者顛倒了,導致連線(xiàn)不成功,最終是通過(guò)查看RTL視圖知道了哪根線(xiàn)有問(wèn)題才修改成功的

360桌面截圖20140715130721.jpg


  2.同一個(gè)變量不能在多個(gè)always語(yǔ)句中被賦值

  我們可能習慣這么寫(xiě)

  always @ (posedge clk or negedge rst_n)

  if(!rst_n) num <= 1'b0;

  else num <= num+1'b1;

  那么,num的值在其他always語(yǔ)句中就不允許再被賦值或者清零,我在寫(xiě)的時(shí)候在其他always語(yǔ)句中將num 清零了,導致編譯不成功

  3. 定義變量之前不要出現該變量,即使后面又定義了

  例如,我先進(jìn)性num的運算,之后再定義num,reg [3:0] num,這樣寫(xiě)的話(huà)雖然編譯沒(méi)有錯誤,但是在調用modelsim仿真的時(shí)候它會(huì )出現編譯錯誤,所以為了規范,不要這樣寫(xiě)

  4. 在邊沿脈沖檢測的時(shí)候,我習慣于檢測下降沿,而這里是檢測tx_en 的上升沿,所以我在復位清零的時(shí)候錯誤的將兩級寄存器賦值為0,實(shí)際上在檢測上升沿時(shí)要對兩級寄存器復位時(shí)置一,再把最后一級寄存器取反后與上一級相與。


360桌面截圖20140715131444.jpg


  5. 在發(fā)送數據部分,由于受到上次寫(xiě)接收部分程序的影響,沒(méi)有將起始位發(fā)送出去,因為在接收部分,是不需要接收起始位的,是從第一位開(kāi)始,而在發(fā)送部分只有先發(fā)送起始位才能和上位機握手通信,還有在發(fā)送完數據后要發(fā)送停止位,其他情況下都發(fā)送高電平來(lái)阻止通信的進(jìn)行


360桌面截圖20140715132338.jpg


  6.最后一個(gè)問(wèn)題是最棘手的問(wèn)題,我找了好大一半天也沒(méi)發(fā)現,最后還是根據源代碼找出來(lái)的,不過(guò)我還是不知道將這兩條語(yǔ)句顛倒了對程序有什么影響,只知道顛倒后數據會(huì )一直在發(fā)送,不會(huì )像預設一樣,每隔一秒發(fā)送一次,至今還是搞不清楚,希望大神指點(diǎn)迷津


360桌面截圖20140715132953.jpg


  總之我覺(jué)得語(yǔ)法上的錯誤到不至于太難,寫(xiě)的多了就不會(huì )出錯了,關(guān)鍵是邏輯上的錯誤很隱蔽,也很難發(fā)現,可以通過(guò)RTL視圖來(lái)檢測連線(xiàn)上是否正確,還可以借助仿真工具,但是我現在仿真工具用的還不熟,就比如這段代碼,在板子上運行時(shí)正確的,但是我用軟件仿真時(shí)輸出端一直是高電平不變,也不知道為什么。反正要學(xué)的東西還很多,這點(diǎn)水平還是遠遠不夠,繼續加油吧!

  今天就到此為止了,謝謝大家!

樹(shù)莓派文章專(zhuān)題:樹(shù)莓派是什么?你不知道樹(shù)莓派的知識和應用

fpga相關(guān)文章:fpga是什么


塵埃粒子計數器相關(guān)文章:塵埃粒子計數器原理


關(guān)鍵詞: FPGA FIFO

評論


相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>