基于VHDL的PCI总线数据采集卡的研究
2010-01-27
作者:林青松,王光辉
摘 要:提出了应用VHDL语言实现PCI数据采集卡的设计方法,对PCI总线主模式控制器的结构、时序和Windows XP环境下PCI设备WDM驱动程序的开发进行了研究;在单片FPGA中实现了A/D转换器的时序控制、FIFO存储器和PCI总线接口控制器的设计。仿真结果表明,该数据采集卡符合PCI 2.2协议,具有DMA传输功能。
关键词:PCI总线;现场可编程逻辑阵列(FPGA);DMA传输;VHDL;WDM驱动
目前,利用个人计算机作为数据采集和处理的平台,通过数据总线将采集的数据高速地传输到计算机的存储设备中,是实现数据采集存储和处理的主要手段。最常用的个人计算机总线有ISA总线、USB总线及PCI总线。3种总线的特点是ISA总线采用程序请求I/O方式与CPU通信,CPU资源占用大,传输速率低;USB2.0标准的理论传输率虽然高达480 Mb/s,但是它的CPU占用率较高;PCI总线理论传输速率可达132 Mb/s,稳定传输速率一般也可达80 Mb/s [1],而且可靠性高。因此PCI总线已经广泛应用于数据采集、测控等领域。
随着超大规模集成电路技术的发展,FPGA(现场可编程门阵列)的集成度和运行速度得到提高,并且FPGA易于实现逻辑控制,时钟频率高、内部时延小,可以实现乘法器、地址发生器、状态机、译码器等功能,具有比单片机和DSP更高的灵活性[2]。基于以上优点本文提出了一种在单片FPGA上实现PCI总线数据采集的设计方案。
1 PCI数据采集系统构成
本设计中数据采集卡包括A/D转换单元、数据缓冲存储单元和基于PCI总线的数据传输单元。被测信号经过前置预处理部分,直接进入A/D采样,采样后的数据经过FIFO(先进先出存储器)缓冲,通过PCI总线传输到PC机中,最后通过计算机软件平台对采集到的数据进行信号分析和处理。整个数据采集卡的工作时序是在单片FPGA控制下进行的,其内部包含A/D和FIFO的时序控制模块、FIFO存储器模块和PCI接口逻辑模块。其硬件设计框图如图1所示。
为了使FPGA能够实现上述三大功能并具有升级空间,本设计选用了Altera公司的Cyclone系列,具体型号为EP1C6Q240C8,该FPGA具有较高的性价比,主要特点如下:
(1) 逻辑单元LE(Logic Elements)数目达到了5 980个,除去电源和配置引脚,为用户提供了185个I/O引脚;
(2) 内嵌了20个M4K RAM块,可方便地配置成FIFO或RAM;
(3) 内嵌了2个锁相环,有利于FPGA内部的时钟管理,提高系统的稳定性;
(4) 支持66 MHz、32位PCI总线标准。
1.1 模数转换单元
采用ADI公司的14位、10M/s高性能模数转换器AD9240。该芯片自带采样保持电路(SHA)和输出缓冲器(OUTPUT BUFFER)。AD9240的时序控制与传统的A/D有所不同,完全依靠时钟控制采样、转换和数据输出[3]。如图2所示,在第1个时钟的上升沿开始采样转换,第4个时钟上升沿到来时,数据将出现在D1~D14端口上。数据输出采用直接二进制编码格式,根据需要可以配置芯片的DRVDD引脚构成+3.3 V或+5 V逻辑系列接口,而不需使用电平转换芯片,简化了电路设计。硬件上,采用系统自通电起,A/D和时钟电路始终处于工作状态,对数据不停进行转换,独立的模拟和数字电源、模拟地和数字地设计,减小数字信号对模拟信号的干扰。
1.2 数据缓冲存储单元
Cyclone系列FPGA是一款高性能、低价格的可编程逻辑器件,具有丰富的逻辑单元和存储单元。其内部的M4K RAM块可以配置大小不同的各种类型存储器,如RAM和FIFO,其中FIFO具有两套数据线而无地址线,可在其一端写操作而在另一端进行读操作,数据在其中顺序移动,从而达到很高的传输速度和效率。因此,FIFO更适合作为A/D采样时数据高速写入的缓冲存储器。
在设计中采用FPGA来实现FIFO和数据传输的时序控制。使用QuartusⅡ 8.0集成开发环境中的MegaWizard Plug-In Manager工具来构建FIFO,首先在向导中设置参数,构建一个14位宽、512B深的FIFO,并设置FIFO的空满标志位,写使能、读使能等控制位,以便实现与A/D转换器和PCI总线的逻辑接口。所构建的FIFO如图3所示。
用FIFO构成高速A/D采样缓存时,由于转换速度较快,直接将ADC采样后的数据存储到FIFO中,此过程对时序配置要求非常严格,如果两者时序关系配合不当,就会发生数据存储出错或者掉数。针对这一问题,把A/D转换时钟和FIFO写时钟设置为同一时钟源,自上电起,A/D和时钟电路一直处于工作状态,不停地进行数据的转换,但数据是否写入到FIFO中,由FIFO的写使能信号(wrreq)来决定,当时序控制模块发出写使能信号有效时,转换的数据才能存储到FIFO中。从图2可知,A/D转换数据的输出和转换时钟有一定的相位差tOD,在FPGA内部可通过延时或时钟管理器来满足建立时间和保持时间,保证数据不失码地传输到FIFO中。
1.3 PCI总线接口模块
目前PCI接口的设计有两种方法:一种是采用现成的PCI总线桥接器件;另一种方法是采用大规模可编程逻辑器件,通过软件编程完成硬件设计[4]。考虑到使用PCI接口专用芯片,如AMCC S5933、PLX9054等,仍需要外部扩展FPGA来进行IO接口处理,这种方法成本较高且占用PCB板面积较大。于是设计中用VHDL(硬件描述语言)对FPGA编程开发PCI接口逻辑,使单片FPGA既包含用户逻辑又包含接口逻辑,从而使电路大大简化,使设计更加紧凑。其次,当系统升级时,只需对可编程器件重新进行逻辑设计,而无需更新PCB板图。
数据采集卡中设计的PCI总线接口电路具有32位总线宽度,工作在33 MHz,具有Target/Initiator模式,在Initiator模式下可以进行DMA传输,主要包含地址命令锁存、地址命令译码、奇偶校验、数据通路、配置空间和有限状态机六部分。其中Initiator模块扮演着总线控制者的角色,它的核心是主模式状态机。主模式状态机处理DMA传输时总线上的各个状态,控制总线的时序,因此主模式状态机的设计是PCI接口模块中的设计重点,下面将主要介绍设计中PCI主模式状态机的设计。
如图4所示主模式状态机由IDLE、REQ、ADDR、WAIT、READ、 WRITE、LAST、RETRY、ABORT9种状态组成。
IDLE:总线空闲状态。当未发起DMA传输时,总线应停留在空闲状态,各信号均无效。
REQ:当接收到start信号,由IDLE状态跳转到REQ状态,将req#信号拉低,申请对总线的控制权,若得到仲裁器允许,即gnt#有效,则跳转到ADDR状态,否则停留在REQ状态。
ADDR:该状态使frame#有效,并同时给出要访问的Host物理首地址和命令,在下一个时钟给出irdy#,跳转到WAIT状态。
WAIT:该状态等待Target准备好,若trdy#无效则停留在WAIT状态;若有效则判断是读还是写,跳转到READ或WRITE,并开始接收或发送数据;若Target在16个周期内未有效trdy#,则跳转到RETRY。
READ:接收pci_ad[31:0]上的数据,一直有效frame#和irdy#,并检测当前传输是否是倒数第二次传输,若是则在下一个时钟无效frame#信号,并跳转到LAST状态;若不是则停留在READ状态;在此过程中,若target有数据的断开(disconnect with data),则跳转到RETRY状态;若target终止传输(target abort),则跳转到ABORT状态。
WRITE:将后端待发送的数据放到pci_ad[31,0]总线上,一直使frame#和irdy#信号处于低电平,并检测当前传输是否是倒数第二次传输,若是则在下一个时钟无效frame#信号,并跳转到LAST状态;若不是则停留在WRITE状态;在此过程中,若target有数据的断开(disconnect with data),则跳转到RETRY状态;若target终止传输(target abort),则跳转到ABORT状态。
RETRY:该状态保存当前剩余字节数、当前内存物理地址,跳转到IDLE状态,等待重新发起传输。
LAST:完成最后一次传输,在下一时钟周期将irdy#无效,回到IDLE状态。
ABORT:无效所有信号,回到IDLE状态。
需要说明的是,PCI配置空间定义在Target模块中,PCI的配置读写操作也由Target模块完成。系统开始工作时,首先由主机通过从模式写操作设置DMA寄存器,如传输字节数、内存物理首地址,最后给出start信号,通知Initiator模块申请总线控制权,在得到仲裁其允许后启动DMA传输。
图5是在Quartus Ⅱ环境下PCI总线上DMA传输的时序仿真图,信号配合过程是:master接收到slave发送的dma_start#请求信号后,发送req#请求占用PCI总线,接到gnt#允许信号后,发送帧信号frame#。在frame#有效的第一个时钟,发送读数据块的地址pci_ad[31:0](addr)及读命令CMD,在随后的时钟当irdy#、devsel#、trdy#有效且stop#无效时,在字节使能信号c/be[3:0]#的同步下,接收读数据块(data)。结束后,发intr_a#中断且释放PCI总线。以上信号带“#”的表示低电平有效。
2 WDM驱动程序的设计
WDM(Windows Driver Model)是Windows 32模式驱动程序模型,这种驱动程序为Windows 98/2000/XP的设备驱动程序提供了统一的框架[5]。它来源于Windows NT的分层32位色设备驱动程序模型(Layered 32-bits Device Driver Model);支持更多的特性,如即插即用(Plug&Play)、电源管理(Power Management)、Windows管理诊断(Windows Management Instrumentation)和NT事件等。
PCI设备驱动程序除驱动程序入口例程、即插即用例程、分发例程、电源管理例程和卸载例程等基本部分外,在框架上与其他类型的设备驱动程序基本相同,是很标准的WDM设备驱动程序。另外,为实现PCI设备的系统中断等功能,还应包括中断服务(IRP)例程和延时过程调度DPC(Deferred Procedure Call)例程等其他例程[6]。图6描述了PCI设备驱动程序的基本组成部分。
结合WDM驱动程序特性,在Windows XP操作系统下,对PCI数据采集卡编写驱动程序。采用DriverStido工具生成的WDM驱动程序框架,在VC++ 6.0中开发支持I/O、内存和DMA操作的驱动程序。
在驱动程序开发中,DMA操作的实现方法如下:首先在即插即用例程中调用IoGetDmaAdapter函数得到一个DMA适配器对象。当驱动程序的分发例程收到应用程序的IRP_Mj_READ IRP包后,调用IoStartPacket函数让系统启动入口例程中的DriverStartIo函数。在DriverStartIo函数中设置DMA寄存器,将IRP的MDL(Memory Descriptor List)所描述的内存区组装成分散/集中列表,最后启动DMA数据传输,由DMA适配器产生数据传输周期。驱动程序收到DMA传输结束中断后,在ISP例程中首先禁止PCI设备的DMA中断,防止中断程序嵌套,然后在返回前调用IoRequestDpc函数请求一个DPC。在DPC例程中首先清除DMA中断源,然后将数据从PCI驱动内存中复制到IRP的MDL用户缓冲区内供应用程序存储和后续处理。这样就完成了一次DMA操作。
随着FPGA技术的发展,硬件设计和软件设计的界限已经被打破。本文用VHDL语言实现了PCI总线数据采集卡的设计,在Quartus Ⅱ中经功能仿真、时序验证,符合PCI总线2.2标准,支持DMA操作。本数据采集卡的各逻辑模块仅占用了FPGA中1 956个LE,大大降低了开发成本,提高了系统集成度。同时,由于FPGA的体系结构和编程的灵活性,使得系统具有很强的扩展性和移植性,为将来系统功能的改进和完善提供了便利。采用DriverStido编写驱动程序,使难度较大的Windows驱动开发变得容易,缩短了开发时间。
参考文献
[1] PIMG.PCI Local Bus Specification.Revision 2.2 18,1998.
[2] 王友波,刘明业.PCI总线接口控制器的FPGA实现 [J].北京理工大学学报, 2004,25(5):423-426.
[3] AD9240 Datasheet.http://www.analog.com. 2008,12.
[4] 李贵山.PCI局部总线开发者指南[M].西安:西安电子科技大学出版社,1997.
[5] 张惠鹃,周利华.Windows环境下的设备驱动程序设计 [M].西安:西安电子科技大学出版社,2002.
[6] 曹荣荣,阙沛文.PCI数据采集卡及其WDM驱动程序设计 [J].
计算机测量与控制,2006,14(3):415-417.