摘? 要: 介紹一種利用計算機打印口調(diào)試ALTERA的FLEX10K系列FPGA的方法。對于沒有ALTERA的Quartus軟件的設計者,該方法可以在一定程度上彌補MAX+PLUSIIl軟件沒有SignalTap邏輯分析功能的不足。
????關鍵詞: 并行口? MAX+PLUSII? FPGA? 硬件調(diào)試
?
隨著FPGA實現(xiàn)的功能越來越復雜,其調(diào)試也越來越困難。尤其對于輸入/輸出較少、內(nèi)部運算復雜的FPGA設計來說,其內(nèi)部操作就象一個“黑箱”,數(shù)據(jù)進入這個“黑箱”后,它如何被操作、傳輸,設計者很難知道。僅憑很少的輸入/輸出信號,很難判斷設計是否有問題以及問題的癥結所在。因此,在硬件調(diào)試中非常有必要深入FPGA內(nèi)部去了解數(shù)據(jù)的運算、存儲、流動是否正常。
目前FPGA的調(diào)試手段很不理想。以ALTERA的器件為例,雖然它的大多數(shù)EPLD、FPGA芯片都帶有JTAG接口,但MAX+PLUSII系列軟件不支持真正的邊界掃描功能,而只是把JTAG接口作為器件配置接口。這就迫使設計者必須把芯片內(nèi)部的信號引到外部引腳上,通過示波器進行測量和調(diào)試。但問題是:當需要引出的內(nèi)部信號很多時,一是有可能芯片管腳不夠分配,二是必須使用昂貴的邏輯分析儀來同時測量這些引出的信號,調(diào)試的代價非常高昂。
ALTERA最新的Quartus軟件中有一個SignalTap 邏輯分析功能,配以專用的硬件,可以使FPGA的調(diào)試變得輕松簡單。SignalTap的操作原理是:用戶在自己的設計中插入一個具有SignalTap功能的特定宏模塊,并定義需記錄的節(jié)點名、數(shù)據(jù)長度、記錄用時鐘信號、觸發(fā)記錄的條件等,然后啟動硬件運行。當記錄完成后,器件內(nèi)部指定節(jié)點的數(shù)據(jù)序列便通過器件的JTAG口傳入計算機,以波形的方式顯示到屏幕上,設計者就可以進行高效率的調(diào)試了。
不過,對于那些仍在使用MAX+PLUSII的用戶,就享受不到這種方便了。為此,本人設計了一種利用計算機并行口調(diào)試FPGA的方法,同樣可以用于讀出FPGA內(nèi)部數(shù)據(jù),提高調(diào)試效率。仍在使用MAX+PLUS II軟件的朋友不妨一試。
1 FPGA的并行口調(diào)試方法
????調(diào)試用硬件平臺示意圖如圖1所示。本方法具有以下特點:
1. 由于采用VHDL語言編程,因此其跨工藝的通用性較強。在ALTERA的FPGA上可用的功能,可以較方便地移植到其它廠家的FPGA上使用(而ALTERA或XILINX的JTAG調(diào)試功能必須在設計中調(diào)用特定的宏模塊);
2. 設計者必須根據(jù)要記錄的數(shù)據(jù)源的不同來修
改VHDL設計,因此靈活性稍差;
3. 沒有使用器件的邊界掃描功能和JTAG口,而是從器件上任意選擇6個可用引腳作為接口,自己定義邏輯把片內(nèi)RAM塊中的數(shù)據(jù)讀出;
4. 需要2臺計算機協(xié)同工作(當然,如果不怕配置和調(diào)試時頻繁拔插接頭的麻煩,也可以采用一臺計算機);
5. 考慮到與底層硬件打交道的方便性及維持較高傳送速度的需要,采用C語言程序與FPGA通訊,進行數(shù)據(jù)傳送;數(shù)據(jù)格式變換及顯示采用MATLAB程序。
?

