7系列 之 IO_FIFO

背景

《ug471_7Series_SelectIO.pdf》介绍了Xilinx 7 系列 SelectIO 的输入/输出特性及逻辑资源的相关内容。

第 1 章《SelectIO Resources》介绍了输出驱动器和输入接收器的电气特性,并通过大量实例解析了各类标准接口的实现。
第 2 章《SelectIO Logic Resources》介绍了输入输出数据寄存器及其双倍数据速率(DDR)操作,以及可编程输入延(IDELAY)和可编程输出延迟(ODELAY)。
第 3 章《Advanced SelectIO Logic Resources》介绍了ISERDESE2 、OSERDESE2与IO_FIFO。

了解了这个手册充分介绍的SelectIO架构和资源,以及所支持的电平标准。就可以利用相应的架构和资源实现与不同电平标准、通信速率间的外设建立起联系。


系列目录与传送门

说明1:本系列基于文档文档《ug471_7Series_SelectIO.pdf》而写,翻译和感悟,会出现中英文混合的情况。

说明2:虽然文中会出现一些原文的部分截图,非常支持并推荐大家去看原汁原味的官方文档

说明3:在查阅相关资料过程中,发现一些关于相关知识点的介绍零零散散,本系列会对其进行整合,力求详尽。

说明4:本博客是笔者用来记录学习过程的一个形式,并非专业论文。因此,在本博客中不会太注重图文格式的规范。

说明5:如果文章有误,欢迎诸位道友指出、讨论,笔者也会积极改正,希望大家一起进步!



1、IO_FIFO 总述

7 series devices have shallow IN_FIFOs and OUT_FIFOs (called IO_FIFOs collectively) located in each of the I/O banks. Although these IO_FIFOs are specifically designed for memory applications, they are available as general resources. For general use, all inputs and outputs are routed via interconnect. The most common use of IO_FIFOs is to interface with external components as an extension of IOLOGIC (e.g., ISERDES or IDDR and OSERDES or ODDR). Because of their general interconnect capability, IO_FIFOs can also serve as additional fabric FIFO resources.

每个 I/O bank 包含四个 IO_FIFO,每个字节组(byte group)一个。一个字节组(byte group)被定义为 bank 内的 12 个 I/O的集合。 IO_FIFO在物理布局上与I/O字节组对齐,当用于连接I/O SERDES等IOI组件时,这种对齐方式能实现最优性能,而这是其最常用的场景。此外,无论位置如何,IO_FIFO 都可以与 FPGA 内部结构和其他 I/O bank 中的资源交互。

对于输入FPGA的外部数据,IN_FIFO可连接至ILOGIC(如ISERDESE2、IDDR或IBUF)接收数据并传递至架构内部;对于输出数据,OUT_FIFO可连接至OLOGIC(如OSERDESE2、ODDR或OBUF),将数据从内部结构传递到 IOB。

IN_FIFO从ILOGIC块接收4位数据,而内部结构侧读取 4 位或 8 位数据。OUT_FIFO从内部结构接收4位或8位数据,OLOGIC块则以4位数据形式读取。

每个IO_FIFO包含768位存储阵列,可配置为12组4位数据或10组8位数据。
IO_FIFO深度为9级,包含输入/输出寄存器。IO_FIFO 的典型应用包括:用作跨越两个时钟域的并行 I/O 接口的缓冲器(例如,BUFR 域 和 BUFG域之间、BUFR域和BUFH域之间),或用作 2:1 串并/并串转换器,以将 PHY 与内部结构分离,从而降低对内部结构性能的要求。

IO_FIFO 是常规 FIFO 的浅层版本,功能类似。IO_FIFO 的主要用途是支持 I/O 数据传输功能,并非用于替代内置 FIFO 或基于 LUT 的 FIFO。IO_FIFO 支持标准标志逻辑、时钟和控制信号,可工作于两种模式:4x4模式(1:1)或 4x8/8x4模式(1:2/2:1)。

在这里插入图片描述

2 ··· IN_FIFO

2.1 ··· IN_FIFO

IN_FIFO 在物理上与 I/O 字节组对齐,以优化性能。该IN_FIFO 深度为8级,支持以下两种操作模式下的数据传输:

  • 4x4 模式

该模式下,FIFO配置为12组4-bit数据输入端口(D)与12组4-bit数据输出端口(Q)。

