Veloris.
返回索引
深入原理 2026-02-19

CLB 深度解析:LUT、MUX 与 Carry Chain 的协同之道

11 分钟
3.4k words

CLB 深度解析:LUT、MUX 与 Carry Chain 的协同之道

💡 上一篇文章我们了解了 FPGA 芯片的六级架构层次。现在让我们把”显微镜”对准最核心的那一层——CLB。

你写的每一行 Verilog 代码,无论是 assign y = a & b,还是 c = a + b,最终都会变成 CLB 内部的 LUT 查表、MUX 选路、Carry Chain 传进位。理解 CLB 内部这三个组件如何分工协作,是写出高效 FPGA 代码的底层功夫。

这篇文章会带你深入 Xilinx 7 系列 CLB 的内部结构,用 Verilog 代码 + Vivado 综合结果的方式,让你亲眼看到代码是如何变成硬件的。


目录


1. CLB 全景:两个 Slice 的世界

在 Xilinx 7 系列 FPGA 中,一个 CLB 包含 2 个 Slice,两个 Slice 之间没有直接连线,各自独立工作。CLB 在芯片中按列排列,这是 ASMBL 架构的特点。

每个 Slice 内部包含:

组件数量核心作用
LUT64 个实现任意 6 输入组合逻辑
MUX3 个扩展 LUT 的逻辑宽度
Carry Chain(CARRY4)1 条加速算术运算的进位传播
FF(触发器)8 个存储数据,实现时序逻辑

CLB 典型结构 而一个 Slice 中的结构如下: Slice 典型结构

这四种组件各司其职,又紧密配合。接下来我们逐一深入。


2. LUT:用查表代替计算的天才设计

2.1 LUT 的本质:一个 64-bit 的小型 ROM

LUT(Look-Up Table,查找表) 是 FPGA 实现组合逻辑的核心。它的工作原理出奇地简单:

  • 一个 6 输入 LUT 内部有 2⁶ = 64 个 SRAM 存储单元
  • 6 个输入信号作为地址线,选中其中一个存储单元
  • 被选中的存储单元中预存的值(0 或 1)就是 LUT 的输出

配置 FPGA 时,综合工具会把你的逻辑函数的真值表写入这 64 个 SRAM 单元。运行时,LUT 不做任何”计算”——它只是”查表”。

2.2 一个具体的例子

用 LUT 实现一个 6 输入与门 Y = A & B & C & D & E & F

assign out = a & b & c & d & e & f;

综合工具会把真值表写入 LUT:64 个存储单元中,只有地址 111111 对应的单元存 1,其余 63 个都存 0

在 Vivado 中综合后,你会看到它被映射成一个 LUT6,INIT 值为 64'h8000000000000000——正好是第 63 位(最高位)为 1。

LUT 的精妙之处:不管你实现什么 6 输入逻辑函数——与门、或门、异或门、还是任意复杂的布尔表达式——消耗的资源和延迟都完全相同。因为它不是”计算”结果,而是”查表”。

2.3 LUT6 的内部结构:两个 LUT5 + 一个 MUX

一个 LUT6 实际上由两个独立的 LUT5 和一个 2:1 MUX 组成:

  • 两个 LUT5 共享 A1~A5 五个输入
  • A6 作为 MUX 的选择信号
  • 当作 LUT6 使用时:A6 选择哪个 LUT5 的结果输出到 O6
  • 当作两个 LUT5 使用时:A6 固定为 1,两个 LUT5 分别从 O5 和 O6 输出

这种**可分形(Fracturable)**设计非常聪明——如果你的设计中有两个 5 输入的逻辑函数恰好共享相同的输入,综合工具可以把它们塞进同一个 LUT6,提高资源利用率。

2.4 LUT 的代价:面积换灵活性