PC機與打印口之間的信號有三種:
一是8位數(shù)據(jù)輸出信號,占據(jù)25針打印機接口的2~9腳,其I/O地址為378H,本設計中未用到;
二是打印機的控制輸出寄存器,其I/O地址為37AH。本設計使用了該寄存器的最低位STROBE(1腳)作為計算機輸出信號Cpu_answer,其為高時表示計算機收到數(shù)據(jù),通知FPGA可以傳送下一組數(shù)據(jù);
三是打印機的狀態(tài)讀入寄存器,其I/O地址為379H。本設計將其最高位BUSY用來接收FPGA發(fā)出的“數(shù)據(jù)有效”信號Send_data_avi,將其第3至第6位用來接收FPGA送出的4位數(shù)據(jù)。具體的信號名稱與其在25芯接口上的引腳號見表1。
?

?
2 VHDL源程序的編寫
本設計用FPGA片內(nèi)的RAM塊記錄感興趣的數(shù)據(jù)。為了增強跨工藝的通用性,可以用VHDL描述一個通用的RAM塊,然后用FPGA Express或Leonardo Spectrum等綜合工具來針對不同廠家的器件進行工藝相關的映射。為了方便起見,本設計采用了MAX+PLUSII中的雙口RAM模塊LPM_RAM_DQ。
2.1 數(shù)據(jù)記錄部分的設計
對數(shù)據(jù)記錄部分的VHDL程序編寫分兩種情況。如果設計內(nèi)有RAM塊,而且正好需要把這個RAM塊中的數(shù)據(jù)讀出時,就不必對這部分邏輯做改動,直接參考1.2.2節(jié)關于數(shù)據(jù)傳送的描述。
當需記錄的數(shù)據(jù)源有多個時,則需建立一個新的記錄專用RAM塊。在設計記錄功能時最常用的是并發(fā)條件多路語句,把感興趣的數(shù)據(jù)接到RAM塊的輸入端口。例如:
ram_in??? <=?? conv_std_logic_vector(0,16) when ((FSM=
?????????????????? idle)or(FSM=clr_ram)) else
?????????????????? conv_std_logic_vector(detect_num,16) when
?????????????????? (FSM=judge) else
?????????????????? conv_std_logic_vector(find_out,16) when
?????????????????? (FSM=clr_fil) else
????? ????????????? ram1_out;
????在上面的例子中,當狀態(tài)機FSM為“空閑態(tài)”(idle)和“清RAM態(tài)”(clr_ram)時,給RAM輸入16位二進制數(shù)據(jù)0;在“判決態(tài)”(judge)時,RAM輸入端接數(shù)據(jù)線detect_num;在clr_fil態(tài)時,RAM輸入端接數(shù)據(jù)線find_out,等等。另外,配合以讀/寫控制輸入和地址信號的相應變化,就可以把感興趣的數(shù)據(jù)存儲到專用RAM塊中。
2.2? 數(shù)據(jù)傳送部分的設計
數(shù)據(jù)存儲完成后,所要做的就是把記錄結果傳到計算機中去。為此需要在主狀態(tài)機中加入兩個與傳送有關的狀態(tài):prepare_send(傳送初始化)和sending(傳送)。在prepare_send態(tài)主要完成RAM塊的尋址、計數(shù)器清零等操作;sending態(tài)的操作是這樣:FPGA先把頭一組數(shù)據(jù)放到D3~D0上,并用Send_data_avi信號通知計算機;等計算機讀走該組數(shù)據(jù)并用Cpu_answer信號(高有效脈沖)通知FPGA后,FPGA在Cpu_answer的下降沿將下一組數(shù)據(jù)送出,如此反復,直到全部數(shù)據(jù)讀完為止。
由于只有4根數(shù)據(jù)線,因此當一個完整的數(shù)據(jù)其長度大于4位時,需要拆為4位一組(加上Send_data_avi作最高位,共5位)的數(shù)據(jù)分別傳送。為防止傳送中發(fā)生數(shù)據(jù)丟失現(xiàn)象,每組數(shù)據(jù)重復傳送3次。
Send_data_avi通常都處于低電平。當進入sending態(tài)開始傳送有效數(shù)據(jù)時,Send_data_avi變?yōu)楦唠娖?當一個完整的數(shù)據(jù)傳送完成后,Send_data_avi=false(低電平)與D[3..0]=“0000”配合產(chǎn)生一個“完整數(shù)據(jù)傳送完”信號。由于計算機并行口對Send_data_avi是反相接收,因此,計算機接收到的有效數(shù)據(jù)是0XXXXb,而接收的“完整數(shù)據(jù)結束”標志是10000b。由于這個標志是獨一無二的,因此在C程序中可以判斷出這個標志數(shù)據(jù)。總之,正確傳送的數(shù)據(jù)應在0~16的范圍內(nèi)。圖2給出了一個數(shù)據(jù)傳送的時序示意圖。??
?

