FPGA教程系列-流水线中的一些概念
什么是反压与气泡?
这两个概念是流水线(Pipeline)设计和 AXI-Stream 协议中最核心的术语。。
1. 什么是反压 (Backpressure)?
一句话解释:下游忙不过来了,告诉上游"慢点,别发了"。
想象一个快递打包流水线:
- 上游(Source) :负责把物品放到传送带上。
- 下游(Sink) :负责把传送带上的物品装进箱子。
反压的场景:
如果下游装箱的工人动作慢了,或者箱子用完了,他面前的传送带就会堆满物品。这时,他必须按下"红灯"按钮,告诉上游:"停!我这里堵住了!"。
上游看到红灯,就必须停止放东西,否则物品就会掉到地上(数据丢失/溢出)。
在 AXI-Stream 信号中:Ready 信号 就是这个"红灯/绿灯"。当 m_axis_tready = 0 (拉低)时,就是反压。这意味着下游模块正在说:"我忙,现在处理不了数据"。
2. 什么是气泡 (Bubble)?
一句话解释:本来能传数据的时候,因为反应慢或设计缺陷,导致传送带空了一格。
继续看那个流水线:
- 下游刚才堵住了(反压),上游停了。
- 突然,下游工人搞定了,按下了"绿灯"(Ready 拉高),喊道:"可以了,继续!"。
气泡的场景:
如果上游工人的反应慢了一拍:他看到绿灯亮了,先发愣了 1 秒,然后才把物品放到传送带上。
那么,传送带上就会出现一段空白。这个空白传到下游,下游工人就得干等 1 秒。
这个空白的无效周期 ,就是气泡。
在 AXI-Stream 信号中: 上游有数据想发,下游也准备好收了(Ready=1)。但是因为寄存器逻辑设计的延迟(Latency),导致 tvalid 在中间莫名其妙变低了 1 个周期。这个周期没有传数据,带宽就被浪费了。
延迟与吞吐率
1. 延迟 (Latency):这一趟要跑多久?
定义:一个数据包从进入系统(起点)到离开系统(终点)所花费的时间。
单位:时间单位(秒、毫秒、纳秒)或时钟周期数(Cycles)。
核心关注点:快慢(Speed)。
🚗 高速公路比喻:
假设要从北京开车去天津。
- 延迟 就是:车从北京收费站开进,到从天津收费站开出,一共花了 1 小时。
- 如果你把车速飙得很快,或者路很直,时间变成了 0.8 小时,那就是低延迟(好)。
- 如果在路上遇到检查站(寄存器),停车检查了 5 分钟,总时间变成 1.1 小时,那就是延迟增加(变慢)。
2. 吞吐率 (Throughput):这一会儿能过多少?
定义:单位时间内,系统能够处理的数据总量。
单位:MB/s, Gbps, PPS (Packets Per Second)。
核心关注点:容量(Capacity)/ 流量(Flow)。
🚗 高速公路比喻:
还是那条高速公路。
- 吞吐率 就是:天津收费站每小时能放行多少辆车?
- 比如:10,000 辆车/小时。
- 哪怕每辆车在路上都要开很久(高延迟),只要路足够宽(位宽大)、车速足够快(频率高)、车间距足够小(无气泡),每小时出来的车就可以非常多。
3. 它们的关系:FPGA 中的经典权衡
场景 A:不做流水线(直连)
- 路况:一条窄路,不限速,但路太长,司机不敢开太快,怕反应不过来(时序不收敛)。
- 时钟频率:100 MHz(车速 100 km/h)。
- 延迟 :1 个周期(10ns)。------ 单个数据极快到达。
- 吞吐率:100 M个数据/秒。
场景 B:做流水线(加寄存器)
-
路况:把长路切成两段短路,中间加个收费站(寄存器)。因为路短了,司机敢把车速飙到极高。
-
时钟频率:300 MHz(车速 300 km/h)。
-
延迟:2 个周期(收费站耽误了一拍)。
- 物理时间:2 × 3.3ns = 6.6ns。(虽然周期数多了,但其实物理上并没有慢多少,甚至更快了)。
-
吞吐率 :300 M个数据/秒。------ 也就是以前的 3 倍!
4. 这里的"延后"和"气泡"的区别
你可能担心:延后了一个周期,是不是等于有一个气泡?
- 气泡 (Bubble) :是指流水线中间断流了,有一个周期谁都没传数据,带宽由 100% 掉到了 0%。这是纯粹的浪费。
- 延后 (Latency) :是指流水线满了,只是整体平移了一格。
视觉对比:
假设输入是 1, 2, 3, 4, 5...
有气泡 (Type 1 Bad Case):
Cycle 1: Out = 1
Cycle 2: Out = (空) <-- 浪费
Cycle 3: Out = 2
Cycle 4: Out = 3
有延后但无气泡 (Type 2):
Cycle 1: Out = (空,因为还没流过来) <-- 仅初始等待一次
Cycle 2: Out = 1
Cycle 3: Out = 2
Cycle 4: Out = 3
Cycle 5: Out = 4
一旦流水线填满(Pipeline Priming),REG_TYPE=2 就能保证每个周期都有数据输出,带宽是 100% 的。