基于blockdesign的PCIe BRAM读写器——Vivado工程搭建

在这里插入图片描述
DMA 直接存储器访问
BRAM 随机访问数据存储器

每个单元对应每个地址 在读写数据时 都会先获取地址 在进行读写数据 BRAM是FPGA内部专用的存储资源,性能优异但数量有限,每一个BRAM是36Kb大小,也可以配置成2个18Kb的BRAM,BRAM可以用来实现多种不同位宽和深度的RAM/ROM/FIFO,在FPGA中应用非常广泛和灵活。

xdma的原理
xdma的主要原理是通过直接访问主机内存,实现数据的快速传输。
在传统的DMA ( Direct Memory Access )技术中,数据传输需要经过CPU的干预,而xdma可以绕过CPU,直接将数据从外设读取到主机内存或者从主机内存传输到外设。这样可以大大提高数据传输的速度和效率。

XDMA主要是在应用层面
在FPGA例化配置完以后基本上就不需要FPGA在逻辑层面上进行过多的操作了,FPGA只需要对HOST主机进行中断触发操作即可,所有的DMA操作完全由HOST主机通过PCIE配置XDMA的寄存器来实现。
主要通信的结构
一般的PCIE通信模式就是host需要数据或者host被通知数据到达时,host通过配置endpoint端DMA寄存器,然后DMA通过PCIE将数据由endpoint端搬运至HOST端的过程,当host需要发送数据给endpoint时,则通过配置endpiont端的DMA寄存器将数据通过PCIE由host端搬运至endpoint端
那DMA怎么知道把数据从哪里搬到哪里
PCIE的地址空间管理,PCIE通过BAR空间映射将设备端的地址空间映射到主机里的一段地址空间,这样在主机端直接操作对应的BAR空间就是在操作endpoint里面的地址空间了,而这种映射关系就需要主机在驱动加载的过程中,去配置对应endpoint的BAR空间寄存器去分配地址空间和长度

加载与初始化过程
从上电开始说起,我们的电脑就是HOST端,我们的板卡就是EP端;上电后双方各自加载各自的软件,EP加载完后等着电脑(电脑比较慢,也需要他慢),HOST在上电后先初始化自己的PCIE设备,然后扫描PCIE总线上的EP设备(这一部分在HOST驱动完成),如果EP在物理层上与HOST端LINK上了,那HOST就会给EP分一个设备号,并且获取EP的PCIE的header寄存器(一般存储了PCIE设备的ID,和其他的能力属性),将这些信息暂存。当系统启动末期在加载设备驱动的时候PCIE总线驱动会匹配驱动程序的ID与上面暂存的ID,如果匹配成功,加载设备的驱动程序,在设备驱动里完成EP的BAR空间分配,中断分配等工作。那这个通信链路就算搭建完成了……

通过vivado建立工程
在这里插入图片描述

搭建 blockdesign

在这里插入图片描述
创建pcie ip核进行配置信息
在这里插入图片描述
然后就可以看到 Diagram 中出现了一个叫 xdma_0 的 IP 。双击这个 xdma_0 ,配置这个 IP 的参数,该 IP 的配置一共有5页。其中第一页最重要,如下图,你可以指定 PCIe 和 AXI 接口的相关信息。其中大多数选项与下图保持一致即可,但有一些选项你可以根据需要去修改:

(PCIe Lane Width(PCIe通道宽度)指的是PCI Express(PCIe)连接中可用的物理通道数量)。
Lane Width 可以自由指定,因为 NetFPGA 的 PCIe 为 x8,我们可以取 x1, x4, x8 。本例中取 x1 。
Maximum Link Speed 代表的是 PCIe 的速率,可以自由指定,2.5 GT/s 代表 PCIe Gen1, 5.0 GT/s 代表 PCIe Gen2,8.0 GT/s 代表 PCIe Gen3 。本例中取 5.0 GT/s
Reference Clock Frequency 是指 PCIe 参考时钟的频率,由于 NetFPGA 使用的是来自 PCIe 插口的,由电脑主板提供的 PCIe 参考时钟,而 PCIe 规定该时钟频率为 100MHz 。因此这里取 100MHz 。
AXI Data Width 是 AXI 总线中数据总线的宽度,也即一个周期最多可以读/写的比特数量。可以自由指定,但要和 AXI slave 保持一致。本例中取 64 bit。
AXI Clock Frequency 是 AXI 总线的时钟频率,可以自由指定,只要 AXI slave 能工作在这个频率下就行。本例中取 62.5 MHz 。

