FPGA中级项目2——硬核 or 软核与FIFO的配置
在上一个项目中提到关于IP核 ROM与RAM 的配置,需要指出的是:我们配置为分布式时是软核(即只需要占用小型的存贮资源),而配置BRAM为硬核(占用较大的资源)
那问题来了:硬核不是在FPGA芯片制造时已经固定好的吗?怎么还能对其配置呢?
这就要区分硬核的 “固定性” 与 “可配置性”
硬核的物理结构固定:硬核是芯片制造时已固化的物理电路模块(如 BRAM、DSP 单元等),其内部逻辑和晶体管布局无法被用户修改。
但是,配置≠修改硬件结构:用户通过工具(如 Vivado)对硬核进行的 “配置”,本质是选择硬核的使用方式,而非改变其物理结构。
例如:
BRAM 的配置:设置数据宽度、深度、读写模式等参数,但 BRAM 的存储单元数量和基本架构不变。
硬核 IP 核:如 PCIe 硬核,用户可配置接口速率、地址空间等,但底层物理层协议已固化
新的问题来了:怎么知道自己配置的是软核还是硬核?
配置为软核的情况
1. 基于可编程逻辑资源实现
原理:当使用 Vivado 配置 ROM 和 RAM 时,如果没有使用 FPGA 内部特定的硬核存储资源,而是利用可编程逻辑资源(如查找表 LUT 和触发器)来实现存储功能,那么它们就是软核。
特点
高度可配置:用户可以根据需求灵活调整存储容量、数据宽度等参数。例如,可以轻松改变 ROM 的初始化数据内容,或者调整 RAM 的读写端口数量和读写模式。
资源灵活分配:在不同的 FPGA 器件上,只要有足够的可编程逻辑资源,就可以实现相应的 ROM 和 RAM 功能,并且可以根据资源情况进行合理的布局布线。
可移植性强:由于是基于硬件描述语言实现的逻辑结构,所以可以在不同工艺和型号的 FPGA 之间进行移植,只需对部分参数进行适当调整。
2. 使用分布式 RAM 实现
原理:分布式 RAM 是利用 FPGA 中的查找表(LUT)来实现的一种存储方式。在 Vivado 中配置时,用户可以选择使用分布式 RAM 来构建较小容量的 RAM。
特点
软核特性明显:它本质上是由可编程逻辑资源构成,配置过程中可以根据需求进行定制,例如选择不同的寻址方式和数据宽度。
适合小规模存储:由于 LUT 资源相对有限,分布式 RAM 通常适用于存储容量较小的场景,如存储一些常量数据或小规模的临时数据。
可能配置为硬核的情况
1. 使用块 RAM(BRAM)硬核资源
原理:大多数 FPGA 芯片都集成了块 RAM 硬核,这是一种预先设计好的、高性能的存储模块。在 Vivado 配置 ROM 或 RAM 时,如果选择使用块 RAM 资源,就相当于使用了 FPGA 的硬核。
特点
高性能:块 RAM 具有较高的读写速度和带宽,能够满足对存储性能要求较高的应用场景,如高速数据缓存。
资源固定性:块 RAM 的结构和功能是固定的,虽然在配置时可以对一些参数(如数据宽度、深度)进行调整,但基本的存储结构是由芯片制造商预先设计好的,用户无法对其内部结构进行修改。
资源限制:使用块 RAM 时会受到芯片中块 RAM 资源数量和大小的限制,如果需求超过了芯片提供的块 RAM 资源,就需要采用其他方式(如分布式 RAM)进行补充。
硬核与软核的配置差异
今天我们所要配置的即为软核IP之一-----FIFO
FIFO 是一种逻辑功能,可通过用户编程实现,而非 FPGA 芯片上的预定义固定模块。虽然 FIFO 本身不固定,但部分 FPGA 的 BRAM、时钟管理单元(CMU)等固定硬件可辅助优化 FIFO 性能
FIFO简介
在 FPGA(现场可编程门阵列)中,FIFO(First-In-First-Out,先进先出队列)是一种常用的时序逻辑模块,主要用于数据缓冲、跨时钟域数据传输或速率匹配。
1. FIFO 的基本功能
数据缓冲:临时存储数据,缓解不同模块之间的数据速率差异。
跨时钟域处理:允许数据在不同时钟域的模块间安全传输,避免亚稳态问题。
突发数据管理:应对突发数据的输入或输出,确保系统稳定性
2. FIFO 的核心结构
存储单元:由 RAM 或寄存器组成,用于存储数据。
读写指针:跟踪数据写入和读取的位置(通常使用计数器或移位寄存器实现)。
控制逻辑:
空 / 满状态:指示 FIFO 是否为空或满,防止下溢(读空)或溢出(写满)。
读写使能:控制数据的写入和读取操作。
状态信号:如剩余空间、当前存储量等。
3. FIFO 的关键参数
数据宽度:单次读写的数据位数(如 32 位、64 位)。
深度:可存储的数据单元数量(如 1024 字)。
读写速率:受时钟频率和逻辑延迟限制。
延迟:数据从写入到读出的周期数(通常为固定值)。
4. FIFO 的应用场景
跨时钟域通信:如 AXI 接口与本地时钟模块之间的数据交互。
数据速率匹配:例如高速 ADC 与低速处理器之间的数据缓冲。
突发数据处理:存储突发传输的数据,避免丢包。
流水线设计:在多级流水线中缓冲中间结果。
问题分析
1. 首先在对FIFO配置时,要明确其特点。其一:先入先出;其二:有写入侧和读出侧位宽可能不同的要求。下图为对FIFO基础页面的配置,其中fifo implementation 是FIFO的实现方式,可以选择时钟与输入输出端口的不同来进行配置。
2. 这里来假设设置写入与读出的位宽不一样的情况。read mode 设置为FWFT(First Word Fall-Through)模式,也称为 “首字直通” 模式。在传统的 FIFO 模式下,当发出读使能信号后,数据需要一个时钟周期才能从 FIFO 输出。而在 FWFT 模式下,FIFO 的输出端会始终呈现 FIFO 中第一个数据(即即将被读出的数据),一旦读使能信号有效,这个数据会立即被输出,无需额外的时钟周期等待,实现了数据的 “直通” 输出。
3. 在以下的状态标志页面中,有optional flags 可配置为几乎全满和几乎全空模式。还有相应的握手选项(handshaking options)用来表示。在 FIFO(先进先出队列)中,overflow(溢出)和underflow(下溢)是两种关键的错误状态,分别对应数据写入和读取过程中的异常情况。可选择是否配置来标志信号。
overflow(溢出):当 FIFO 已被数据填满(即达到最大存储容量),但仍有新数据试图写入时,会发生溢出。此时新数据无法被存储,导致数据丢失。
underflow(下溢):当 FIFO 已为空(无数据可读取),但仍有读取操作被触发时,会发生下溢。此时读取到的数据可能是无效值或未定义数据。
4. 在数据计数端口进行配置时,有 more accurate data counts 选项可勾选。若勾选,wr_data_count 的位宽会多一位。该选项的主要作用是提供更精确的 FIFO 内数据数量的统计信息。在 FIFO 的常规操作中,需要知道当前 FIFO 中存储了多少数据,这对于控制数据的读写操作非常关键。例如,在决定是否继续写入数据(要避免溢出)或者是否还有数据可供读取(防止下溢)时,数据计数是重要的判断依据。开启 “more accurate data counts” 选项后,能让这个计数更加精准,减少因计数误差导致的读写异常。但是需根据 FIFO 深度、时钟域数量及资源限制决定是否启用此选项。若资源紧张且对精度要求不高,可关闭该选项以节省硬件成本。
5. 最后便是FIFO IP核配置的总结页面,可根据实际项目结合芯片手册选择性修改