文档库 最新最全的文档下载
当前位置:文档库 › PCIE---论坛

PCIE---论坛

//------------------------------------------------------------------------------------------------------------------------
==================================================PCIE 讨论对答=========================================================
//------------------------------------------------------------------------------------------------------------------------
//1 学习步骤:
并行协议,不要用CPLD就行了。至于后面怎么做。如果是小白,先不看PCI协议,先看Freescale的Flash BUS协议或者Altera的Avalon MM
总线协议,这两个协议简单易懂,理解透了再看PCI就很容易明白了。做逻辑设计的,先关注什么是主从,怎么同步,怎么读写,地址
怎么表示,如何竞争,如何仲裁,如何握手。中断怎么表示,如何提高效率,然后再看如何路由,出错怎么办,一开始怎么检测,
(这已经到通用标准协议了)。怎么仿真,如何验证。然后可以选择往硬件走,比如电流电平,带载能力,阻抗要求,jitter范围,
抗冲击能力,如何测量,接收标准. 或者走软件,了解总线层级结构,哪些层做了哪些事。软件的硬件平台结构,谁在控制。接口最大
最小响应时间,系统兼容性,健壮度。协议的缺陷在哪里,可靠性如何保证等等,然后再考虑总线对应用的要求。合理操作的范围等等
//------------------------------------------------------------------------------------------------------------------------
//2 配置空间问题
继续配置空间:提出一个问题,配置空间是不是一般是我们在FPGA例化pcie核的时候分配的BAR0?或者说是BAR0的一部分呢?
继续:配置空间的层次以及大小, 在PCI Express系统中,总线号(8位)、设备号(5位)和功能号(3位)组成了每一功能的16位地址,
也确定了每一设备中的每一功能在PCI Express系统拓扑结构中的位置。从上面的数字可以推出,一个PCI Express系统最多有256条总线
或链路,每条总线上最多可以挂2的16次方个功能,再加上每一功能的配置空间容量为4KB,系统的配置空间总容量为4KBX64K=256MB=2的
28次方B。实际上,不可能存在含有64K个功能的系统,因为除了在交换开关或根复合体内部的逻辑(虚拟)PCI总线上可以挂连多个设备
以外,在一条PCI Express链路上由于采用点到点的连接只能挂连一个设备。
//------------------------------------------------------------------------------------------------------------------------
//3 PCIE配置空间访问机制
处理器一般不具有直接生成配置读和写事物的能力,比如Intel x86和PowerPC处理器,它们使用存储器或IO(IO仅在x86情况下)指令生
成存储器或IO读写事物,访问外部设备的存储器或IO空间。由于我们只讨论x86和windows系统,所以使用IO指令访

问外设。而访问机制
一般有两种,即: 1.PCI兼容的配置访问机制; 2.PCI Express增强的配置机制 不过,使用PCI兼容的配置访问机制只能访问到功能
的4KB配置空间中的PCI兼容配置寄存器区(256B),PCI Express增强配置访问机制可以访问到整个4KB配置空间。两者访问方法的不同之
处在于处理器向Host-PCI桥表达自己配置访问意图的方式。
//------------------------------------------------------------------------------------------------------------------------
//4 PCI月PCI-E的兼容
物理上你觉得可能兼容么?PCI几十根线,PCIE几对线,怎么个接法?
PCIE协议兼容PCI操作,但是只是用PCIE协议来模拟PCI协议而已
//------------------------------------------------------------------------------------------------------------------------
//5 配置空间的解析
首先,PCIE空间的配置寄存器规格是约定的,通过按顺序解析配置空间的寄存器,即可获得完整解析配置空间的能力。其次,RP端是通
过配置读来获取EP信息的。整个过程大致是1,链路充电轮询,2.爬电监测 3. 同步,获取链路属性,4 RP发起配置读信息,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控制器开始向
PCIE IP发送读请求,读地址是0xcc000000+不停累加的偏址,当读到指定长度后,DMA控制器停止工作,并且发一个中断给PC。
//------------------------------------------------------------------------------------------------------------------------
//7 bar空间在PC内存中的基地址
首先,一般情况下,FPGA不需要知道bar空间在PC内存中的基地址。不过想知道的话,也可以。可以通过截取类型0配置包获得pcie配置
空间的内容。如果用IP的话,可以用IP提供的配置空间接口。比如ALTERA就有多种途径,你看看手册上,给出的几个接口。除了用来接
收数据包的,剩下的大多数是用来读配置空间的。还有那个test_in,test_out也是在这里玩的。实际上pcie在调试过程中,如果出了问
题,大部分情况下,借助于配置空间中的各项参数以及ltssm的值,是能大致判断问题的。在没有高级示波器或者逻辑分析仪的情况下,
这也是仅有的调试手段。当然我这里指的不包括用户逻辑出的问题。
//------------------------------------------------------------------------------------------------------------------------
//8 Bar空间的定义
所谓BAR,是Base Address Register,即基址寄存器的意思。所有需要将系统存储器,IO或者存储器映射的IO地址分配给上层应用软件
作为目标设备的设计都必须实现BAR。也就是说,所谓BAR空间,就是PCIE设备空间在操作系统中的映射。简单的说,PCIE设备就是BAR空
间。BAR不是一个交换的缓存,而是PCIE设备上的资源在PC内存的映射。不存在访问不访问的问题,上位机实际上能操作的只能是内存的空
间,所以所有外设的IO,如果需要上位机访问,必须映射到内存中。那么是不是所有设备端口都必须映射到一块连续的空间呢?不是的,
因为这样既不利于管理,也不便于使用。因此可以分成几个不同的功能区来处理。于是就定义了BAR,bar空间是上位机根据下位机声明的
大小来建立的,物理存在于PC内存中。
//------------------------------------------------------------------------------------------------------------------------
//9 如何发起读写操作
你这个概念比较乱,直接说吧,以你的例子,假设你是个32bit系统,这里BAR0选择32-bit non prefetchable,大小选2MB就好了,其他
的BAR都不要(其实2MB都多余,几个就够了)。然后在FPGA里头做3个寄存器,分配地址。