????????
??? 下面是一個傳送16位數(shù)據(jù)的VHDL例程。?????
??? PROCESS (reset,clk)
?????? BEGIN
?????? ... ...
????????????? if (FSM=sending) then?????????
?????? ? case send_ram_cnt? is
?????? ? when 0 | 1 | 2 => ???? D<=ram_out(3 downto 0);
???????????????? ?????????????????? Send_data_avi<=true;
?????? ? when 3 | 4 | 5 => ???? D<=ram_out(7 downto 4);
????????????????????????????????Send_data_avi<=true;
?????? ? when 6 | 7 | 8 => D<=ram_out(11? downto 8);
???????? when 9 | 10 | 11 => D<=ram_out(15 downto 12);
????? ????????????????????????? Send_data_avi<=true;
? ?????? when others => ??? D<=″0000″;
????????? ????????????????????? Send_data_avi<=false;
?????? end case;
???? … …
??? END PROCESS;
??? 在上例中,send_ram_cnt作為傳送計數(shù)器,其計數(shù)范圍根據(jù)要傳送的數(shù)據(jù)位數(shù)和次數(shù)來確定。在本例中要傳送16位數(shù)據(jù),每組傳4位,一組數(shù)據(jù)重復3次,共傳3×(16÷4)=12次。加上還要傳送3次結束標志,因此send_ram_cnt計數(shù)范圍為0~14。另外,RAM塊的讀/寫控制輸入和地址信號也必須有相應的配合。3 C語言程序的編寫C程序的作用是與FPGA協(xié)同完成數(shù)據(jù)的正確接收,并存成文件備用。通過實驗我們發(fā)現(xiàn):雖然傳輸數(shù)據(jù)率不是很高,但偶爾會有數(shù)據(jù)丟失的情況。為防止這種情況的發(fā)生,每組數(shù)據(jù)(4位二進制)重復發(fā)送3次。因此在C程序的編寫中,要加上消除重復數(shù)據(jù)的功能。
4 Matlab程序編寫
??? 在數(shù)據(jù)文件生成后,出于編程方便快捷的考慮,這里采用Matlab軟件作為數(shù)據(jù)格式變換及顯示的工具。當然,如果設計者覺得沒有必要的話,也可以采用其它編程語言如C語言來做同樣的工作。
??? MATLAB是MathWorks公司推出的一種面向科學與工程計算的高級(語言)軟件。它功能強大、編程效率極高,而且還可以方便地進行各種變換、計算、統(tǒng)計、繪圖。下面是一個進行數(shù)據(jù)格式變換及作圖的例子,從中可以體會到Matlab的方便快捷。
load('c:ad.dat');???????? %讀入原始數(shù)據(jù)文件
x=ad;??? len=length(x);
res=[];? y=0;
for i=1:len,???????????????????????????
%以下把16位二進制原始數(shù)據(jù)變換為無符號十進制數(shù)據(jù)。
if mod(i,5)==1,??????? tmpy=x(i);
????elseif mod(i,5)==2,?? tmpy=x(i)*16;
??? elseif mod(i,5)==3,?? tmpy=x(i)*16*16;
??? elseif mod(i,5)==4,?? tmpy=x(i)*16*16*16;
??? else,?tmpy=0;
????end;
????if mod(i,5)==1, y=tmpy;
????else y=y+tmpy;
????end;
????if (mod(i,5)==0) | (i==len),?%如果遇到一個完整數(shù)據(jù)的結束標志,則存儲此次變換結果。
??? res=[res,y];
?? end;
end;
figure(1); plot(res);? %繪圖顯示十進制數(shù)據(jù)
title('來自FPGA的真實數(shù)據(jù)');
?
參考文獻
1 Altera. DATA BOOK.1998
2 Altera. SigalTap Plus System Analyzer.2000
3 Altera. IEEE 1149.1(JTAG) Boundary_Scan Testing in Altera Device.2000
4 董浩斌. 基于打印機接口的A/D、D/A卡. 電子技術應用,1996;22(2)
