調(diào)試FPGA電路板總結(jié)
這兩周都在調(diào)一塊我們組畫(huà)的FPGA電路板,遇到了不少的問(wèn)題,在此總結(jié)一下。
焊電路板肯定是從電源焊起,我們的電源部分基本上沒(méi)有問(wèn)題,3.3V、2.5V和1.2V輸出都很正常。
但是當(dāng)我們把FPGA芯片焊上后,在quartus里用JTAG方式下載程序時(shí),問(wèn)題出錯(cuò),提示是找不到芯片。起初我們認(rèn)為是下載電路設(shè)計(jì)得有問(wèn)題,于是我們對(duì)照著CycloneIII的芯片手冊(cè)中找關(guān)于JTAG下載的描述。其中有一段是這樣描述的:
For device VCCIO of 2.5 V, 3.0 V, or 3.3 V, refer to Figure 10–24. All I/O inputs must
maintain a maximum AC voltage of 4.1 V. Because JTAG pins do not have the internal
PCI clamping diodes to prevent voltage overshoot when using VCCIO of 2.5 V, 3.0 V, or
3.3 V, you must power up the download cable’s VCC with a 2.5- V supply from VCCA.
For device VCCIO of 1.2 V, 1.5 V, or 1.8 V, refer to Figure 10–25. You can power up the
download cable’s VCC with the supply from VCCIO.
在我們?cè)诎遄由希琕CCIO用的是3.3V,因此VCCA應(yīng)該用2.5V,再看我們的VCCA,竟然是1.2V,再查了CycloneIII的芯片手冊(cè),其中寫(xiě)到:
Each Cyclone III PLL uses separate VCC and ground pin pairs for their analog
circuitry. The analog circuit power and ground pin for each PLL is called VCCA<PLL
number> and GNDA. Connect the VCCA power pin to a 2.5-V power supply even if you
do not use the PLL.
就是說(shuō)VCCA是2.5V,看來(lái)我們是連錯(cuò)了,VCCA和VCCD分別是鎖相環(huán)的數(shù)字電源和模擬電源,在畫(huà)原理圖的時(shí)候不小心畫(huà)錯(cuò)了。這也是CycloneIII和CycloneII的區(qū)別,在CycloneII中,VCCA和VCCD_PLL都接1.2V,而在CycloneIII中,VCCA接2.5V,VCCD_PLL接1.2V。
發(fā)現(xiàn)這個(gè)錯(cuò)誤后,我們只能小心翼翼地飛線了,經(jīng)過(guò)一翻折騰后,終于飛好了,上電,下載,成功!
后面我們就要測(cè)SDRAM了,因?yàn)槲覀円肧OPC系統(tǒng),程序要在SDRAM里跑。但是無(wú)論我們的程序怎么調(diào),在nios里下載程序時(shí),控制臺(tái)總是顯示verify failed between address 0x1000000 and 0x1000020,其中這個(gè)地址范圍在SDRAM的地址空間中。出現(xiàn)這個(gè)問(wèn)題是因?yàn)榕cSDRAM通信出現(xiàn)了問(wèn)題,而且大部分是因?yàn)镾DRAM的時(shí)鐘與SDRAM CONTROLLER的時(shí)鐘之間的相移設(shè)置得不正確。但是我設(shè)置得相移是根據(jù)quartus handbook中關(guān)于相移地介紹算出來(lái)的,應(yīng)該不會(huì)有問(wèn)題。話雖這么說(shuō),但是是不是算錯(cuò)了我也不敢確定,所以只能修改此相移(error and try),因?yàn)橐话愦讼嘁贫荚O(shè)為-72度,所以把相移修改為-72度,但是問(wèn)題依舊。既然是error and try,于是我又試了一些其它的值,但是依然沒(méi)有效果。此時(shí)我們認(rèn)為問(wèn)題出在電路板上的可能性會(huì)比較大,于是圍繞著SDRAM檢測(cè)硬件,SDRAM的連接非常簡(jiǎn)單,只需要把數(shù)據(jù)線、地址線和一些控制線直接連到FPGA的引腳上即可,所以在連接上不會(huì)有太大的問(wèn)題。后來(lái)突然想到我們之前把PLL的電源接錯(cuò)了,沒(méi)準(zhǔn)當(dāng)時(shí)已經(jīng)把PLL燒壞了,而我們的SDRAM的相移是通過(guò)PLL來(lái)實(shí)現(xiàn)的。于是我們寫(xiě)了一個(gè)測(cè)試程序,看PLL的輸出是否正確。結(jié)果果然不出我們所料,PLL的輸出根本不是我們想要的方波(當(dāng)然用示波器測(cè)應(yīng)該是輸出正弦波,因?yàn)榉讲ǖ念l率是50M,根據(jù)信號(hào)與系統(tǒng)的理論,此方波是由50M和及高次諧波組成的,而示波器的帶寬也就60M,所以只能顯示50M的正弦波),而是一些雜波,這說(shuō)明我們這片F(xiàn)PGA的PLL已經(jīng)被我們搞壞了,查看其芯片手機(jī),VCCD_PLL最多只能接1.8V,之前我們用2.5V來(lái)虐待它,而且時(shí)間還不短,它不壞就不正常了。
現(xiàn)在我們只能換FPGA芯片了,經(jīng)我們小心翼翼地再次飛線,最終將芯片焊好后,一步一步地測(cè),電源正常、硬件下載正常、PLL輸出正常、nios下載正常。至此我們的工作算是暫告一段落。
在以上調(diào)試過(guò)程中,還遇到了一些其它的問(wèn)題。
在nios里下載軟件程序時(shí),會(huì)出現(xiàn)
assertion "m_state == STATE_DEBUG" failed: file "nios2oci.cpp", line 157
Using cable "USB-Blaster [USB-0]", device 1, instance 0x00
Pausing target processor: not responding.
Resetting and trying again: D:\altera\81\nios2eds\bin\nios2-download: line 594:
6300 Hangup nios2-gdb-server --instance 0 --tcpport none --wri
te-pid ./Debug/nios2-download.pid ./Debug/GigaCard.elf.srec
這個(gè)問(wèn)題在我調(diào)試的過(guò)程中偶爾會(huì)出現(xiàn),而且是沒(méi)有規(guī)律的,也正是這個(gè)問(wèn)題,總是阻礙著我們前進(jìn)的腳步,后來(lái)我們發(fā)現(xiàn)一個(gè)程序本來(lái)是可以下到onchip-memory中的,后來(lái)同樣的程序無(wú)論如何都下不進(jìn)去了,于是我們基本可以確定問(wèn)題出在了硬件。對(duì)于有控制器的系統(tǒng),晶振肯定是非常重要的,于是我們測(cè)晶振的輸出是不是正常的,結(jié)果是有時(shí)正常有時(shí)不正常,這說(shuō)明晶振虛焊了,經(jīng)過(guò)我們小寶同學(xué)精心補(bǔ)焊,上面那個(gè)問(wèn)題就再也沒(méi)有出現(xiàn)過(guò)了。
在nios里下載軟件程序時(shí),出現(xiàn)
Using cable "USB-Blaster [USB-0]", device 1, instance 0x00
Pausing target processor: not responding.
Resetting and trying again: FAILED
Leaving target processor paused
這個(gè)錯(cuò)誤在可編程部分的原因大多是引腳分配錯(cuò)誤。網(wǎng)上有人說(shuō)要在quartus將沒(méi)有用到的FPGA的引腳設(shè)為“input tri-state”,但是我并沒(méi)有發(fā)現(xiàn)這是必須的,可能只是一些特定地器件需要這樣設(shè)置。
經(jīng)過(guò)這次調(diào)試,感覺(jué)自己增長(zhǎng)了不少調(diào)試經(jīng)驗(yàn),雖然之前調(diào)試過(guò)51板子,但是畫(huà)那塊板子時(shí),參考電路有很多,所以調(diào)試起來(lái)比較順利,沒(méi)出太多問(wèn)題。這次就不同了,問(wèn)題出了一大堆,真有點(diǎn)不知所措??偨Y(jié)一下調(diào)試有主控芯片的電路,首先要保證電源沒(méi)有問(wèn)題,不僅是電源模塊地輸出沒(méi)有問(wèn)題,還有芯片地電源不能接錯(cuò),因?yàn)殡娫匆诲e(cuò),所以一切都要玩兒完,就像我們這次就因?yàn)殡娫吹膯?wèn)題燒了幾百塊錢(qián)的芯片。在電源沒(méi)有問(wèn)題的情況下,就要看看主控芯片的晶振有沒(méi)有問(wèn)題,很多問(wèn)題都是晶振引起的,我之前調(diào)試51板子的時(shí)候也是因?yàn)橛昧艘粋€(gè)已經(jīng)壞掉的晶振導(dǎo)致不能下載程序。遇到硬件方面的問(wèn)題時(shí)需要一點(diǎn)一點(diǎn)地排查,在確定前面的模塊是正確的情況下再進(jìn)行后面的部分。
關(guān)于FPGA的調(diào)試,我想要分為以下幾步,首先要保證FPGA芯片的幾個(gè)電源是正確的,然后先用一個(gè)最簡(jiǎn)單地用硬件描述語(yǔ)言寫(xiě)的小程序測(cè)試FPGA芯片是否能夠正常下載并工作正常。然后用nios建立軟件工程并把程序放在onchip-memory上下載。接下來(lái)再繼續(xù)調(diào)試外圍的電路。
在nios里把程序放到onchip-memory上進(jìn)行編譯時(shí),很多時(shí)候都會(huì)遇到錯(cuò)誤,提示onchip-memory的空間不足。這是因?yàn)槌绦蚴怯胢ain作為主函數(shù),這樣的話nios會(huì)在程序進(jìn)入main函數(shù)前進(jìn)行一些系統(tǒng)的初始化工作,這做占用不少的空間。要在onchip-memory上跑程序,最好是采用alt_main作為主函數(shù),例如采用下面的程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "system.h"
#include "sys/alt_sys_init.h"
#include "sys/alt_irq.h"
#include "priv/alt_file.h"
#include "altera_avalon_pio_regs.h"
int main (void) __attribute__ ((weak, alias ("alt_main")));
int alt_main(void)
{
alt_irq_init (ALT_IRQ_BASE);
alt_sys_init();
alt_io_redirect (ALT_STDOUT, ALT_STDIN, ALT_STDERR);
while(1)
{
IOWR(TEST_PIO_BASE,0,1);
usleep(1000);
IOWR(TEST_PIO_BASE,0,0);
usleep(1000);
}
return 0;
}