学习PCIe,使用FPGA作为RC,实现对SSD(EP)的读写
(前半部分,PCIE,DEMO的实现和分析)
参考:
1:AMD官网:https://docs.amd.com/r/en-US/pg055-axi-bridge-pcie/Add.-Debug-Options
2:大佬介绍: https://blog.csdn.net/u011565038/article/details/136896068
3:XPDMA(pg055):https://download.amd.com/docnav/documents/ip_attachments/axi-pcie.html
IP核简介
分为两部分AXI MM/S Bridge和AXI-S Enhanced PCIe。
AXI MM/S Bridge负责将用户侧的逻辑接口(采用标准AXI4总线)转换为AXI-stream数据流。
AXI-S Enhanced PCIe部分处理来自AXI MM/S Bridge的AXI-stream数据流,并将其转换为PCI Express协议所需的事务层数据包(TLP)。同时,它还能够将来自PCI Express的TLP数据包转换回AXI-stream数据流。
配置完IP之后,我们需要关心的只有用户侧的三部分,axi_ctrl,m_axi,s_axi三个接口。
AXI Memory Mepped To PCIe 核的配置
板卡使用7100,以Z7为例
1,首页主要配置FPGA作为RC,还有使能Link Status Register,参考时钟默认100MHz
2,配置一栏主要选择 连接的位置 和 PCIe的速度等级和Lane宽度
此板卡只有1路M.2接口,Location选择X0Y0(如果有多路接口,参考原理图选择本次连接位置)
Lane的宽度选择x4,里面有4条link(同时x4是gen2的最大宽度)
速度等级选择gen2(5GT/s----500MB/s 一条link读或写的理论速度) 5G * 8 / 10 / 8
使用8/10b编码,因为是全双工通信,所以实际上一条link的理论速度是1GB/s。
3,下面是ID的配置,基本上是默认
Vendor ID : Xilinx的ID(使用它家芯片的都是这个)
Devide ID : 0x7124
7:表示7系列的芯片(Z7,V7,A7,K7)
1:表示作为RC(0表示作为EP)
2:表示PCIe的速度等级,gen2
4:表示Lane的宽度,4links
Class code : 这个保持0x060A00,和后面的加载驱动有关
06:base classs 板卡的功能类型(桥,switch等等)
0A: sub_class 更加具体的类型 (比如PCI-PCIe桥等)
00: interface 接口类型
4,基地址空间的设置
我们使能64位的Bar,大小设置为1GB
(RC只能1个32位或者64位的bar,最大2GB)
5,中断设置,保持默认
使能中断,动态地址传输
6,BAR 的映射地址设置,保持默认(AXI memory space ------- PCIe memory space)
这个是设置AXI BARS 的地址范围
7,AXI addring and Interconnect parameters
这个是设置device的地址范围
互联模块M_AXI和S_AXI的地址,数据位宽大小
后面的debug和共享功能都不使用
导出历程源码分析
generate output products之后,open example design
rtl 框图结构如下
m_axi_model: 充当主机,连接IP核的S_AXI端口,向里面发送读写请求
axi_pcie_0: IP核
axi_bram_ctrl_0:BRAM模块,充当从机,连接IP核的M_AXI端口,访问外设(BRAM,DDR)
m_axi_ctrl_model:配置模块,保证初始化完成
1,m_axi_model:主要是等配置完成之后,向地址0x4000000a写入数据0xb4b4b4b4
等写完成之后,在读取地址0x40000008的数据
2,axi_bram_ctrl:这个模块没用到,因为例程只通过FPGA(RC)向EP模型读写
没有FPGA读写外设(BRAM,DDR),没用到M_AXI端口
3,m_axi_ctrl_model:读取地址0x00000144的值(包含了link,rate,width,ltssm_state)
当读取的数值和配置的一直时,拉高连接完成信号;
然后通过AXI_Lite接口继续配置,配置完成,拉高配置完成信号
读出地址0x00000144的值,每一位对应关系
写入地址和值对应如下:
仿真记录分析
仿真框图如下:
添加了一个EP模型
1,先看配置模块m_axi_ctrl_model:
复位结束之后,读取地址0x00000144的值,读出的数据是0x00000006,和我们配置的不一致,继续读该地址的值
之后可以观察到,144地址读出的数据一直在变化,一直到读出值为0x000008b4才停止
这个时候,已经可以说明我们配置IP(RC)的参数和仿真模型(EP)里的link,gen参数一致
link_up拉高
然后开始根据IP的参数,通过Lite接口继续配置(即向不同地址写入不同参数)
配置完成后,拉高cfg_cmpld_pluse一周期,然后m_axi模块开始进行读写操作
2,m_axi模块
首先是向地址0x4000000a写入0xb4b4b4b4
然后读取地址0x40000008的数据
在握手信号有效时,读出的数据正确
注意:
我们写入的地址是0x4000000a,读出的地址是0x40000008
而我们设置的数据位宽是128位,所以读出的时候会先将0x40000008读出,然后再从高位读出数据
写入:0x4000000a-------0x00000000_00000000_00000000_b4b4b4b4(_00000000_00000000)
后面是default值
读出:0x40000008-------0x00000000_b4b4b4b4_00000000_00000000
配图1:(RC,type1型)
PCI_Express_Base_Specification_Revision2.0.pdf
配图2:(AXI address memory mepped)
pg055-axi-bridge-pcie.pdf