比如说你通过驱动申请到的PC内存空间Byte地
址为0x6600 0000~0x661f ffff(对应2MB Bar),然后你往PC内存空间0x6600 0000写0x55aa55aa,那么在PCIE IP的用户接口就会收到
一个地址为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通过PCIE IP往
0x88000000(将这个地址写入报告写请求的包头,以此为第一个包,每个包地址需不断累加)发写请求包,不断的发(要看信用),直到
发完指定长度的包。然后停止发送,给PC一个中断(有个中断线,拉一下就好,事先驱动需要先注册一下这根中断线)。然后数据就传
完了,在PC内存里,PC就可以拿去交差了。这里的写都是存储器写。
//------------------------------------------------------------------------------------------------------------------------
//10 FPGA主动发写数据
你好,请问FPGA是否能主动给电脑发数据(DMA模式)?如果是的话FPGA如何获取存储器地址在PCI地址域的映射?也就是说我要发到哪
里去?恳请指教。FPGA数无法主动向PC内存发送数据的,需要PC先配置DMA,比如读写地址、读写长度等,然后再启动DMA,这时DMA就会
根据寄存器信息往PCIE发送数据。
我想你的意思是想实现fpga主动发起dma,把数据从fpga(或者所连接的外部存储器)(这里统称on-chip ram)通过pcie搬移到pc机的
内存(这里说:Mem)。 这个工作其实就是网卡的工作原理。我这里以Scatter Gather DMA为例,简单讲一下。
on-chip ram --> Mem
1. 首先驱动程序开始的时候,申请一个环形数据缓冲区,Ring。Ring里面存放指向Discriptor Table的指针和一些状态信息。Discriptor
可以申明为结构体,他包含两个地址信息,一个为cpu可读地址,一个是dma物理地址,另外可以配备一些别的状态信息,看你的需要。
整个Discriptor Table的区域是dma coherent的区域,这样fpg

a里面的dma或者你自己的逻辑可以通过pcie访问这整个table。只有一个
table,其中包含了多个discriptor。table中discriptor的数量也是你根据你的数据量自己设定。
2. 为table的每一个discriptor都分配dma map的区域。然后每个discriptor中的两个地址信息分别存放了刚刚dma map出来的这个区域
的物理地址和cpu可访问地址。这个区域dma map后,目前cpu不能访问。这个区域的大小是你提前设定的。
3. 你fpga里面自己设定一些寄存器,来存储pc机系统中Discriptor Table的入口地址(base address),discriptor的数量,每个
discriptor有多大。因为整个table的区域是dma coherent(连续内存)的,所以你可以通过base address和已经使用的discriptor数量
(或者编号)计算出下一个可使用的discriptor的地址。
4. 驱动一些准备好以后,当你想从fapga发数据,fpga里面的dma controller或者你自己的逻辑,通过pcie读取table里面的下一个可用
的discriptor,获取你目前的数据在Mem中可以存放的物理地址,然后开始fpga里的dma,长度不能超过你在步骤2中设定的大小。如果你
要传送的数据比这个大,你就分包传送。每次传送你都获取一个新的discriptor,从而得到新的可用空间的物理地址。传送结束后产生
中断通知cpu,这时候,数据已经在Mem里边了,只是cpu还不能获得,在ISR中则把已经存了数据的区域dma unmap,切断discriptor与他
的联系,把这块区域的cpu可读地址传给cpu,然后重新分配一块新的内存,再dma map,再链接到刚才空出来的discriptor,以备下次使
用,同时还要更新fpga里面的寄存器现目前discriptor的使用情况。如果你只设定一个discriptor,其实就是传统普通的dma,一次只能
搞定一个包,传完后cpu处理完,重新分配内存,fpga再传。

//====================================================================================================================//

相关文档