原文地址:?https://bbs.elecfans.com/jishu_2489801_1_1.html?
作者:@王釗
引言:FPGA開發(fā),思路先行!
玩FPGA板子,讀代碼是基本功!尤其對從C語言轉(zhuǎn)戰(zhàn)FPGA的“寶貝們”來說,適應(yīng)流水線(pipeline)編程可能需要點(diǎn)時(shí)間。
上篇點(diǎn)燈代碼解讀了基礎(chǔ),而如果能親手寫出串口通訊代碼,恭喜你,F(xiàn)PGA的大門算是真正踏入了!
本文旨在幫初學(xué)者梳理FPGA開發(fā)的核心思維流程——思路對了,后面的路才順暢,這可是重中之重!
一:感性認(rèn)知 - 燒錄 & 看效果
廢話不多說,先燒程序,眼見為實(shí)!

在Ubuntu下,等程序燒錄完成后,打開gtkterm,通過USB轉(zhuǎn)串口設(shè)備節(jié)點(diǎn)與板子通訊。
本次燒錄的實(shí)例實(shí)現(xiàn)的是“回顯”(Echo):你鍵盤輸入什么,板子就原樣發(fā)回什么。

這種時(shí)候我們可能會以為出現(xiàn)了幻覺(這效果對嗎?)
好辦!在回顯代碼里“加個(gè)1”,把接收到的數(shù)據(jù)+1再發(fā)送

再次燒錄以后,測試發(fā)現(xiàn),按鍵輸入123變成了234。果然不是幻覺,我們可以繼續(xù)看代碼了。
經(jīng)驗(yàn)上講以上步驟還是必要的,這證明代碼是對的,以免被坑。
二:硬件連接 - 原理圖 & 管腳對一對
回到代碼,Top頂層模塊走起!

輸入腳有個(gè)25m的時(shí)鐘,輸出有個(gè)燈,這跟點(diǎn)燈程序一樣。然后串口有收發(fā)兩個(gè)腳。然后我去對一下原理圖。

找到原理圖第三頁,底板的原理圖,供電的Type-C口其實(shí)連到了CH340 USB轉(zhuǎn)串口芯片(單片機(jī)玩家老朋友了!)
這個(gè)原理圖其實(shí)看著有點(diǎn)暈,反正大致意思就是串口發(fā)送接收接到了H10和H11這兩個(gè)腳上。

管腳配置瞧一瞧:外部時(shí)鐘腳和led的腳跟之前點(diǎn)燈的程序一樣,下面就是多了H10和H11兩個(gè)腳,分別對于串口的RX和TX。
然后它們的電平是3.3V的。如果這里看著難受的話可以把它改到其他腳上,然后接一個(gè)自己的USB轉(zhuǎn)串口的板子上,自己的串口板只需要多接個(gè)GND地線,無需接3.3V電源,加上RX和TX一共3根線,注意RX和TX可能需要反一下。
三:協(xié)議基礎(chǔ) - 磨刀不誤砍柴工
到這里又要啰嗦一下,F(xiàn)PGA調(diào)一個(gè)接口,首先就是我們需要清楚的知道接口有個(gè)的數(shù)據(jù)定義,協(xié)議等知識。不能上來就研究代碼,否則可能會迷糊。

