//------------------------------------------------------------------------------------------------------------------------==================================================PCIE讨论对答=========================================================//------------------------------------------------------------------------------------------------------------------------//1学习步骤:并行协议,不要用CPLD就行了。至于后面怎么做。如果是小白,先不看PCI协议,先看Freescale的FlashBUS协议或者Altera的AvalonMM总线协议,这两个协议简单易懂,理解透了再看PCI就很容易明白了。做逻辑设计的,先关注什么是主从,怎么同步,怎么读写,地址怎么表示,如何竞争,如何仲裁,如何握手。中断怎么表示,如何提高效率,然后再看如何路由,出错怎么办,一开始怎么检测,(这已经到通用标准协议了)。怎么仿真,如何验证。然后可以选择往硬件走,比如电流电平,带载能力,阻抗要求,jitter范围,抗冲击能力,如何测量,接收标准.或者走软件,了解总线层级结构,哪些层做了哪些事。软件的硬件平台结构,谁在控制。接口最大最小响应时间,系统兼容性,健壮度。协议的缺陷在哪里,可靠性如何保证等等,然后再考虑总线对应用的要求。合理操作的范围等等//------------------------------------------------------------------------------------------------------------------------//2配置空间问题继续配置空间:提出一个问题,配置空间是不是一般是我们在FPGA例化pcie核的时候分配的BAR0?或者说是BAR0的一部分呢?继续:配置空间的层次以及大小,在PCIExpress系统中,总线号(8位)、设备号(5位)和功能号(3位)组成了每一功能的16位地址,也确定了每一设备中的每一功能在PCIExpress系统拓扑结构中的位置。从上面的数字可以推出,一个PCIExpress系统最多有256条总线或链路,每条总线上最多可以挂2的16次方个功能,再加上每一功能的配置空间容量为4KB,系统的配置空间总容量为4KBX64K=256MB=2的28次方B。实际上,不可能存在含有64K个功能的系统,因为除了在交换开关或根复合体内部的逻辑(虚拟)PCI总线上可以挂连多个设备以外,在一条PCIExpress链路上由于采用点到点的连接只能挂连一个设备。//------------------------------------------------------------------------------------------------------------------------//3PCIE配置空间访问机制处理器一般不具有直接生成配置读和写事物的能力,比如Intelx86和PowerPC处理器,它们使用存储器或IO(IO仅在x86情况下)指令生成存储器或IO读写事物,访问外部设备的存储器或IO空间。由于我们只讨论x86和windows系统,所以使用IO指令访问外设。而访问机制一般有两种,即:1.PCI兼容的配置访问机制;2.PCIExpress增强的配置机制不过,使用PCI兼容的配置访问机制只能访问到功能的4KB配置空间中的PCI兼容配置寄存器区(256B),PCIExpress增强配置访问机制可以访问到整个4KB配置空间。两者访问方法的不同之处在于处理器向Host-PCI桥表达自己配置访问意图的方式。//------------------------------------------------------------------------------------------------------------------------//4PCI月PCI-E的兼容物理上你觉得可能兼容么?PCI几十根线,PCIE几对线,怎么个接法?PCIE协议兼容PCI操作,但是只是用PCIE协议来模拟PCI协议而已//------------------------------------------------------------------------------------------------------------------------//5配置空间的解析首先,PCIE空间的配置寄存器规格是约定的,通过按顺序解析配置空间的寄存器,即可获得完整解析配置空间的能力。其次,RP端是通过配置读来获取EP信息的。整个过程大致是1,链路充电轮询,2.爬电监测3.同步,获取链路属性,4RP发起配置读信息,5.RP通过配置写分配路由6.应用层该干嘛干嘛1。处理器为内存分配空间可以连续,可以不连续,但是一个bar内的空间要连续2。如果是PCIE定义的BAR空间在内存中的镜像,那么是边丢边发,如果是用于DMA的,那这个空间是可以另外定义的,需要FPGA逻辑来搬运,称之为DMA,当然,如果PC很闲的话,也可以PC一个一个往BAR空间放,然后由操作系统一个一个去搬。3。处理器不仅仅为PCIE分配一块存储区域,这取决于你的BAR的数量,最多6个Bar。所有需要CPU以PIO方式读写的FPGA内部地址全部都得映射到PC分配的空间里。所以这个PIO空间不可太大,否则太占内存。大数据量的需要以DMA来实现不是,协议规定PCIE设备最多有6个BAR,也就是说允许处理器为这个设备分配6段连续的存储空间。这样可以避免单一设备占用很大的存储空间,不利于内存利用。另外也便于下位机进行地址转换。一般是Bar0有类型0的CSR信息,Bar1放IO信息,BAR2,BAR3是基于查找表的地址配置,即给偏址,BAR4、5是直接地址,即给出来的地址为下面实际的地址。不过如果是自己做,图简单的话,只用BAR0就可以了//------------------------------------------------------------------------------------------------------------------------//6读写控制常用的方法举个典型的例子吧,首先我不建议你在bar0空间里放数据,太浪费,bar0空间就放一些控制用的寄存器吧,相对数据而言,没多少的。对FPGA地址的读写,假设FPG**内你设计了一个地址查找表,某寄存器byte地址为0x000055aa,那么你在PC端往bar0基址+0x000055aa写一个byte数0x1,那么这个寄存器的值就是0x1。对大段的数据而言,你在内存中开辟一段存储空间,比如0xcc000000~0xdd000000,然后在FPGA里头做一个DMA控制器,通过PC往FPGA的寄存器里写DMA起始地址0xcc000000和dma的长度**x,然后你做的这个DMA控制器开始向PCIEIP发送读请求,读地址是0xcc000000+不停累加的偏址,当读到指定长度后,DMA控制器停止工作,并且发一个中断给PC。//------------------------------------------------------------------------------------------------------------------------//7bar空间在PC内存中的基地址首先,一般情况下,FPGA不需要知道bar空间在PC内存中的基地址。不过想知道的话,也可以。可以通过截取类型0配置包获得pcie配置空间的内容。如果用IP的话,可以用IP提供的配置空间接口。比如ALTERA就有多种途径,你看看手册上,给出的几个接口。除了用来接收数据包的,剩下的大多数是用来读配置空间的。还有那个test_in,test_out也是在这里玩的。实际上pcie在调试过程中,如果出了问题,大部分情况下,借助于配置空间中的各项参数以及ltssm的值,是能大致判断问题的。在没有高级示波器或者逻辑分析仪的情况下,这也是仅有的调试手段。当然我这里指的不包括用户逻辑出的问题。//------------------------------------------------------------------------------------------------------------------------//8Bar空间的定义所谓BAR,是BaseAddressRegister,即基址寄存器的意思。所有需要将系统存储器,IO或者存储器映射的IO地址分配给上层应用软件作为目标设备的设计都必须实现BAR。也就是说,所谓BAR空间,就是PCIE设备空间在操作系统中的映射。简单的说,PCIE设备就是BAR空间。BAR不是一个交换的缓存,而是PCIE设备上的资源在PC内存的映射。不存在访问不访问的问题,上位机实际上能操作的只能是内存的空间,所以所有外设的IO,如果需要上位机访问,必须映射到内存中。那么是不是所有设备端口都必须映射到一块连续的空间呢?不是的,因为这样既不利于管理,也不便于使用。因此可以分成几个不同的功能区来处理。于是就定义了BAR,bar空间是上位机根据下位机声明的大小来建立的,物理存在于PC内存中。//------------------------------------------------------------------------------------------------------------------------//9如何发起读写操作你这个概念比较乱,直接说吧,以你的例子,假设你是个32bit系统,这里BAR0选择32-bitnonprefetchable,大小选2MB就好了,其他的BAR都不要(其实2MB都多余,几个就够了)。然后在FPGA里头做3个寄存器,分配地址。比如说你通过驱动申请到的PC内存空间Byte地址为0x66000000~0x661fffff(对应2MBBar),然后你往PC内存空间0x66000000写0x55aa55aa,那么在PCIEIP的用户接口就会收到一个地址为0x0,数据为0x55aa55aa的报告请求。你这两个寄存器地址就可以分别定义为0x0和0x4,0x8,然后通过上位机往0x66000000和0x66000004,0x66000008写数据,把数据写到这3个寄存器中。现在说这3个寄存器做什么用的。第一个寄存器定义为目的地址,你首先应该在PC内存空间中申请一块地址用于存AD上传数据(这空间可以每次DMA前再申请,没必要在那2MB内,那2MB是定死的,长期占用内存的,这个空间是任意的,每次用完就可以还的,可以申请非常大,也不影响系统工作),例如0x88000000~0xXXXXXXXX,第一个寄存器就写0x88000000,表示DMA目的地址。第二个寄存器定义为长度,即DMA数据的大小。第三个寄存器定义为开始寄存器,上位机往这个寄存器先写0,再写1,FPGA在收到这个上升沿的时候发起DMA操作。DMA操作的流程是,当收到发起操作的命令时(PC发完命令就可以去做别的事了),FPGA通过PCIEIP往0x88000000(将这个地址写入报告写请求的包头,以此为第一个包,每个包地址需不断累加)发写请求包,不断的发(要看信用),直到发完指定长度的包。然后停止发送,给PC一个中断(有个中断线,拉一下就好,事先驱动需要先注册一下这根中断线)。然后数据就传完了,在PC内存里,PC就可以拿去交差了。这里的写都是存储器写。//-------