输入端口D0[3:0] –D9[3:0]分别映射至输出端口Q0[3:0]–Q9[3:0]。

额外输入端口D10[3:0]和D11[3:0]通过D5[7:4]和D6[7:4]实现,并映射至Q5[7:4]和Q6[7:4]对应的额外输出端口Q10[3:0]和Q11[3:0]。其余Qn[7:4]端口未使用。

具体映射关系详见技术手册表3-13。
在这里插入图片描述
在这里插入图片描述

  • 4x8 模式

该模式下FIFO配置为10组4-bit数据输入端口(D)与10组84-bit数据输出端口(Q)。通过解复用4位输入数据形成8位输出数据。当输出时钟频率超过输入时钟频率一半时,且此时输出数据宽度为输入数据的两倍。具体映射关系详见技术手册表3-14。
在这里插入图片描述

  • 两种模式都支持 FULL, EMPTY, ALMOSTFULL, 和ALMOSTEMPTY 标志位。

2.2 ··· IN_FIFO 原语

在这里插入图片描述

2.3 ··· IN_FIFO 原语例化

// IN_FIFO: Input First-In, First-Out (FIFO)
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
IN_FIFO #(
.ALMOST_EMPTY_VALUE(1), // Almost empty offset (1-2)
.ALMOST_FULL_VALUE(1), // Almost full offset (1-2)
.ARRAY_MODE("ARRAY_MODE_4_X_8"), // ARRAY_MODE_4_X_8, ARRAY_MODE_4_X_4
.SYNCHRONOUS_MODE("FALSE") // Clock synchronous (FALSE)
)
IN_FIFO_inst (
// FIFO Status Flags: 1-bit (each) output: Flags and other FIFO status outputs
.ALMOSTEMPTY(ALMOSTEMPTY), // 1-bit output: Almost empty
.ALMOSTFULL(ALMOSTFULL), // 1-bit output: Alomst full
.EMPTY(EMPTY), // 1-bit output: Empty
.FULL(FULL), // 1-bit output: Full
// Q0-Q9: 8-bit (each) output: FIFO Outputs
.Q0(Q0), // 8-bit output: Channel 0
.Q1(Q1), // 8-bit output: Channel 1
.Q2(Q2), // 8-bit output: Channel 2
.Q3(Q3), // 8-bit output: Channel 3
.Q4(Q4), // 8-bit output: Channel 4
.Q5(Q5), // 8-bit output: Channel 5
.Q6(Q6), // 8-bit output: Channel 6
.Q7(Q7), // 8-bit output: Channel 7
.Q8(Q8), // 8-bit output: Channel 8
.Q9(Q9), // 8-bit output: Channel 9
// D0-D9: 4-bit (each) input: FIFO inputs
.D0(D0), // 4-bit input: Channel 0
.D1(D1), // 4-bit input: Channel 1
.D2(D2), // 4-bit input: Channel 2
.D3(D3), // 4-bit input: Channel 3
.D4(D4), // 4-bit input: Channel 4
.D5(D5), // 8-bit input: Channel 5
.D6(D6), // 8-bit input: Channel 6
.D7(D7), // 4-bit input: Channel 7
.D8(D8), // 4-bit input: Channel 8
.D9(D9), // 4-bit input: Channel 9
// FIFO Control Signals: 1-bit (each) input: Clocks, Resets and Enables
.RDCLK(RDCLK), // 1-bit input: Read clock
.RDEN(RDEN), // 1-bit input: Read enable
.RESET(RESET), // 1-bit input: Reset
.WRCLK(WRCLK), // 1-bit input: Write clock
.WREN(WREN) // 1-bit input: Write enable
);
// End of IN_FIFO_inst instantiation

3 ··· OUT_FIFO

OUT_FIFO与IN_FIFO共置于同一I/O组内,其物理布局同样与I/O字节组对齐以实现优化性能。该FIFO深度为8级,支持以下两种操作模式的数据传输:

  • 4x4模式

此模式下FIFO配置为12组4-bit数据输入端口(D)与12组4-bit数据输出端口(Q)。输入端口D0[3:0]–D9[3:0]依次映射至输出端口Q0[3:0]–Q9[3:0]。额外输入端口D10[3:0]和D11[3:0]复用D5[7:4]与D6[7:4]信号线,并映射至Q5[7:4]和Q6[7:4]对应的输出端口Q10[3:0]和Q11[3:0]。其余D[7:4]端口未启用。

