3. 可编程逻辑单元(PFU):Slice结构、LUT4与LUT5的差异、进位链的工作原理

好,咱们今天聊聊ECP5里最核心的东西——可编程逻辑单元,也就是PFU。你想想看,整个FPGA就像一座城市,那PFU就是城市里的一栋栋楼房。你所有的逻辑功能,最后都得靠这些楼房里的房间来实现。

我个人习惯把PFU看作是FPGA的“肌肉”。它够不够强壮,直接决定了你的设计能跑多快、能塞多满。ECP5的PFU设计得挺巧妙,咱们一层层剥开来看。

3.1 Slice结构:PFU的基本单元

一个PFU里包含了四个Slice。这四个Slice不是完全一样的,它们分两种:SLICE_A和SLICE_B。我刚开始接触的时候也觉得奇怪,为什么要搞两种?后来做项目多了才明白,这是为了在面积和灵活性之间找个平衡。

每个Slice里都有这么几样东西:

  • 查找表(LUT):这是实现逻辑的核心。ECP5用的是4输入查找表,也就是LUT4。
  • 触发器(FF):用来寄存数据,每个Slice有两个。
  • 进位链(Carry Chain):专门为算术运算准备的快速通道。
  • 多路选择器(MUX):用来组合和选择信号。

SLICE_A和SLICE_B最大的区别在于:SLICE_A的LUT可以配置成5输入的模式,也就是LUT5。而SLICE_B只能老老实实做LUT4。嗯,这里要注意,不是所有Slice都能扩展,只有A型的才行。

核心要点:一个PFU = 2个SLICE_A + 2个SLICE_B。A型Slice支持LUT5扩展,B型不支持。这个差异在资源紧张的时候特别有用。

3.2 LUT4与LUT5的差异:多一个输入,多一片天地

咱们先说说LUT4。说白了,它就是一个4输入、1输出的函数发生器。你可以用真值表的方式,把任意一个4输入布尔函数写进去。比如一个4输入的与门,或者一个4输入的异或门,都能用一个LUT4搞定。

那LUT5呢?它比LUT4多了一个输入。你可能会问:多一个输入能干嘛?

我在项目中遇到过这样一个场景:需要实现一个5输入的地址译码器。如果用LUT4,得拆成两个LUT4再加一个MUX,不仅占资源,延迟还大。但ECP5的SLICE_A可以直接用一个LUT5搞定,又快又省。

具体怎么实现的?其实LUT5是通过把两个LUT4“拼”在一起得到的。SLICE_A里有两个LUT4,它们可以共享前4个输入,然后通过第5个输入来选择输出哪一个LUT4的结果。你想想看,这不就是一个2选1的多路选择器吗?

我的经验:在做地址译码、状态机跳转逻辑这种需要较多输入的场景,优先把关键路径放到SLICE_A里。我曾经因为没注意这个细节,导致一个5输入的逻辑被拆成两级LUT,时序直接崩了。后来换成LUT5,一拍就过。

咱们用个表格来对比一下:

特性 LUT4 LUT5
输入数量 4 5
实现方式 单个LUT4 两个LUT4 + MUX
支持的Slice SLICE_A 和 SLICE_B 仅 SLICE_A
延迟 较低 略高(多一级MUX)
典型应用 通用逻辑、小规模译码 地址译码、多输入函数

3.3 进位链(Carry Chain)的工作原理

进位链这东西,做算术逻辑的时候绕不开。你想想看,如果不用进位链,光靠LUT搭一个加法器,那延迟会大到没法看。为什么?因为进位信号要从一个LUT传到下一个LUT,走的是通用布线资源,绕来绕去,延迟就上去了。

ECP5的进位链是专用的硬件路径。它就在Slice内部,把相邻的Slice串起来。进位信号从低位Slice直接传到高位Slice,走的是一条“高速公路”,不是普通马路。

具体怎么工作的?我画个图你就明白了。

ECP5 进位链(Carry Chain)工作原理 进位信号传播方向 Slice 0(低位) A0 + B0 + Cin → S0, Cout0 Slice 1 A1 + B1 + Cout0 → S1, Cout1 Slice 2(高位) A2 + B2 + Cout1 → S2, Cout2 关键特性 • 专用硬件路径,不走通用布线 • 每个Slice内完成: 求和 + 进位生成 • 延迟极低(约0.3ns/级) • 支持加法、减法、比较器 • 可级联多个PFU形成 更宽的进位链 Cin Cout

你看这个图,进位信号从Slice 0的Cin进来,经过Slice内部的快速逻辑,生成Cout,然后直接送到Slice 1的进位输入。整个过程不需要经过任何通用布线资源。这就是为什么ECP5做加法器能跑到几百兆赫兹的原因。

每个Slice里的进位链逻辑其实很简单,就两个功能:

  1. 求和:用LUT4实现A XOR B XOR Cin,得到当前位的和S。
  2. 进位生成:用专门的进位逻辑实现 (A AND B) OR (A AND Cin) OR (B AND Cin),得到进位输出Cout。

避坑指南:我曾经在一个项目中,用进位链做32位加法器。综合后时序报告显示进位链路径有0.5ns的余量,我觉得稳了。结果布局布线后,余量变成了负的。查了半天才发现,是因为我把加法器放在了PFU的边界上,进位链被截断了,走了通用布线。后来手动把加法器约束到连续的PFU里,问题就解决了。

所以我的建议是:如果你要用进位链做宽位算术运算,一定要确保所有Slice在物理上是连续的。工具一般会自动处理,但有时候它也会犯糊涂,尤其是当你的设计里有很多其他逻辑干扰的时候。

嗯,关于PFU的Slice结构、LUT4与LUT5的差异、以及进位链的工作原理,咱们就聊到这儿。这些东西看着简单,但用好了,你的设计就能又快又省资源。下一节咱们聊聊ECP5的存储资源,那又是另一番天地了。

小技巧:在Diamond或Radiant软件里,打开Floorplan Viewer,可以直观地看到进位链的物理布局。如果发现进位链被“打断”了,赶紧调整约束或者重写代码。

专注资料整理