PCIe BARs(Base Address Registers)
是PCI Express(PCIe)设备中的一组寄存器,用于访问设备的内存地址空间和I/O地址空间。这些寄存器存储了设备内存区域和I/O端口区域的基地址。PCIe BARs的作用是提供了CPU和PCIe设备之间进行数据交换的通道,使得设备可以与系统进行通信和数据交换。

在这里插入图片描述
PCIe misc
通常指PCIe(Peripheral Component Interconnect Express)的一些其他或杂项功能、属性或配置。这些功能可能不属于PCIe规范中定义的主要特性,但可能对特定的应用或环境有重要意义。

在这里插入图片描述
PCIe DMA(Direct Memory Access)
是指通过PCIe总线直接访问计算机内存的技术。DMA允许外部设备(如网卡、磁盘控制器等)直接访问系统内存,而无需通过中央处理器(CPU)的介入。这样可以提高数据传输的效率和速度,减少了CPU的负载,从而提高了系统的整体性能

在这里插入图片描述
用 Constant IP 把 XDMA 的中断输入设为 0
xdma IP 添加好后,我们可以看到它的左边有一个 usr_irq_req[15:0] 信号,它是用来向主机发送中断的。由于我们暂时用不着中断,需要让该信号恒定设置为0 。
为此,我们在 Diagram 中点上方的 “+” (Add IP) ,输入 constant ,然后双击 “Constant”,如下图 。
在这里插入图片描述
然后我们可以看到出现了一个叫 xlconstant_0 的 IP,该 IP 非常简单——输出一个恒定值,我们双击该 IP ,设置 Const Width = 16 ,Const Val = 0 ,然后点 OK ,如下图。
在这里插入图片描述
然后把 xlconstant_0 的输出 (dout) 连接到 xdma_0 的 user_irq_req[15:0] 上,如下图。
在这里插入图片描述
AXI(Advanced eXtensible Interface)是一种高性能、高带宽的总线协议,用于连接计算机系统中的各种硬件组件,如处理器、内存、外设等。它提供了一种灵活、可扩展的接口,能够支持并行数据传输、乱序访问等特性,以满足现代计算机系统对高性能、高效率的需求。
BRAM(Block RAM)是一种内置的存储器资源,通常用于FPGA(Field-Programmable Gate Array,现场可编程门阵列)中。BRAM提供了一种快速、可靠的存储器解决方案,可以在FPGA中存储大量数据或配置信息。BRAM通常具有低延迟、高带宽的特性,适用于需要高速数据存储和访问的应用场景。
“AXI BRAM” 是指连接到AXI总线的BRAM,即使用AXI协议与FPGA中的BRAM进行通信。这种组合可以实现对BRAM的高效访问,并通过AXI总线与其他外设或处理器进行数据交换。

在这里插入图片描述
可以看到出现了一个叫 axi_bram_ctrl_0 的 IP,该 IP 的功能是充当 AXI master 和 “裸BRAM” 之间的桥梁,可以理解为进行一个协议转换——接收 AXI 总线的命令,把它转化为对 “裸BRAM” 的读写。

在这里插入图片描述
现在我们发现 AXI BRAM controller 右侧的 BRAM_PORTA 还空着,它需要连接一个 “裸BRAM” 。“裸BRAM” 是一个名为 Block Memory Generator 的 IP ,你可以手动添加,但另一个简便的添加方法是点击上方的 Run Connection Automation ,这是 Vivado 提供的一个智能添加功能,比如它发现你添加了 AXI BRAM controller ,那么它猜测你下一步大概率想添加一个 “裸BRAM” 连上去,那么它就会自动帮你完成这个工作。
在这里插入图片描述
连接好后再把一些引脚引出去
在这里插入图片描述
在 blockdesign 中,只要有 AXI master 和 AXI slave 对接的情况,就需要进行地址分配 。因为一个 AXI master 可能对应多个 AXI slave ,我们需要分配这些 AXI slave 在该 AXI master 中对应的地址 ——即使只有一个 AXI slave。

