时间:2024-07-27 来源:网络搜集 关于我们 0
日前,小眼睛科技开展了基于紫光同创Logos系列PGL50H的盘古50K开发板免费试用活动。近期,小编将陆续为大家推出系列体验报告。本期分享来自从事微电子芯片设计的FPGA工程师:死神杜兰特。本期推出:体验紫光同创PCIE之DMA读写/PIO内存读写TLP解析。
一:PIO内存读写操作TLP解析
读3DW数据。
注意的是,根据PCIE协议的Mwr,一次Mwr/Mrd数据大小最大可以是4096Byte,上面大于4Byte分了多次Mwr发送是驱动程序的做法。看到时序图的信号都是满足要求的,但是具体信号的数据是怎样的呢?现在以读写12Byte Memory为例来分析这些数据。
Write/Read Memory 使用到了三种类型的报文—Mwr/Mrd/CplD。在使用PCIE IP时,底层的东西可以不需要太关心,但是解析接收到的TLP解析和发送合乎要求的TLP是重点。
对于Mwr/Cpld,他们携带的数据就是数据,没什么需要分析的,需要分析的是TLP中的Header,Mrd报文只有Header,分析Header才是重点。
注意的是,Mwr/Mrd是地址路由,而CplD是ID(Bus/Device/Function)路由,这是协议规定的,所谓路由简单理解就是RC根据地址/ID,能够在众多的PCIE传输路径中把数据送到目标设备,因为内核程序初始化给给每个BAR分配了PCIE总线域空间,每个BAR空间地址都是独立映射的,而ID根据(Bus/Device/Function)唯一确定。
对于Mwr/Mrd的Header格式如下图:Mwr:
Header:0x0000_0000_df20_2000_0000_000f_4000_0001
Data: 0x0000_0000_0000_0000_0000_0000_0102_0304
Header:0x0000_0000_df20_2004_0000_000f_4000_0001
Data:0x0000_0000_000_0000_0000_0000_0506_0708
Header:0x0000_0000_df20_2008_0000_000f_4000_0001
Data:0x0000_0000_0000_0000_0000_0000_090a_0b0c 对于Mwr的Header,对着协议格式分析,很容易知道第一个Header地址(32bit)是df20_2000,携带数据长度Length(以DW为单位)为1,报文类型[Fmt,Type]=0x40(表明为3DW Mwr),字节使能[last DW BE,first DW BE]=0x0f,其他信息对座入号就行了,特别注意的是TLP是大端格式,[Fmt,Type]=axis_master_tdata[31:24],实际代表的是0Byte的位置,其他DW数据亦如此。Mrd:
Header:0x0000_0000_df20_2000_0000_000f_0000_0001
Header:0x0000_0000_df20_2004_0000_000f_0000_0001
Header:0x0000_0000_df20_2008_0000_000f_0000_0001 对于Mrd的Header,对着协议格式分析,很容易知道地址(32bit)是df20_2000,请求数据长度Length(以DW为单位)为1,报文类型[Fmt,Type]=0x00(表明为3DW Mrd),字节使能[last DW BE,first DW BE]=0x0f,其他信息对座入号就行了,深入了解可读PCIE协议规范。CplD:
Header:0x0000_0000_0000_0000_0100_0004_4a00_0001
Data:0x0000_0000_0000_0000_0000_0000_0102_0304
Header:0x0000_0000_0000_0010_0100_0004_4a00_0001
Data:0x0000_0000_0000_0000_0000_0000_0506_0708
Header:0x0000_0000_0000_0020_0100_0004_4a00_0001
Data:0x0000_0000_0000_0000_0000_0000_090a_0b0c 对于Cpld的Header,采用的是ID路由,很容易知道Requester ID为0x0000,Completer ID为0x0100,回复数据长度Length(以DW为单位)为1,报文类型[Fmt,Type]=0x4a(表明为CplD),Byte Count为0x004,TAG为0x00,其他信息对座入号就行了。具体的含义可查询PCIE协议规范。2048Byte DMA读,FPGA到主机。
通过上面的DMA读写时序图不难发现,实现DMA读,主机会首先发3次Mwr TLP给FPGA,FPGA解析MWr TLP后会发起Mrd TLP,主机再回复CplD TLP,这样就数据传输到FPGA了;实现DMA写,主机首先发3次Mwr TLP给FPGA,FPGA解析MWr TLP后会直接上发带数据的MWr TLP,这样就数据传到主机了。主机的3次MWr TLP是什么呢?通过解读例程的DMA模块下的dma_controller模块,不难发现,BAR1+0x100偏移量的数据是指示FPGA发起带数据的Mwr/不带数据的Mrd(也包含数据长度等),BAR1+0x100偏移量的数据是搬运数据的主机物理内存首地址的低32位,BAR1+0x100偏移量的数据是搬运数据的主机物理内存首地址的高32位。DMA是直接存储器访问,要直接从主机内存搬数据/写数据,首先要知道主机内存首地址。一定是3次Mwr TLP通信握手吗?肯定不是的,这是生成IP例程的做法,自行设计DMA控制器的话,可以使用更复杂/更有效的握手机制来触发DMA操作。时序图中Header:DMA——主机的Mwr (以1024Byte为例)第一次:
Header:0x0000_0000_df20_4100_0000_000f_4000_0001
Data:0x0000_0000_0000_0000_0000_0000_ff00_0100第二次:
Header:0x0000_0000_df20_4110_0000_000f_4000_0001
Data:0x0000_0000_0000_0000_0000_0000_00a0_2647第三次:
Header:0x0000_0000_df20_4120_0000_000f_4000_0001
Data:0x0000_0000_0000_0000_0000_0000_0100_0000 这个Mwr是32bit Address访问,存储器访问都是通过地址路由,Header的意义和上面Mwr分析是一致的。DMA——主机的CplD(以1024Byte为例)第1个Header:0x0000_0000_0100_0000_0000_0200_4a00_0020第2个Header:0x0000_0000_0100_0000_0000_0180_4a00_0020第3个Header:0x0000_0000_0100_0000_0000_0100_4a00_0020第4个Header:0x0000_0000_0100_0000_0000_0080_4a00_0020第5个Header:0x0000_0000_0100_0100_0000_0200_4a00_0020第6个Header:0x0000_0000_0100_0100_0000_0180_4a00_0020第7个Header:0x0000_0000_0100_0100_0000_0100_4a00_0020第8个Header:0x0000_0000_0100_0100_0000_0080_4a00_0020完成报文使用ID路由(协议规定,简单就是对于每一个BAR,都有自己的ID(Bus/Device/Function),通过这个唯一的ID可以找到接收目标)。CplD的Header只能是3DW组成,具体和上面CplD分析是一致的。需要注意的是协议规定CplD最大数据长度是1024DW(4096 Byte),但是我们IP配置页面默认设置Max Playload Size其实是128 Byte,所以大于128 Byte的数据需要分多次发送。需要注意的是前4 Header的TAG=0x00,后4 Header的TAG=0x01,为什么这样,因为FPGA发了两次Mrd,TAG就是记录发了Mrd,收到完成报文中TAG和Mrd一致,代表当前Mrd完成了。可以知道TAG是8bit,一旦Mrd的TAG=0xff,但是0x00的CplD还没回复,Mrd便不可再发送了(对于同一个的BAR的Mrd)。可以看到Byte Count是变化的,这个很好理解,表示当前传输距离Mrd请求的数据量还有多少(这里不是我们最终的1024 Byte,而是一个Mrd的Byte数)。第一个Header为0x200,表示距离Mrd请求数据量还有512 Byte,第二个Header为0x180,表示距离Mrd请求数据量还有384 Byte,以此类推。一次Max Playload Size是128 Byte,传输一次CplD,距离目标就减少128 Byte。到了第5个Header,为什么回到512 Byte了,因为第5个Header CplD是新的Mrd请求了,同样请求长度为512 Byte。DMA——FPGA的Mrd(以1024Byte为例)Header:0x20d5_0400_0000_0000_0000_0001_0100_1c80
Header:0x20d5_0480_0000_0000_0000_0001_0100_3c80 这个Mrd是64bit Address访问,存储器访问都是通过地址路由,Header的意义和上面Mrd分析是一致的。这个64bit的地址是FPGA要读主机的内存的地址,低32bit放在第4DW,高32bit放在了第3个DW,这个地址肯定不是固定的,即使同一台电脑,主机每次读写开辟内存空间放数据的位置也不一样。这里Mrd为什么需要分两次发送呢,因为PCIE IP设置的Max_rd_req_size为512 Byte,所以大于512 Byte的数据,需要分多次Mrd,例如向主机内存请求2048 Byte的数据,需要4次Mrd,每一个Mrd记录一个Tag,这样就对应上了CplD的Tag。DMA——FPGA的Mwr(以1024Byte为例)Mwr已经展开多次了,就不重复了。END