在这里插入图片描述

  • 8x4模式

此模式下FIFO配置为10组8-bit数据输入端口(D)与10组4-bit数据输出端口(Q)。输出路径中的2:1复用器将8位输入数据串行化为4位输出。此模式适用于输出时钟频率是输入时钟频率两倍的场景,此时输出数据宽度减半。
在这里插入图片描述

  • 两种模式都支持 FULL, EMPTY, ALMOSTFULL, 和ALMOSTEMPTY 标志位。

3.2 ··· OUT_FIFO 原语

在这里插入图片描述

3.3 ··· IN_FIFO 原语例化

// OUT_FIFO: Output First-In, First-Out (FIFO) Buffer
// 7 Series
// Xilinx HDL Libraries Guide, version 13.4
OUT_FIFO #(
	.ALMOST_EMPTY_VALUE(1), // Almost empty offset (1-2)
	.ALMOST_FULL_VALUE(1), // Almost full offset (1-2)
	.ARRAY_MODE("ARRAY_MODE_8_X_4"), // ARRAY_MODE_8_X_4, ARRAY_MODE_4_X_4
	.OUTPUT_DISABLE("FALSE"), // Disable output (FALSE, TRUE)
	.SYNCHRONOUS_MODE("FALSE") // Must always be set to false.
)OUT_FIFO_inst (
	// FIFO Status Flags: 1-bit (each) output: Flags and other FIFO status outputs
	.ALMOSTEMPTY(ALMOSTEMPTY), // 1-bit output: Almost empty flag
	.ALMOSTFULL(ALMOSTFULL), // 1-bit output: Alomst full flag
	.EMPTY(EMPTY), // 1-bit output: Empty flag
	.FULL(FULL), // 1-bit output: Full flag
	// Q0-Q9: 4-bit (each) output: FIFO Outputs
	.Q0(Q0), // 4-bit output: Channel 0 output bus
	.Q1(Q1), // 4-bit output: Channel 1 output bus
	.Q2(Q2), // 4-bit output: Channel 2 output bus
	.Q3(Q3), // 4-bit output: Channel 3 output bus
	.Q4(Q4), // 4-bit output: Channel 4 output bus
	.Q5(Q5), // 8-bit output: Channel 5 output bus
	.Q6(Q6), // 8-bit output: Channel 6 output bus
	.Q7(Q7), // 4-bit output: Channel 7 output bus
	.Q8(Q8), // 4-bit output: Channel 8 output bus
	.Q9(Q9), // 4-bit output: Channel 9 output bus
	// D0-D9: 8-bit (each) input: FIFO inputs
	.D0(D0), // 8-bit input: Channel 0 input bus
	.D1(D1), // 8-bit input: Channel 1 input bus
	.D2(D2), // 8-bit input: Channel 2 input bus
	.D3(D3), // 8-bit input: Channel 3 input bus
	.D4(D4), // 8-bit input: Channel 4 input bus
	.D5(D5), // 8-bit input: Channel 5 input bus
	.D6(D6), // 8-bit input: Channel 6 input bus
	.D7(D7), // 8-bit input: Channel 7 input bus
	.D8(D8), // 8-bit input: Channel 8 input bus
	.D9(D9), // 8-bit input: Channel 9 input bus
	// FIFO Control Signals: 1-bit (each) input: Clocks, Resets and Enables
	.RDCLK(RDCLK), // 1-bit input: Read clock
	.RDEN(RDEN), // 1-bit input: Read enable
	.RESET(RESET), // 1-bit input: Active high reset
	.WRCLK(WRCLK), // 1-bit input: Write clock
	.WREN(WREN) // 1-bit input: Write enable
);
// End of OUT_FIFO_inst instantiation

4 ··· IO_FIFO复位

IO_FIFO 具有一个单一的异步复位信号,该信号在读和写时钟域内内部重新同步。为了确保正确复位,在向 IO_FIFO 写入数据之前,必须将 RESET 信号保持高电平至少四个周期,无论是 RDCLK 还是 WRCLK,以较慢的那个为准。在断言 RESET 时,必须将 RDEN 和 WREN 保持为低电平。

应将 IO_FIFO 保持在复位状态,直到写和读时钟都存在且稳定。同样,如果读或写时钟在配置后才可用,则在有效的时钟被断言后,必须按照上述方法复位 IO_FIFO。

5、EMPTY 和 FULL 标志