(圖片來源:https://zhuanlan.zhihu.com/p/689643287)
這里是我搜索出來知乎的帖子,講串口協(xié)議的,有需要的話可以補(bǔ)充一下底層知識。
當(dāng)然相信沒幾個(gè)人不知道串口的,但FPGA開發(fā)它還是蠻多套路的,比如接收一幀數(shù)據(jù)該如何接收。
大致的思路是這樣的,我們需要用一個(gè)比串口波特率更高的采樣信號去采集,串口的RX上什么時(shí)候出現(xiàn)起始位,然后接收每個(gè)數(shù)據(jù)位,最后延時(shí)一個(gè)停止位,再循環(huán)檢測起始位,接收下一幀數(shù)據(jù)。
四:代碼解析 - 接收模塊的奧秘
然后代碼我就不再講倍頻和reset邏輯了,點(diǎn)燈程序已經(jīng)講過了。

直接看接收的代碼:這里看到模塊的調(diào)用,可以想象成我們在板子上焊了一塊芯片,它有一個(gè)clk腳rst_n腳;然后連到了top頂層的UART的RX上;收到數(shù)據(jù)后會返回一個(gè)接收完成的標(biāo)志,8位的接收到的數(shù)據(jù);最后還需要一個(gè)比波特率大的,這里是大16倍的采樣時(shí)鐘。

進(jìn)入接收模塊的代碼里,我們看看芯片內(nèi)部是怎樣實(shí)現(xiàn)的。這里作者用ASCCII碼畫了一個(gè)時(shí)序圖,這個(gè)太有用了,看代碼的時(shí)候需要反復(fù)的看這個(gè)圖。
簡單說一下這個(gè)時(shí)序圖,IDLE的時(shí)候是檢測起始位的狀態(tài),起始位start是bit0,這里看著它是低電平的;然后到接收數(shù)據(jù)的狀態(tài),也就是bit1到bit8這8位;最后是end停止位,回到IDLE。
所以程序的思路就有了,我們需要在16倍波特率的采樣周期上,不停的檢測RX腳上的電平,完成串口通訊一幀數(shù)據(jù)的接收。

接著看代碼,作者大神首先把RX腳做了個(gè)同步,這個(gè)套路不看代碼是學(xué)不到的,久了看見這種代碼腦袋里面會浮現(xiàn)出一個(gè)時(shí)序圖,大概就能看到clk和rx信號的時(shí)序,然后理解到為什么要同步。
注意這個(gè)模塊有兩個(gè)時(shí)鐘,一個(gè)是系統(tǒng)時(shí)鐘,一個(gè)是16倍的波特率的時(shí)鐘,它這同步的是系統(tǒng)時(shí)鐘。咱們先別暈在這里,繼續(xù)往下看。

后面的代碼是個(gè)狀態(tài)機(jī),這代碼還有點(diǎn)多,我抓屏一爪還抓不完。大家可以打開代碼自己對著看,反正行號可以看出是講到哪里了。狀態(tài)機(jī)跟作者的時(shí)序圖是一致的,就是那些IDLE,start,end之類的狀態(tài)。
這里還有個(gè)特別玄乎的套路,本人也不是大神,所以也沒看明白。就是這個(gè)狀態(tài)機(jī)是用系統(tǒng)時(shí)鐘來檢測的,那個(gè)16倍波特率的采樣時(shí)鐘是在下面用個(gè)if來判斷的,就是采樣信號為高的時(shí)候去檢測數(shù)據(jù)信號的高低。本寶認(rèn)為,為什么不直接把采樣信號放在always語句上面用呢。手賤的同學(xué)可以改一下試試,看看串口會不會丟數(shù)據(jù),試完記得告訴我結(jié)論。

IDLE狀態(tài)沒什么看頭,我們看看start狀態(tài)。它這里有個(gè)采樣的計(jì)數(shù),一個(gè)bit采樣16次。這里首先是從IDLE進(jìn)入START狀態(tài)需要rx管腳為低電平,并且在16次采樣的中間那會不變成低電平,才認(rèn)為起始信號有效。(為什么不判斷全部為高?或者前半段為高?)
反正最重要的是數(shù)到16個(gè)采樣就切到下一個(gè)狀態(tài),不能快也不能慢,保證時(shí)序要求。
這里還有一個(gè)套路是我們會看到那些a=a,b=b的語句,其實(shí)我感覺是可以刪掉的,不知道是不是作者年級比較大,或許以前古時(shí)候的綜合器不寫else后面的東西,它會亂綜合一些東西出來。好奇寶寶們可以寫個(gè)測試程序,看看RTL電路有什么區(qū)別,同樣,測試出結(jié)論以后記得告訴我……

采樣狀態(tài)的邏輯看了半天,也沒真正做采樣的事情,只是輸出了一個(gè)變量rxd_cnt,這個(gè)變量表示采樣的是第幾個(gè)bit,還要注意的是這個(gè)變量在什么時(shí)候被鎖存改變的,我們注意到是在采樣計(jì)數(shù)為最后一個(gè)的時(shí)候鎖存的。

停止?fàn)顟B(tài)啥也沒干,只是保證延時(shí)一個(gè)波特率的時(shí)間而已。

