FPGA内部模块详解之二 FPGA的逻辑“心脏”——可编程逻辑块(PFU/CLB)深度解析

第2篇:FPGA的逻辑"心脏"------可编程逻辑块(PFU/CLB)深度解析

一、什么是可编程逻辑块?

1.1 不同厂商的不同叫法

在深入细节之前,我们需要先统一一下概念。不同FPGA厂商对基本可编程逻辑单元有不同的命名:

厂商 基本逻辑单元名称 说明
Xilinx(AMD) CLB(Configurable Logic Block) 每个CLB包含2个Slice
Intel(Altera) LAB(Logic Array Block) 每个LAB包含10个LE(Logic Element)
Lattice PFU(Programmable Function Unit) 由8个LUT和8-9个寄存器组成

尽管名称各异,但它们的核心组成是相似的: 查找表(LUT)+ 触发器(Flip-Flop)+ 进位链(Carry Chain)+ 多路选择器(MUX) 。本章将以Xilinx 7系列架构为主进行讲解,因为其资料最为丰富,结构也最具代表性,其他厂商的器件原理相通,只是组织方式略有差异。

1.2 CLB的层级结构

在Xilinx FPGA中,逻辑资源的组织关系如下:

  • 最顶层 :整个芯片由大量CLB阵列组成
  • CLB层 :每个CLB包含2个Slice
  • Slice层 :每个Slice包含:
  • 4个6输入查找表(LUT6)
  • 8个触发器(Flip-Flop)
  • 3个数据选择器(MUX)
  • 1个进位链(Carry Chain)

小知识 :一个CLB中的两个Slice可以是SLICEL(Logic)和SLICEM(Memory)的组合,也可以是两个SLICEL。通常,FPGA中约2/3的Slice是SLICEL,1/3是SLICEM。

二、查找表(LUT)------组合逻辑的实现者

2.1 LUT的本质:一个可编程的ROM

查找表(Look-Up Table,LUT)是FPGA实现组合逻辑的核心元件。它的本质是什么?简单来说, LUT就是一个小的RAM(或ROM)

理解LUT的关键在于一个基本事实:对于一个n输入的逻辑函数,无论它多么复杂,其输出结果的可能性最多只有2ⁿ种。例如,一个2输入与门,输入有00、01、10、11四种组合,对应的输出分别是0、0、0、1。这四种结果完全可以预先存储在一个小型的存储器中,然后用输入信号作为地址去"查表"读出对应的输出。

2.2 6输入LUT的工作模式

以7系列FPGA中的LUT6为例,它有6个输入(A1-A6)和2个输出(O5、O6)。它可以工作在两种模式下:

模式一:6输入1输出

  • 使用全部6个输入A1-A6
  • 输出为O6
  • 可以实现任意6输入布尔函数
  • 相当于一个64×1的ROM(2⁶=64种存储结果)

模式二:5输入2输出

  • 使用A1-A5作为输入,A6被拉高
  • O5和O6分别输出两个独立的5输入布尔函数
  • 这两个函数共用相同的5个输入
  • 相当于两个32×1的ROM

通俗理解 :LUT就像一本"答案之书"。你在书上写下所有可能的问题(输入组合)对应的答案(输出结果),然后当有人问你问题时,你根据问题内容(输入信号)快速翻到对应页码,读出答案。这个过程就是"查找表"的含义。

2.3 从代码到LUT的映射

让我们通过一个简单的例子,看看Verilog代码是如何映射到LUT的:

verilog

复制代码
// 例1:6输入与门
module lut_test1(
    input [5:0] data,
    output data_o
);
assign data_o = data[0]&data[1]&data[2]&data[3]&data[4]&data[5];
endmodule

这段代码会综合成一个LUT6,其真值表中只有输入全为1时输出1,其余情况输出0。

verilog

复制代码
// 例2:混合逻辑表达式(5输入)
module lut_test2(
    input [5:0] data,
    output data_o
);
assign data_o = ((data[0]&data[1])^data[2]|data[3]&data[4]);
endmodule

这段代码只用了5个输入,会综合成一个LUT5,O6输出结果。

通过这两个例子可以看到, 开发者并不需要关心LUT的具体配置,综合工具会自动将逻辑函数转换为LUT的编程数据 。这正是FPGA开发"软件化"的体现。

三、进位链(Carry Chain)------算术运算的加速器

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