当 FULL 标志被置高时,表示 FIFO core 和 输入寄存器 都已满。输出寄存器的状态被忽略。

EMPTY 标志标示着输出寄存器中数据的状态。当 EMPTY 标志被置高时,输出寄存器中的数据无效。

6、ALMOST EMPTY 和 ALMOST FULL 标志

ALMOSTEMPTY 和 ALMOSTFULL 标志提供了 IO_FIFO 接近其容量限制的预警标志。这些标志可以配置为在 IO_FIFO 达到满或空状态前一或两个时钟周期触发。

阈值=1:输出寄存器仅剩1个有效数据字可读
阈值=2:输出寄存器剩余2个有效数据字可读

由于 IO_FIFO 的异步特性和内部同步机制,这些标志可能会过于保守。读操作时,输出寄存器可能包含多于阈值指示的有效数据。写操作时,输入寄存器可能具备超过阈值指示的剩余容量。

ALMOST FULL/EMPTY标志与FULL/EMPTY标志不存在必然时序关联。如果 WRCLK 的速度比 RDCLK 快两倍以上,可能会在 EMPTY 断言之前出现 ALMOSTEMPTY 断言和去断言的情况。

在这里插入图片描述

7、参考文献

1、《ug471_7Series_SelectIO.pdf》

STM32H7系列微控制器的SPI模块支持FIFO(先入先出队列),这使得批量传输数据时更高效,并减少了CPU的负担。当配置好FIFO并启用对应的中断后,可以在接收或发送完成一定量的数据时触发相应的处理函数。 下面是一个简单的例子展示如何通过HAL库编写基于FIFO模式下的SPI通信的中断服务程序: ```c #include "stm32h7xx_hal.h" // 假设已经初始化了SPI句柄 hspi1 uint8_t aTxBuffer[] = {0x01, 0x02, 0x03}; // 发送缓冲区 volatile uint8_t *pTxBuffPtr; volatile uint16_t TxXferCount; void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) { if (hspi->Instance == SPI1) { /* 配置完成后回调 */ printf("Transmit complete\n"); } } int main(void){ pTxBuffPtr = &aTxBuffer[0]; // 指向起始地址 TxXferCount = sizeof(aTxBuffer); __HAL_RCC_SPI1_CLK_ENABLE(); hspi1.Instance = SPI1; hspi1.Init.Mode = SPI_MODE_MASTER; hspi1.Init.Direction = SPI_DIRECTION_2LINES; hspi1.Init.DataSize = SPI_DATASIZE_8BIT; hspi1.Init.CLKPolarity = SPI_POLARITY_LOW; hspi1.Init.CLKPhase = SPI_PHASE_1EDGE; hspi1.Init.NSS = SPI_NSS_SOFT; hspi1.Init.BaudRatePrescaler= SPI_BAUDRATEPRESCALER_4; hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB; hspi1.Init.TIMode = SPI_TIMODE_DISABLE; hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; hspi1.Init.CRCPolynomial = 10; if(HAL_OK != HAL_SPI_Init(&hspi1)) Error_Handler(); // 开启DMA FIFO模式 hspi1.hdmatx = hdma_spi1_tx; __HAL_LINKDMA(&hspi1,hdmatx,hdma_spi1_tx); // 设置 FifoThreshold 和 CR2 中的相关位使能TXEIE/FREE MODIFY_REG(hspi1.Instance->CR2, SPI_CR2_DS | SPI_CR2_FRXTH | SPI_CR2_TXEIE | SPI_CR2_RXNEIE , ((uint8_t)(SPI_FIFO_THRESHOLD_01DATA << SPI_CR2_FRXTH_Pos)) | SPI_CR2_TXEIE); // 使用Fifo模式开始非阻塞式传送 while(TxXferCount--) (*(__IO uint8_t *) &(hspi1.Instance->DR) = *(pTxBuffPtr++)); // 启动中断机制等待结束事件 HAL_NVIC_SetPriority(SPI1_IRQn,5, 0); HAL_NVIC_EnableIRQ(SPI1_IRQn); } ``` 请注意上述代码只是演示用途,在实际应用中你需要根据具体的硬件连接情况调整引脚设置和其他初始化参数;同时还需要保证`aTxBuffer`内的数据已经被正确填充并且其长度适配于你要发送的信息大小。 此外,如果你想要利用更多的高级特性如DMA等,则需要进一步研究相关的API文档以及参考手册。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值