《电子技术应用》
您所在的位置:首页 > 嵌入式技术 > 业界动态 > 利用计算机打印口调试FPGA

利用计算机打印口调试FPGA

2009-03-06
作者:蔡英武 许 晏

  摘  要: 介绍一种利用计算机打印口调试ALTERA的FLEX10K系列FPGA的方法。对于没有ALTERA的Quartus软件的设计者,该方法可以在一定程度上弥补MAX+PLUSIIl软件没有SignalTap逻辑分析功能的不足。

    关键词: 并行口  MAX+PLUSII  FPGA  硬件调试

 

  随着FPGA实现的功能越来越复杂,其调试也越来越困难。尤其对于输入/输出较少、内部运算复杂的FPGA设计来说,其内部操作就象一个“黑箱”,数据进入这个“黑箱”后,它如何被操作、传输,设计者很难知道。仅凭很少的输入/输出信号,很难判断设计是否有问题以及问题的症结所在。因此,在硬件调试中非常有必要深入FPGA内部去了解数据的运算、存储、流动是否正常。

  目前FPGA的调试手段很不理想。以ALTERA的器件为例,虽然它的大多数EPLD、FPGA芯片都带有JTAG接口,但MAX+PLUSII系列软件不支持真正的边界扫描功能,而只是把JTAG接口作为器件配置接口。这就迫使设计者必须把芯片内部的信号引到外部引脚上,通过示波器进行测量和调试。但问题是:当需要引出的内部信号很多时,一是有可能芯片管脚不够分配,二是必须使用昂贵的逻辑分析仪来同时测量这些引出的信号,调试的代价非常高昂。

  ALTERA最新的Quartus软件中有一个SignalTap 逻辑分析功能,配以专用的硬件,可以使FPGA的调试变得轻松简单。SignalTap的操作原理是:用户在自己的设计中插入一个具有SignalTap功能的特定宏模块,并定义需记录的节点名、数据长度、记录用时钟信号、触发记录的条件等,然后启动硬件运行。当记录完成后,器件内部指定节点的数据序列便通过器件的JTAG口传入计算机,以波形的方式显示到屏幕上,设计者就可以进行高效率的调试了。

  不过,对于那些仍在使用MAX+PLUSII的用户,就享受不到这种方便了。为此,本人设计了一种利用计算机并行口调试FPGA的方法,同样可以用于读出FPGA内部数据,提高调试效率。仍在使用MAX+PLUS II软件的朋友不妨一试。

1 FPGA的并行口调试方法

    调试用硬件平台示意图如图1所示。本方法具有以下特点:

  1. 由于采用VHDL语言编程,因此其跨工艺的通用性较强。在ALTERA的FPGA上可用的功能,可以较方便地移植到其它厂家的FPGA上使用(而ALTERA或XILINX的JTAG调试功能必须在设计中调用特定的宏模块);

  2. 设计者必须根据要记录的数据源的不同来修

改VHDL设计,因此灵活性稍差;

  3. 没有使用器件的边界扫描功能和JTAG口,而是从器件上任意选择6个可用引脚作为接口,自己定义逻辑把片内RAM块中的数据读出;

  4. 需要2台计算机协同工作(当然,如果不怕配置和调试时频繁拔插接头的麻烦,也可以采用一台计算机);

  5. 考虑到与底层硬件打交道的方便性及维持较高传送速度的需要,采用C语言程序与FPGA通讯,进行数据传送;数据格式变换及显示采用MATLAB程序。

 

  PC机与打印口之间的信号有三种:

  一是8位数据输出信号,占据25针打印机接口的2~9脚,其I/O地址为378H,本设计中未用到;

  二是打印机的控制输出寄存器,其I/O地址为37AH。本设计使用了该寄存器的最低位STROBE(1脚)作为计算机输出信号Cpu_answer,其为高时表示计算机收到数据,通知FPGA可以传送下一组数据;

  三是打印机的状态读入寄存器,其I/O地址为379H。本设计将其最高位BUSY用来接收FPGA发出的“数据有效”信号Send_data_avi,将其第3至第6位用来接收FPGA送出的4位数据。具体的信号名称与其在25芯接口上的引脚号见表1。

 

 

2 VHDL源程序的编写

  本设计用FPGA片内的RAM块记录感兴趣的数据。为了增强跨工艺的通用性,可以用VHDL描述一个通用的RAM块,然后用FPGA Express或Leonardo Spectrum等综合工具来针对不同厂家的器件进行工艺相关的映射。为了方便起见,本设计采用了MAX+PLUSII中的双口RAM模块LPM_RAM_DQ。