我们切换到 Diagram 旁边的 Address Editor ,发现目前 AXI master (也即xdma_0) 有一个 AXI slave (也即 axi_bram_ctrl_0) 没有分配地址。我们右键它,点击 “Assign Address” ,然后它会自动分配一个地址。

在这里,我们为了方便,把 Offset Address 设为 0x0000000000000000 。换句话说, 当 xdma_0 通过 AXI 总线对 0x0 这个地址进行读写时,读写的就是 axi_bram_ctrl_0 的起始位置。

我们切换回 Diagram ,然后点击上方的 “Validate Design” ,软件会帮我们检查该 blockdesign 中是否有错误。它只能检查出一些低级错误(比如 AXI 总线两侧的位宽不匹配),而功能性的正确性还需开发者自己保证。
在这里插入图片描述
生成 blockdesign 的 HDL Wrapper
blockdesign 开发方法本质上还是基于 HDL 语言(例如 Verilog HDL)的,例如我们刚刚搭好的这个 blockdesign 实际上就是 Vivado 帮我们封装好的一个大型的 Verilog 模块 (module) ,我们需要把它生成为实际的 Verilog module ,然后才能调用它实现最终的部署。

我们右键 Sources 中的 block design (也就是最开始被我们命名为 xdma_bram 的这个 Blockdesign),点击 “Generate HDL Wrapper” ,如下图
在这里插入图片描述
然后它就会生成一个名为 xdma_bram_wrapper 的 Verilog 源文件。双击这个文件可以看到它的代码,我们发现它的模块输入输出接口就是我们之前引出到 blockdesign 的外部的那些信号(也即 PCIe 时钟、复位、信号),如下:
在这里插入图片描述
注意到在这里,PCIe 的参考驱动时钟 是单端的,而 FPGA 引脚上收到的 PCIe 参考时钟实际上是差分的。因此,这里还需要一个单端转差分的 clock buffer 。另外,还需要对复位信号 进行 IO buffer 。这一步将在以下 Verilog 顶层模块中实现。sys_clk_0sys_rst_n_0

所以,"单端转差分"的操作将在 FPGA 的顶层模块中实现,通常使用专门的时钟缓冲器(clock buffer)来完成这一转换。这个时钟缓冲器接收单端的 REFCLK 信号,并在 FPGA 内部生成差分时钟信号,以供 PCIe 接口使用。

差分信号 PCIE_TX0_P 与PCIE_TX0_N有什么区别?

在 PCIe(Peripheral Component Interconnect Express)中,TX0_P 和 TX0_N 表示差分信号对的一部分,通常用于传输数据。这两个信号通常用于差分传输,其中 TX0_P 是正向传输线,而 TX0_N 是其相应的负向传输线。它们一起传输数据信号,利用其之间的差分电压来提高抗干扰能力和信号完整性。
TX0_P 和 TX0_N 之间的差分传输通常遵循差分信号传输的原则,即当 TX0_P 信号的电压上升时,TX0_N 信号的电压下降,反之亦然。这种差分传输方式有助于减小传输线路上的串扰和噪声影响,提高了数据传输的可靠性和稳定性

AXI协议通道的理解
主要AXI分5个通道 主要三个通道是写数据(数据是从AXI-master流向AXI-slave)
在这里插入图片描述
写地址 (AXI Write Address Channel, 简称 AW) :AXI-master 告诉 AXI-slave 要写的首地址、长度、ID 等信息
写数据 (AXI Write Data Channel, 简称 W) :AXI-master 向 AXI-slave 传送数据
写响应 (AXI Write Response Channl, 简称 B) : 在收到数据后, AXI-slave 向 AXI-master 响应
以下 2 个通道用来读数据 (数据从 AXI-slave 流向 AXI-master):

读地址 (AXI Read Address Channel, 简称 AR) :AXI-master 告诉 AXI-slave 要读的首地址、长度、ID 等信息
读数据 (AXI Read Data Channel, 简称 R) :AXI-slave 向 AXI-master 传送数据
AXI 进行的是 burst 操作,也即指定一个读/写地址和长度 len ,然后以这个地址为起始地址,传送 len 字节的数据。

下面我们分析 AXI 读和写的时序,讲解 axi_bram.sv 中的 AXI-slave 的状态机的编写思路。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值