资源描述
PCI Express总线基础及FPGA设计实战1. PCI Express基础PCIe总线是基于PCI总线发展起来的,很多基本概念都来自于PCI总线,有必要在介绍PCIe之前了解PCI总线。1.1 PCI基础PCI总线作为处理器系统的局部总线,其主要目的是为了连接外部设备,而不是作为处理器系统的系统总线连接Cache和主存储器。PCI总线作为系统总线的延伸,其设计考虑了许多与处理器相关的内容,孤立的研究PCI总线并不可取,因此需要将PCI作为存储器系统的一个部分来研究。1.1.1 几个重要概念1) PCI总线空间与处理器空间隔离PCI设备具有独立的地址空间,即PCI总线地址空间,该空间与存储器地址空间通过HOST主桥隔离。处理器需要通过HOST主桥才能访问PCI设备,而PCI设备需要通过HOST主桥才能方位主存储器。要注意区分存储器地址空间和PCI总线地址。在一个处理器系统中,存储器域、PCI总线域与HOST主桥的关系如下图。图中的处理器系统由一个CPU、一个DRAM控制器和两个HOST主桥组成。在这个处理器系统中,包含CPU域、DRAM域、存储器域和PCI总线域地址空间。其中HOST主桥x和HOST主桥y分别管理PCI总线x域与PCI总线y域。CPU访问PCI设备,必须通过HOST主桥进行地址转换,而PCI设备访问存储器设备,也需要HOST主桥进行地址转换。HOST主桥的一个重要作用就是将存储器访问的存储器地址转换成PCI总线地址。CPU域地址空间是指CPU所能直接访问的地址空间集合。DRAM域地址空间是指DRAM控制器所能访问的地址空间集合,又称为主主存储器域。存储器域是CPU域和DRAM域的集合。存储器域包括CPU内部的通用寄存器、存储器映射寻址的寄存器、主存储器空间和外部设备空间。在Intel的x86处理系统中,外部设备空间与PCI总线域地址空间等效。因为在x86处理器系统中,使用PCI总线同一管理全部外部设备。值得注意的是,存储器域的外部设备空间,在PCI总线域中还有一个地址映射。当处理器访问PCI设备时,首先访问的是这个设备在存储器域上的PCI设备空间,之后HOST主桥将这个存储器域的PCI总线地址转换成PCI总线域的物理地址,然后通过PCI总线事务访问PCI总线域的地址空间。2) 可扩展性PCI总线具有很强的扩展性。在PCI总线中,HOST主桥可以直接推出一条PCI总线,这条总线也是该HOST主桥管理的第一条PCI总线,该总线还可以通过PCI桥扩展一系列PCI总线,并以HOST主桥作为根节点,形成1棵PCI总线树。这些PCI总线都可以连接PCI设备,但是一棵PCI设备树上,最多只能挂接256个PCI设备(包括PCI桥)。3) 动态配置机制PCI设备使用的地址可以根据需要由系统软件动态分配。PCI总线使用这种方式合理地解决设备间的地址冲突,从而实现了“即插即用”功能。每一个PCI设备都有独立的配置空间,在配置空间中包含该设备在PCI总线中使用的基地址即BAR地址,从而保证每一个PCI设备使用的物理地址并不相同。PCI桥的配置空间中包含有其下PCI子树所能使用的地址范围。x86系统的工作流程是:主板上的BIOS程序会扫描PCI/PCIE设备,读取其BAR空间的大小,动态地为PCI/PCIE设备分配地址空间。在调试过中发现,假如将BAR空间设置成2G,x86系统会报no bootable device的错误,原因应该是BIOS给PCIE设备分配了2G的地址空间,暂用了硬盘的地址空间,导致无法加载操作系统。4) 总线带宽PCI总线与之前的局部总线相比,极大提高了数据传送带宽,32位/33MHz的PCI总线可以提供132MB/s的峰值带宽,而64位/66MHz的PCI总线可以提供的峰值带宽为532MB/s。虽然PCI总线所能提供的峰值带宽远不能和PCIe总线相比,但是与之前的局部总线ISA、EISA和MCA总线相比,仍然具有极大的优势。ISA总线的最高主频为8MHz,位宽为16,其峰值带宽为16MB/s;EISA总线的最高主频为8.33MHz,位宽为32,其峰值带宽为33MB/s;而MCA总线的最高主频为10MHz,最高位宽为32,其峰值带宽为40MB/s。PCI总线提供的峰值带宽远高于这些总线。5) 共享总线机制PCI设备通过仲裁获得PCI总线的使用权后,才能进行数据传送,在PCI总线上进行数据传送,并不需要处理器进行干预。PCI总线仲裁器不在PCI总线规范定义的范围内,也不一定是HOST主桥和PCI桥的一部分,虽然绝大多数HOST主桥和PCI桥都包含PCI总线仲裁器,但是在某些处理器系统设计中也可以使用独立的PCI总线仲裁器。PCI设备使用共享总线方式进行数据传递,在同一条总线上,所有PCI设备共享同一总线带宽,这将极大地影响PCI总线的利用率。这种机制显然不如PCIe总线采用的交换结构。6) 中断机制PCI总线上的设备可以通过四根中断请求信号INTAD#向处理器提交中断请求。与ISA总线上的设备不同,PCI总线上的设备可以共享这些中断请求信号,不同的PCI设备可以将这些中断请求信号线与后,与中断控制器的中断请求引脚连接。PCI设备的配置空间记录了该设备使用这四根中断请求信号的信息。PCI总线还进一步提出了MSI(Message Signal Interrupt)机制,该机制使用存储器写总线事务传递中断请求,并可以使用x86处理器FSB(Front Side Bus)总线提供的Interrupt Message总线事务,从而提高了PCI设备的中断请求效率。1.1.2 PCI总线的组成结构。图中与PCI总线相关的模块包括:HOST主桥、PCI总线、PCI桥和PCI设备。PCI总线是由HOST主桥和PCI桥推出,HOST主桥与主存储器控制器在同一级总线上,因此PCI设备可以方便通过HOST主桥访问存储器,即进行DMA操作。在一些简单的处理器系统中,可能不包含PCI桥,此时所有PCI设备都是连接再HOST主桥上推出的PCI总线上。在一些处理器系统中有可能有多个HOST主桥,如图1-1所示处理器系统中含有HOST主桥x和HOST主桥y。X86处理器的HOST主桥X86处理器使用南北桥结构连接CPU和PCI设备。其中北桥连接快速设备,如显卡和内存条,并推出PCI总线,HOST主桥包含在北桥中。而南桥连接慢速设备。1.2 PCIE总线概述PCI总线使用并行总线结构,在同一条总线上的所有外部设备共享总线带宽,而PCIe总线使用高速查分总线,采用端对端的连接方式,因此在每一条PCIe链路中只能连接两个设备。这使得PCIe与PCI总线采用的拓扑结构有所不同。PCIe总线除了在连接方式上与PCI总线不同之外,还使用一些在网络通信中使用的技术,如支持多种数据路由方式,基于多通路的数据传递方式,和基于报文的数据传送方式,并充分考虑在数据传送中出现的服务质量QoS(Quality of Service)问题。1.2.1 基于PCIe的系统结构前期的Intel主板中会集成单独的南北桥芯片,北桥负责连接速度较快的CPU、主存储器以及显卡等元件,南桥负责连接速度较慢的设备,包括硬盘、USB、网卡等。只要CPU读取主存储器,还需要北桥的支持,也就是CPU与主存储器的交流,会占用北桥的带宽。因此新一代的Intel主板架构,大多将北桥存储控制器整合到CPU封装中,CPU直接与主存储器交互,速度较快。基于PCIe总线的Intel处理器架构主存储器的速度SDRAM/DDR型号数据位宽内部时钟频率速度带宽SDRAMPC10064100100800MBytes/secSDRAMPC133641331331064MBytes/secDDRDDR-266641332662.1GBytes/secDDRDDR-400642004003.2GBytes/secDDRDDR2-900642008006.4GBytes/secDDRDDR3-160064200160012.8GBytes/secPCIe总线带宽规格1x带宽16x带宽PCIe1.0250Mbytes/sec4GBytes/secPCIe2.0500Mbytes/sec8GBytes/secPCIe3.01GBytes/sec16GBytes/secPCIe4.02GBytes/sec32GBytes/secSATA总线带宽版本带宽SATA1.0150Mbytes/secSATA2.0300Mbytes/secSATA3.0600Mbytes/secUSB总线带宽版本带宽USB1.01.5Mbytes/secUSB2.060Mbytes/secUSB3.0500Mbytes/secUSB3.11000Mbytes/sec1.2.2 端到端的数据传递 PCI总线不同,PCIe总线采用端到端的连接方式,在一条PCIe链路的两端只能各连接一个设备,这两个设备互为数据发送端和数据接收端。在PCIe总线的物理链路的一个数据通路(Lane)中,有两组查分信号,共4根信号线。其中发送端的TX部件与接收端的RX部件使用一组差分信号连接,该链路也被称为发送端的发送链路,也是接收端的接收链路;而发送端的RX部件与接收端TX部件使用另一组查分信号连接,该链路也被称为发送端的接收链路,也是接收端的发送链路。一个PCIe链路可以由多个数据通路Lane组成,目前PCIe链路可以支持1、2、4、8、16和32Lane,即x1、x2、x4、x8、x16、x32宽度的PCIe链路。PCIe总线物理链路间的数据传送使用基于时钟的同步传送机制,但是在物理链路上并没有时钟线,PCIE总线的接收端含有时钟恢复模块CDR(Clock Data Recovery),CDR将从接收报文中提取接收时钟,从而进行同步数据传递,PCIe设备进行链路训练时将完成时钟的提取工作。1.2.3 PCIe总线的层次结构PCIe总线采用串行连接方式,并使用数据包(Packet)进行数据传输。在PCIe总线中,数据报文在接收和发送过程中,需要通过多个层次,包括事务层、数据链路层和物理层。PCIe总线的层次组成结构与网络中的层次结构有类似之处,但PCIe总线的各个层次都是用硬件逻辑实现的。在PCIe体系结构中,根据报文首先在设备的核心层(Device Core)中产生,然后再经过该设备的事务层(Transaction Layer)、数据链路层(Data Link Layer)和物理层(Physical Layer),最终发送出去。而接收端的数据也需要经过物理层、数据链路层和事务层,最终到达核心层。1. 事务层事务层定义了PCIe总线使用总线事务,其中多数总线事务与PCI总线兼容。这些总线事务可以通过Switch等设备传送到其他PCIe设备或者RC设备。RC设备也可以使用这些总线事务访问PCIe设备。事务层接收来自PCIe设备核心层的数据,并将其封装成TLP(Transaction Layer Packet)后,发向数据链路层。此外事务层还可以从数据链路层中接收数据报文,然后转发至PCIe设备的核心层。2. 数据链路层数据链路层保证来自发送端事务层的报文可以可靠、完整地发送到接收端的数据链路层。来自事务层的报文在通过数据链路层时,被添加Sequence Number前缀和CRC后缀。数据链路层使用ACK/NAK协议保证报文的可靠传递。PCIe总线的数据链路层还定义了多种DLLP(Data Link Layer Packet),DLLP产生于数据链路层,终止与数据链路层。3. 物理层物理层是PCIe的最底层,将PCIe设备连接再一起。PCIe总线的物理电气特性决定了PCIe链路只能使用端到端的连接方式。PCIe总线的物理层为PCIe设备间的数据通信提供传送介质,为数据提供可靠的物理环境。1.2.3 PCIe体系结构的组成结构PCIe总线作为处理器系统的局部总线,其作用于PCI总线类似,主要目的是为了连接处理器系统中的外部设备。在大多数处理器系统中,都使用RC Switch和PCIe-to-PCI桥这些基本模块连接PCIe和PCI设备。在PCIe总线中,基于PCIe总线的设备,也成为EP(Endpoint)。 基于PCIe总线的通用处理器系统如下图图中所示的结构将PCIe总线端口、存储器控制器等一系列与外部设备有关的接口都集成在一起,并统称为RC。RC具有一个或者多个PCIe端口,可以连接各类PCIe设备。PCIe设备包括(网卡、显卡等设备)、Switch和PCIe桥。PCIe总线采取端到端的连接方式,每一个PCIe端口只能连接一个EP,当然PCIe端口也可以连接Switch进行链路扩展。通过Switch扩展出的PCIe链路可以继续挂接EP或者其它Switch。2. 基于FPGA的PCIe总线分析2.1 硬件系统设计本章将采用xilinx的FPGA芯片搭建一个RC端和EP端的硬件平台,用于仿真学习PCIe总线相关的知识包括DMA操作、地址映射等,以及xilinx的AXI Memoy Mapped TO PCI Express、AXI DMA等IP使用。2.1.1 RC端系统设计RC端硬件系统由MicroBlaze处理器、RC(采用xilinx的AXI Memony Mapped To PCI Express配置成RC模式)、内存(采用内置BRAM块)、常用外设包括GPIO、串口。地址分配pcie地址空间 axi_pcie_bar0 0xC000_00000xC000_FFFFmem地址空间 axi_mem_0 0x0600_00000x0600_FFFF2.1.2 EP端系统设计EP端硬件系统由MicroBlaze处理器、EP(采用xilinx的AXI Memony Mapped To PCI Express配置成EP模式)、DMA以及内置BRAM块。地址分配pcie地址空间 axi_pcie_bar0 0x4000_00000x4000_FFFFmem地址空间 axi_mem_0 0x0800_00000x0800_FFFF2.2 读写数据分析2.2.1 读写MEM数据操作地址为RC端BAR空间存储器域地址+偏移量例如,往EP端偏移量为0x1000的MEM写数据,RC端写地址为0xC000_000+0x10000xC000_000为RC端axi_pcie_bar0基地址,即EP端PCIe域基地址映射到RC端存储器地址域的基地址。将RC端存储器域地址0xC000_1000,转换成EP端AXI地址0x0800_1000,最终写入到EP端MEM。2.2.2 DMA操作DMA在EP端,源地址和目的地址为EP端AXI总线地址2.2.2.1读内存读内存指将RC端的内存的数据搬移到EP端MEM。数据流图如下RC端EP端源地址为0x4000_1000,RC端存储器域地址在EP端AXI总线域的映射地址目标地址为0x0800_2000,EP端AXI总线域地址2.2.2.2写内存写内存将EP端的数据写入RC端的内存。数据流图EP端RC端源地址为0x0800_1000,EP端AXI总线地址目标地址为0x4000_2000,RC端存储器域内存地址在EP端AXI总线地址域的映射地址3. 设计实战本章将搭建一个基于PCIe x4的EP端硬件系统,并在安装Windows7的x86电脑上,使用WinDriver软件完成驱动开发。3.1 EP端硬件系统搭建地址分配AXI Memony Mapped To PCI Express参数配置1. 将Device/Port Type配置成功PCI Express Endpoint device2. 将Lane Width配置成x4,将Link Speed配置成5.0GT/s3. 配置Vendor ID和Device ID,驱动开发时将根据Vendor ID和Device ID来扫描PCIe设备。4. 配置BAR0的地址空间为128K,配置C_PCIEBAR2AXIBAR_0为0x0800_00005. 配置C_AXIBAR2PCIEBAR_0为0xFFFF_00003.2 上板调试记录1. BAR0的地址空间分配过大当将Bar0空间配置成2GB时,WINDOWS7的PC机没有启动操作系统,报错no bootable device,原因应该是BIOS需要给BAR0分配2G的地址空间,占用了硬盘的地址空间,导致无法加载操作系统。2. axi_pcie的BAR空间或C_AXIBAR2PCIEBAR0设置不正确调试时可以使用windriver工具辅助开发,快速获取pcie设置的配置寄存器的值以及主机为pcie设备分配的bar空间大小,假设主机为pcie设备分配的bar空间为0xF7D000000xF7D1FFFF,总共128KB(注意x86处理器系统中存储器域地址和pcie域地址相等,而arm处理器则不一致)。主机为锁定的dma的物理地址为0x00000000db361000(pDma-pDma-Page0.pPhysicalAddr),进行dma写内存操作时,源地址为EP端bram空间的地址,目标地址位置成主机为锁定的dma的物理地址,假设EP端为axi_pcie分配的空间为0x4000_00000x7FFF_FFFF,0xdb361000无法顺利达到axi_pcie的S_AXI总线,将EP端的axi_pcie的地址空间设置成0xC000_00000xFFFF_FFFF时,0xdb361000可以顺利达到axi_pcie的S_AXI总线。但如果C_AXIBAR2PCIEBAR0设置不正确,数据也无法正常返回PC端。假如EP端的参数配置如下C_AXIBAR_0 = 0xC000_0000C_AXI_HIGHADDR_0 = 0xFFFF_FFFFC_AXIBAR2PCIEBAR0 = 0x4000_0000axi到pcie地址转换如下,pcie的最终地址为0x5b361000,无法返回PC端。为了获取正确的pcie域地址,需要将C_AXIBAR2PCIEBAR0的最高2比特设置成全1,如C_AXIBAR2PCIEBAR0=0xC000_0000、0xFFFF_0000都是可行的。3.调试时发下 axi dma每次最大传输长度为16KB-1,假如超过16KB,dma无法工作。原因是Width of Buffer Length Register配置成了14bits,16KB-1=0x3FFF刚好达到buffer的上限。将Width of Buffer Length Register配置成了17bits后,dma可以一次传输64KB数据。3.3 WINDOWS下驱动开发3.3.1 开发流程WinDriver是Jungo公司提供的一种通用的驱动开发支持软件,它简化了用户的上层驱动开发和应用接口开发,而且易于再封装,实现商业化应用。该软件提供了对PCI Express接口设备的驱动支持,而且也提供了对DMA实现功能的支持。开发流程及使用的函数如下图所示,使用接口函数可以分成3大类:WDC库相关、设备相关以及dma相关。1.WDC库相关打开Windriver驱动并初始化WDC库DWORD DLLCALLCONV WDC_DriverOpen(WDC_DRV_OPEN_OPTIONS openOptions,const CHAR *sLicense);关闭Windriver驱动以及WDC库DWORD DLLCALLCONV WDC_DriverClose(void);2.设备相关扫描PCI设备,dwVendorId为厂商ID,dwDeviceId为器件ID,pPciScanResult为扫描到的PCI设备。WDC_PciScanDevices(DWORD dwVendorId, DWORD dwDeviceId,WDC_PCI_SCAN_RESULT *pPciScanResult);返回设备信息。DWORD DLLCALLCONV WDC_PciGetDeviceInfo(WD_PCI_CARD_INFO *pDeviceInfo);获取设备句柄。DWORD DLLCALLCONV WDC_PciDeviceOpen(WDC_DEVICE_HANDLE *phDev,const WD_PCI_CARD_INFO *pDeviceInfo, const PVOID pDevCtx,PVOID reserved, const CHAR *pcKPDriverName, PVOID pKPOpenData);关闭设备句柄DWORD DLLCALLCONV WDC_PciDeviceClose(WDC_DEVICE_HANDLE hDev);3.dma相关WinDriver提供了两种DMA缓冲区的分配方式,即连续缓冲区和分散聚合缓冲区。前者当用户申请缓冲区时,分配的是一个物理地址连续的内存块;而后者分配的缓冲区在物理位置上可以是分段的,这些物理上不连续的内存段通过虚拟地址空间映射给用户的是一个在应用层连续的缓冲区。分配一块连续物理空间的内存DWORD DLLCALLCONV WDC_DMAContigBufLock(WDC_DEVICE_HANDLE hDev, PVOID *ppBuf,DWORD dwOptions, DWORD dwDMABufSize, WD_DMA *ppDma);分配非连续物理空间的内存段DWORD DLLCALLCONV WDC_DMASGBufLock(WDC_DEVICE_HANDLE hDev, PVOID pBuf,DWORD dwOptions, DWORD dwDMABufSize, WD_DMA *ppDma);释放DMA缓存区DWORD DLLCALLCONV WDC_DMABufUnlock(WD_DMA *pDma);AXI DMA的Simple DMA模式的配置流程如下,具体参见pg021。Direct Register Mode (Scatter Gather Engine is disabled) provides a configuration for doing simple DMA transfers on MM2S and S2MM channels that requires less FPGA resource utilization. Transfers are initiated by accessing the DMACR, the Source or Destination Address and the Length registers. When the transfer is completed, a DMASR.IOC_Irq asserts for the associated channel and if enabled generates an interrupt out.3.3.2速度测试方向数据量耗时速度读内存64KB401us159MByte/sec写内存64KB66us969MByte/sec读内存4KB31us129MBytes/sec写内存4KB8us500MBytes/sec读内存256B7us37Mbytes/sec写内存256B4us64Mbytes/sec
展开阅读全文