LUT 的灵活性是有代价的。实现一个 6 输入与门:

  • 用逻辑门:5 个与门 × 6 个 MOS 管 = 30 个晶体管
  • 用 LUT6:64 个 SRAM 单元 × 6 个晶体管 = 384+ 个晶体管(还不算译码电路)

FPGA 的通用性,本质上是用面积换来的。这也是为什么同等功能下,FPGA 的功耗和面积都大于 ASIC。

💬 你可能会问:如果我的逻辑超过 6 个输入怎么办?

综合工具会自动用多个 LUT 级联来实现。比如一个 8 输入的比较器需要 2~3 个 LUT 级联完成。级联越多,逻辑级数越深,延迟越大——这就是为什么 FPGA 设计要关注”逻辑级数”,必要时用流水线寄存器切割长组合逻辑路径。


3. MUX:LUT 的得力助手

3.1 Slice 中的三个专用 MUX

每个 Slice 包含 3 个专用 MUX:

MUX输入来源输出去向实现的功能
F7AMUXLUT-A 和 LUT-B 的 O6 输出F8MUX 或直接输出7 输入逻辑 / 8:1 MUX
F7BMUXLUT-C 和 LUT-D 的 O6 输出F8MUX 或直接输出7 输入逻辑 / 8:1 MUX
F8MUXF7AMUX 和 F7BMUX 的输出直接输出8 输入逻辑 / 16:1 MUX

这三个 MUX 的连接关系是固定的:F7MUX 只能接 LUT 的输出,F8MUX 只能接 F7MUX 的输出

3.2 从 4:1 到 16:1:MUX 的级联扩展

通过 LUT + 专用 MUX 的组合,一个 Slice 可以实现不同规模的多路选择器:

MUX 规模所需资源说明
4:1 MUX1 个 LUT64 数据 + 2 选择 = 6 输入,刚好一个 LUT
8:1 MUX2 个 LUT6 + 1 个 F7MUX每个 Slice 可以放 2 个
16:1 MUX4 个 LUT6 + 2 个 F7MUX + 1 个 F8MUX每个 Slice 只能放 1 个

3.3 为什么不全用 LUT 实现 MUX?

你可能会想:既然 LUT6 可以实现 2:1 MUX,为什么还需要专用 MUX?

两个关键原因:

  1. 资源效率:用 LUT6 实现 2:1 MUX,有 3 个输入被浪费了。专用 MUX 不占用 LUT 资源
  2. 布线质量:一个 Slice 只有 4 个 LUT6。如果用纯 LUT 实现 16:1 MUX,需要 5 个 LUT,第 5 个必须布线到其他 Slice,路径长度不一致容易产生毛刺。而 LUT + 专用 MUX 的组合全部在一个 Slice 内完成,布线长度基本一致

💡 工程师手记:我曾经在一个高频设计中遇到 MUX 路径的时序违例。分析后发现是一个 32:1 MUX 被综合成了多级 LUT 级联,跨越了多个 Slice。后来改用树形结构 + 流水线寄存器,把 MUX 拆成两级 8:1,每级都在一个 Slice 内完成,时序立刻收敛了。


4. Carry Chain:算术运算的高速公路

4.1 为什么需要专用进位链?

当你写 c = a + b 时,每一位的计算结果不仅取决于当前输入,还取决于低位传来的进位。

如果用通用 LUT 和布线来传递进位信号,32 位加法器的进位要穿过 32 级 LUT + 32 段通用布线,延迟会非常大。

Carry Chain 就是专门给进位信号开辟的”高速公路”——它在 Slice 内部提供了一条低延迟的专用通路,让进位信号可以快速地从一位传到下一位。

4.2 CARRY4 的结构

7 系列 FPGA 的每个 Slice 包含一个 CARRY4 单元,可以处理 4 位的进位传播。它包含:

组件数量作用
MUXCY4 个选择是传递进位还是使用本级生成的进位
XOR 门4 个计算每一位的”和”(Sum)