加法运算是数字电路中最基本的算术操作。如果用常规的LUT实现加法器,需要复杂的逻辑门组合,而且随着位宽增加,延迟会急剧增大。为了解决这个问题,FPGA在Slice中集成了专用的进位链逻辑。

进位链的本质是一个 快速超前进位电路 ,它可以在LUT计算出"和"与"进位"的中间结果后,快速将进位传递到下一级,而不需要经过通用布线资源。

3.2 CARRY4的结构与原理

在7系列FPGA中,进位链单元称为 CARRY4 。它的主要接口包括:

  • S输入 :来自LUT的异或结果(S = A ⊕ B)
  • DI输入 :来自LUT的另一个输入(通常为A或B)
  • CYINIT :初始进位值(通常为0)
  • CIN :来自上一级的进位输入
  • O输出 :加法结果
  • CO输出 :进位输出

CARRY4的内部结构包含4个相同的级联单元,每个单元可以处理1比特的加法。

3.3 加法运算实例分析

让我们通过一个具体例子,看看CARRY4是如何计算加法的:

假设要计算 a = 4'b1000 (8) 和 b = 4'b1100 (12) 的和,预期结果为20(5'b10100)。

计算过程如下:

  1. 首先计算 S = a ⊕ b = 4'b0100
  2. 取 DI = b = 4'b1100(也可以取a)
  3. CIN = 0(没有低位进位)
  4. CARRY4逐位计算:
位数 S DI 低位进位 O(和) CO(进位输出)
bit0 0 0 0 0 0
bit1 0 0 0 0 0
bit2 1 0 0 1 0
bit3 0 1 0 0 1

最终结果:{CO3, O3, O2, O1, O0} = 5'b10100 = 20 ✅

3.4 多位宽加法的级联

对于8位加法,需要两个CARRY4级联;对于48位加法,则需要12个CARRY4级联。 级联级数越多,路径延迟越大,时序越难收敛 。这是一个在实际设计中需要重点关注的问题。

设计提示 :当进行大位宽加法时(如48位计数器),可以考虑将加法拆分成多个小位宽加法并在中间插入寄存器,虽然会增加一些LUT资源,但能显著改善时序。

四、触发器(Flip-Flop)------时序逻辑的基石

4.1 触发器的基本功能

触发器是FPGA中实现时序逻辑的核心元件。它的作用是在时钟边沿(上升沿或下降沿)将输入数据"锁存"到输出端,从而实现数据的存储和同步。

每个Slice中包含 8个触发器 。这8个触发器分为两类:

  • 4个专用触发器 :只能配置为边沿触发的D触发器
  • 4个多功能触发器 :可配置为边沿触发的D触发器,或电平敏感的锁存器(Latch)

重要提醒 :当4个多功能触发器被用作锁存器时,那4个专用触发器将无法使用。也就是说,一个Slice要么拥有8个D触发器,要么拥有4个D触发器+4个锁存器。

4.2 触发器的控制集

每个触发器都有三个控制端口:

  • CE :时钟使能(Clock Enable)
  • SR :置位/复位(Set/Reset)
  • CLK :时钟

这三个信号的组合称为触发器的 控制集 。在设计中,控制集的种类越少越好,因为同一个Slice内的触发器必须共享相同的控制信号。如果设计中使用了太多不同的时钟、复位极性组合,会导致触发器分散在不同的Slice中,降低资源利用率。

4.3 触发器与锁存器的对比

很多初学者容易混淆触发器和锁存器,这里做一个清晰的对比:

特性 触发器(Flip-Flop) 锁存器(Latch)
触发方式 边沿敏感(上升/下降沿) 电平敏感(高/低电平)
同步性 时序元件 组合逻辑的一种
抗毛刺能力 弱(电平期间输入变化直接影响输出)
设计建议 推荐使用 尽量避免(容易产生时序问题)

如何避免意外生成锁存器 :在组合逻辑中(always @(*)),一定要保证if语句有配套的else,case语句有default。时序逻辑(always @(posedge clk))则不需要,因为触发器本身会保持原值。

五、多路选择器(MUX)------信号路由的枢纽

5.1 LUT实现的MUX

有趣的是,LUT本身就可以实现小型多路选择器。一个LUT6可以配置成一个 4选1多路选择器 。它的4路数据输入和2路地址输入共同连接到LUT的6个输入端。

5.2 Slice中的专用MUX

除了LUT,每个Slice还包含3个专用的多路选择器: F7AMUX、F7BMUX和F8MUX 。它们的作用是与LUT配合,实现更大规模的多路选择:

  • 两个LUT + F7MUX → 8选1多路选择器(每个Slice可实现2个)
  • 四个LUT + F7AMUX + F7BMUX + F8MUX → 16选1多路选择器(每个Slice可实现1个)

这种层次化的MUX结构,使得FPGA可以高效地实现大型数据选择逻辑,而不需要占用大量通用布线资源。

六、SLICEL vs. SLICEM------Logic与Memory的区别

6.1 主要区别

前面多次提到,Slice分为SLICEL和SLICEM两种类型。它们的主要区别在于 LUT的功能扩展

功能 SLICEL SLICEM
基本LUT逻辑
ROM
分布式RAM
移位寄存器

简单来说, SLICEM中的LUT可以"兼职"做存储功能,而SLICEL只能做逻辑

6.2 分布式RAM(Distributed RAM)

SLICEM中的LUT可以配置为 分布式RAM

  • 单个LUT6可配置为64×1的RAM
  • 多个LUT6可级联成更大容量
  • 写操作同步,读操作异步(如需同步读,需额外使用触发器)
6.3 移位寄存器(Shift Register)

SLICEM中的LUT还可以配置为 移位寄存器

  • 单个LUT6可实现32位移位寄存器
  • 同一Slice中的4个LUT6可级联实现128位移位寄存器
  • 常用于实现延迟线、FIFO缓冲等

应用场景 :当需要少量存储资源时,使用SLICEM的分布式RAM比调用BRAM更高效,可以节省BRAM资源给更需要的地方。

七、设计中的实用建议

7.1 资源选择策略
需求 推荐资源 原因
普通组合逻辑 SLICEL 够用且资源丰富
少量存储(<几百bit) SLICEM分布式RAM 节省BRAM
较大存储(Kb级别) BRAM 专用硬核,性能更好
延迟线 SLICEM移位寄存器 高效利用LUT
7.2 控制集优化

如前所述,控制集种类过多会影响资源利用率。优化方法:

  • 时钟种类尽可能少 :同一设计中使用尽量少的独立时钟
  • 复位策略统一 :要么全部同步复位,要么全部异步复位,避免混合使用
  • 复位极性一致 :要么全部高有效,要么全部低有效
7.3 进位链时序优化

对于大位宽加法器/计数器:

  • 考虑拆分成多级流水线
  • 每级之间插入寄存器
  • 虽然增加LUT开销,但显著改善时序

八、本章小结

本章我们深入探索了FPGA的"心脏"------可编程逻辑块(PFU/CLB),重点掌握了以下内容:

核心组件 功能 关键特性
LUT 实现组合逻辑 6输入可配置,本质是小RAM
进位链 加速算术运算 专用超前进位电路
触发器 时序逻辑存储 8个/Slice,有控制集概念
MUX 信号选择路由 层次化结构,可扩展至16选1
SLICEM 扩展存储功能 分布式RAM、移位寄存器

一句话总结 :可编程逻辑块是FPGA最基础的积木块,LUT实现"逻辑",触发器实现"记忆",进位链实现"运算",三者配合加上灵活的MUX,构成了FPGA实现千变万化数字电路的根基。

相关推荐
Saniffer_SH3 小时前
【高清视频】如何针对电动汽车进行通信可靠性测试、故障注入与功率分析?
服务器·驱动开发·测试工具·fpga开发·计算机外设·硬件架构·压力测试
博览鸿蒙4 小时前
基于FPGA技术的数字存储示波器设计探讨
fpga开发
Saniffer_SH5 小时前
【高清视频】企业级NVMe SSD (E3.S, U.2)和消费类M.2 SSD拆解分析
服务器·网络·数据库·驱动开发·测试工具·fpga开发·压力测试
嵌入式-老费5 小时前
Linux camera驱动开发(ARM、FPGA、DDR共享总线)
图像处理·驱动开发·fpga开发
尤老师FPGA6 小时前
HDMI数据的接收发送实验(五)
fpga开发
范纹杉想快点毕业6 小时前
Zynq-7000 PS端开发深度技术指南:从硬件架构到实战应用
fpga开发·硬件架构
FPGA小迷弟6 小时前
FPGA工业常用接口:FPGA 的 SPI 总线多从机通信设计与时序优化
学习·fpga开发·verilog·fpga·modelsim
Flamingˢ15 小时前
基于ARM的裸机程序设计和开发(一):Zynq SoC FPGA的诞生
arm开发·fpga开发