2.1 数据记录部分的设计

  对数据记录部分的VHDL程序编写分两种情况。如果设计内有RAM块,而且正好需要把这个RAM块中的数据读出时,就不必对这部分逻辑做改动,直接参考1.2.2节关于数据传送的描述。

  当需记录的数据源有多个时,则需建立一个新的记录专用RAM块。在设计记录功能时最常用的是并发条件多路语句,把感兴趣的数据接到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;

    在上面的例子中,当状态机FSM为“空闲态”(idle)和“清RAM态”(clr_ram)时,给RAM输入16位二进制数据0;在“判决态”(judge)时,RAM输入端接数据线detect_num;在clr_fil态时,RAM输入端接数据线find_out,等等。另外,配合以读/写控制输入和地址信号的相应变化,就可以把感兴趣的数据存储到专用RAM块中。

2.2  数据传送部分的设计

  数据存储完成后,所要做的就是把记录结果传到计算机中去。为此需要在主状态机中加入两个与传送有关的状态:prepare_send(传送初始化)和sending(传送)。在prepare_send态主要完成RAM块的寻址、计数器清零等操作;sending态的操作是这样:FPGA先把头一组数据放到D3~D0上,并用Send_data_avi信号通知计算机;等计算机读走该组数据并用Cpu_answer信号(高有效脉冲)通知FPGA后,FPGA在Cpu_answer的下降沿将下一组数据送出,如此反复,直到全部数据读完为止。

  由于只有4根数据线,因此当一个完整的数据其长度大于4位时,需要拆为4位一组(加上Send_data_avi作最高位,共5位)的数据分别传送。为防止传送中发生数据丢失现象,每组数据重复传送3次。

  Send_data_avi通常都处于低电平。当进入sending态开始传送有效数据时,Send_data_avi变为高电平;当一个完整的数据传送完成后,Send_data_avi=false(低电平)与D[3..0]=“0000”配合产生一个“完整数据传送完”信号。由于计算机并行口对Send_data_avi是反相接收,因此,计算机接收到的有效数据是0XXXXb,而接收的“完整数据结束”标志是10000b。由于这个标志是独一无二的,因此在C程序中可以判断出这个标志数据。总之,正确传送的数据应在0~16的范围内。图2给出了一个数据传送的时序示意图。  

 

        

    下面是一个传送16位数据的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作为传送计数器,其计数范围根据要传送的数据位数和次数来确定。在本例中要传送16位数据,每组传4位,一组数据重复3次,共传3×(16÷4)=12次。加上还要传送3次结束标志,因此send_ram_cnt计数范围为0~14。另外,RAM块的读/写控制输入和地址信号也必须有相应的配合。3 C语言程序的编写C程序的作用是与FPGA协同完成数据的正确接收,并存成文件备用。通过实验我们发现:虽然传输数据率不是很高,但偶尔会有数据丢失的情况。为防止这种情况的发生,每组数据(4位二进制)重复发送3次。因此在C程序的编写中,要加上消除重复数据的功能。

4 Matlab程序编写

    在数据文件生成后,出于编程方便快捷的考虑,这里采用Matlab软件作为数据格式变换及显示的工具。当然,如果设计者觉得没有必要的话,也可以采用其它编程语言如C语言来做同样的工作。

    MATLAB是MathWorks公司推出的一种面向科学与工程计算的高级(语言)软件。它功能强大、编程效率极高,而且还可以方便地进行各种变换、计算、统计、绘图。下面是一个进行数据格式变换及作图的例子,从中可以体会到Matlab的方便快捷。

load('c:ad.dat');         %读入原始数据文件

x=ad;    len=length(x);

res=[];  y=0;

for i=1:len,                           

%以下把16位二进制原始数据变换为无符号十进制数据。

  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), %如果遇到一个完整数据的结束标志,则存储此次变换结果。

    res=[res,y];

   end;

end;

figure(1); plot(res);  %绘图显示十进制数据

title('来自FPGA的真实数据');

 

参考文献

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)

本站内容除特别声明的原创文章之外,转载内容只为传递更多信息,并不代表本网站赞同其观点。转载的所有的文章、图片、音/视频文件等资料的版权归版权所有权人所有。本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如涉及作品内容、版权和其它问题,请及时通过电子邮件或电话通知我们,以便迅速采取适当措施,避免给双方造成不必要的经济损失。联系电话:010-82306118;邮箱:aet@chinaaet.com。