信号流向:

  • S0~S3(来自 LUT 的 O6 输出):进位链的”传播”信号
  • DI1~DI4(来自 LUT 的 O5 输出或旁路输入):进位链的”生成”信号
  • CIN:来自下方 Slice 的进位输入
  • CO0~CO3:每一位的进位输出,其中 CO3 连接到上方 Slice 的 CIN
  • O0~O3:每一位的求和结果

4.3 进位链的级联

一个 CARRY4 处理 4 位。对于更宽的运算:

  • 8 位加法器:需要 2 个 CARRY4(同一 CLB 内的 2 个 Slice)
  • 16 位加法器:需要 4 个 CARRY4(2 个 CLB)
  • 32 位加法器:需要 8 个 CARRY4(4 个 CLB)

进位链在 Slice 之间垂直级联——这也是为什么 CLB 采用列状排列的原因之一。

⚠️ 设计注意:进位链的传播延迟随位宽线性增长。如果你的加法器位宽很大(比如 64 位)且时钟频率很高,可能需要用流水线把加法拆成多级。另外,进位链不能跨越 SLR 边界

💡 工程师手记:我曾经在一个 200 MHz 的设计中用了一个 48 位的累加器,时序报告显示关键路径延迟超标 0.3 ns。分析后发现是 Carry Chain 太长——48 位需要 12 个 CARRY4 级联,跨越了 6 个 Slice。解决方案是把 48 位加法拆成两级流水线(低 24 位先加,高 24 位下一拍再加),时序立刻收敛。理解 Carry Chain 的物理结构,能帮你快速判断“这个加法器能跑多快”。

4.4 你不需要手动使用 Carry Chain

好消息是:当你写 c = a + bc = a - b 时,综合工具会自动识别并使用 Carry Chain。你不需要手动例化 CARRY4 原语。

但理解 Carry Chain 的存在,能帮你:

  • 看懂综合报告中的 Carry Chain 使用情况
  • 理解为什么加法器的时序比同等复杂度的纯逻辑要好
  • 在时序不满足时,知道可以通过流水线拆分来优化

5. SliceL vs SliceM:标准版与增强版

每个 CLB 包含 2 个 Slice,但这 2 个 Slice 不一定相同。Xilinx 将 Slice 分为两种类型:

核心区别

特性SliceL(Logic)SliceM(Memory)
LUT 功能只能做查找表查找表 + 分布式 RAM + 移位寄存器
LUT 可写性只读(配置后固定)可读可写(运行时可更新)
数量比例约占 2/3约占 1/3
典型用途通用逻辑、状态机、控制逻辑小型 FIFO、延迟线、分布式缓存

SliceM 的两个超能力

超能力 1:分布式 RAM

SliceM 中的 LUT 可以配置为小型 RAM:

  • 单个 LUT → 64×1 bit 单端口 RAM
  • 多个 LUT 组合 → 更大容量或多端口 RAM

适用场景:需要极低延迟的小容量存储(<64 bit),比如小型查找表、寄存器文件。

超能力 2:移位寄存器(SRL)

SliceM 中的 LUT 可以配置为高效的移位寄存器:

  • 单个 LUT → 最多 32 位移位寄存器(SRL32)
  • 4 个 LUT 级联 → 最多 128 位移位寄存器

适用场景:数据延迟线、流水线对齐、去抖动。一个 LUT 就能替代 32 个触发器,资源效率极高。

SliceM 的这两个超能力非常实用,但也有不少坑——比如 SRL 不能带复位信号,否则会退化为触发器链。下一篇文章我们会深入展开 SRL 的工作原理和正确使用姿势,以及触发器的设计陷阱。

💬 你可能会问:综合工具怎么知道该用 SliceL 还是 SliceM?

你不需要手动选择。综合工具会根据你的代码自动判断:普通逻辑映射到 SliceL,需要分布式 RAM 或 SRL 的逻辑映射到 SliceM。你只需要确保代码风格正确(比如 SRL 不能带复位信号),工具就能正确推断。