接著看代碼,上面采樣狀態(tài)輸出了一個(gè)變量rxd_cnt,然后這里才進(jìn)行真正的采樣操作,它同時(shí)判斷了采樣計(jì)數(shù)器cmp_cnt,保證是在波形中部進(jìn)行采樣。可能這么做是增加魯棒性。相信看到這里有些人會表示不服,我們可以把串口線接長一點(diǎn),中間再加點(diǎn)電磁干擾,這樣比較一下如果不在中間采樣會不會導(dǎo)致丟數(shù)據(jù)的比率變高。同樣,如果有人測試了,記得把結(jié)論告訴我!!!

最后一段代碼是輸出一幀率數(shù)據(jù)接收完成的標(biāo)志,可以看到它的鎖存邏輯是在停止位發(fā)送完畢的時(shí)候持續(xù)了一個(gè)采樣時(shí)鐘的高電平。同時(shí)鎖存輸出數(shù)據(jù)。

五:發(fā)送模塊 - 相對簡單
再往下就是看發(fā)送邏輯了,這塊邏輯跟接收邏輯幾乎一樣。其實(shí)發(fā)送邏輯大可不必這么精細(xì),因?yàn)榻邮詹判枰哳l率的采樣,發(fā)送只要保證時(shí)序就可以了。如果實(shí)在看不懂接收邏輯,我建議大家還是直接寫一下發(fā)送邏輯,比如就按作者畫的時(shí)序圖,先用pll生成一個(gè)波特率的時(shí)鐘,再按照時(shí)鐘調(diào)整TX管腳的高低電平即可。最后用上面講的接長串口線的方法測試一下數(shù)據(jù)傳輸?shù)男省?/span>

大半夜的不知道誰拍了我一下,我就突然看到這塊代碼有點(diǎn)不對……這個(gè)case里面的語句的等于符號前面居然沒有小于符號了。這種情況奶奶沒教過啊,而且它always語句里面是個(gè)*號。其實(shí)verilog我也是只學(xué)了三天,所以不太確定這是不是就是個(gè)組合邏輯電路。哎,這個(gè)迷哪位好心人回帖告訴我一聲好不好。

萬一有人整篇文章都看不懂,這里有個(gè)好玩的東西,test_io這個(gè)腳是接到燈上的,它這里的邏輯是TX和RX上只要有數(shù)據(jù)變化,燈就會閃爍,實(shí)測我一直往串口輸入字符a,這個(gè)燈是可以看到閃爍的,閃的比較暗,大家可以關(guān)燈看看。
終極總結(jié):FPGA接口開發(fā)心法
總結(jié)一下,關(guān)于接口的實(shí)現(xiàn),無論接口多復(fù)雜,其實(shí)也是邏輯電平的控制,但前提是需要對協(xié)議非常的熟悉,再就是一下FPGA代碼的套路了,這些套路都是一點(diǎn)一點(diǎn)看眾大神的代碼悟出來的。
-
FPGA
+關(guān)注
關(guān)注
1660文章
22408瀏覽量
636197 -
串口通信
+關(guān)注
關(guān)注
34文章
1662瀏覽量
57960 -
開發(fā)板
+關(guān)注
關(guān)注
26文章
6289瀏覽量
118033
發(fā)布評論請先 登錄
fpga時(shí)序分析案例 調(diào)試FPGA經(jīng)驗(yàn)總結(jié)
基于FPGA的USB串口通信設(shè)計(jì)
【技術(shù)經(jīng)典下載】《深入淺出玩轉(zhuǎn)FPGA》-珍貴的學(xué)習(xí)經(jīng)驗(yàn)和筆記
特權(quán)同學(xué)新書《勇敢的芯伴你玩轉(zhuǎn)Altera FPGA》電子版 下載 (FPGA初學(xué)者首選)
賽靈思FPGA初學(xué)者 必備圖書 特權(quán)同學(xué)新書《勇敢的芯伴你玩轉(zhuǎn)賽靈思 FPGA》
MATLAB串口調(diào)試助手應(yīng)用程序和基于MATLAB開發(fā)USB的串口通信源代碼
PID算法原理_調(diào)試經(jīng)驗(yàn)以及代碼總結(jié)
單片機(jī)——串口通信(從串口接收多位數(shù)據(jù)保存到數(shù)組,發(fā)送多位數(shù)據(jù)到串口)
單片機(jī)UART串口通信(代碼親自調(diào)試成功)
玩轉(zhuǎn)ZMP110x創(chuàng)新串口屏的虛擬串口屏開發(fā)模式
【經(jīng)驗(yàn)分享】玩轉(zhuǎn)FPGA串口通信:從“幻覺調(diào)試”到代碼解析
評論