6. 设计启示:如何写出对 CLB 友好的代码

理解了 CLB 的内部结构,以下是几条实用的设计建议:

6.1 善用触发器做流水线

每个 Slice 有 8 个 FF,整个 FPGA 的触发器资源非常充裕。不要吝啬使用流水线寄存器——它们能有效切割长组合逻辑路径,提升时钟频率。

6.2 减少独特的控制信号

同一个 Slice 内的 8 个 FF 共享时钟(CLK)、时钟使能(CE)和置位/复位(S/R)信号。如果你的设计中有太多不同的控制信号组合,FF 会被分散到更多的 Slice 中,降低资源利用率。

6.3 让综合工具推断专用资源

  • c = a + b,工具会自动用 Carry Chain
  • 写移位寄存器时不要加复位信号,工具才能推断为 SRL
  • 写小容量 RAM 时用同步读写风格,工具会自动选择分布式 RAM 或 Block RAM

6.4 关注逻辑级数

当综合报告显示某条路径的逻辑级数(Logic Levels)过高时,意味着信号要穿过太多级 LUT。解决方案:

  • 插入流水线寄存器
  • 重构逻辑,减少单级的输入数量
  • 检查是否有不必要的优先级编码(if-else 链 vs case

7. 总结

组件核心作用关键数字你需要记住的一件事
LUT6实现任意 6 输入组合逻辑每 Slice 4 个查表不计算,任意函数延迟相同
F7/F8 MUX扩展 LUT 的逻辑宽度每 Slice 3 个16:1 MUX 可在单个 Slice 内完成
CARRY4加速算术运算进位传播每 Slice 1 条a+b 自动使用,无需手动例化
FF存储数据,实现时序逻辑每 Slice 8 个资源充裕,大胆用流水线
SliceM 特殊能力分布式 RAM + SRL约占 1/3 SliceSRL 不能带复位,否则退化为 FF 链

CLB 是 FPGA 的”逻辑心脏”。LUT 负责”想”(组合逻辑),FF 负责”记”(时序逻辑),Carry Chain 负责”算”(算术运算),MUX 负责”选”(信号路由)。四者协同,构成了 FPGA 实现任意数字逻辑的基础能力。


常见问题

Q1:一个 LUT6 最多能实现多大的 MUX?

4:1 MUX。因为 4:1 MUX 需要 4 个数据输入 + 2 个选择输入 = 6 个输入,刚好用满 LUT6 的 6 个输入端口。5:1 MUX 需要 8 个输入,超出了单个 LUT6 的能力。

Q2:为什么 Vivado 把我的 2:1 MUX 映射到 LUT 而不是专用 MUX?

Slice 内的专用 MUX(F7MUX、F8MUX)的输入只能来自 LUT 的输出,它们是用来扩展 LUT 逻辑宽度的,不是用来替代 LUT 实现小型 MUX 的。2:1 MUX 是一个简单的 3 输入组合逻辑,完全在 LUT 的能力范围内,所以工具直接用 LUT 实现。

Q3:Carry Chain 能用于除法运算吗?

Carry Chain 主要优化的是加法、减法和比较运算。除法运算通常需要更复杂的逻辑结构(如迭代除法器或查找表),不能直接利用 Carry Chain。如果需要高性能除法,建议使用 DSP Slice 或 Vivado 的 IP 核。

Q4:SliceL 和 SliceM 的比例可以调整吗?

不能。SliceL 和 SliceM 的比例是芯片制造时就固定的(通常约 2:1)。如果你的设计需要大量分布式 RAM 或 SRL,需要在选型时关注目标芯片的 SliceM 数量。


参考资料


系列导航:本文是「FPGA 内部资源深度解析」系列第 2 篇。

如果这篇文章对你有帮助,欢迎点赞、收藏,也欢迎在评论区分享你在 CLB 资源优化方面的经验。

End of file.