FPGA内部模块PFU配置: 6输入LUT如何实现32位移位寄存器

深入探究:6输入LUT如何实现32位移位寄存器?

LUT不仅可以实现任意组合逻辑,还可以配置为分布式RAM或移位寄存器。其中,用LUT实现移位寄存器是FPGA中非常高效且常用的技巧。本文将详细探讨一个6输入LUT(LUT6)是如何摇身一变,成为一个32位移位寄存器的。

一、LUT的多重身份

在Xilinx 7系列及之后的FPGA中,一个6输入LUT(LUT6)本质上是一个64×1的RAM(64个存储单元,每个单元1比特)。这是因为:

  • 6个地址输入可以寻址2⁶ = 64个不同的存储位置。
  • 每个存储位置可以存储1比特数据。

这种RAM特性使得LUT可以工作于多种模式:

  • 逻辑模式 :作为查找表实现组合逻辑,内容由综合工具根据逻辑函数真值表生成。
  • 分布式RAM模式 :作为小型RAM使用,支持同步写、异步读。
  • 移位寄存器模式(SRL) :作为串行输入、串行/并行输出的移位寄存器。

二、SRL32的工作原理

一个LUT6配置为移位寄存器时,称为 SRL32 (Shift Register LUT,深度32位)。为什么是32位,而不是64位?因为SRL模式只使用了LUT的一半存储单元(32个),另一半通常用于其他功能或保留。在Xilinx的术语中,有SRL16(深度16)和SRL32(深度32)之分,SRL32使用LUT6实现,而SRL16使用LUT5或LUT6的一半资源。

2.1 内部结构

SRL32的核心是一个32比特的移位寄存器链。它的主要口包括:

  • D(输入) :串行数据输入。
  • CLK(时钟) :移位时钟,上升沿有效。
  • CE(时钟使能) :可选,高电平时允许移位。
  • A[4:0](地址) :5位地址,用于选择32个抽头中的一个作为输出Q(异步读)。
  • Q(输出) :根据地址A选择的抽头输出(组合逻辑输出)。
  • Q31(输出) :最后一个寄存器的输出(第32级),通常用于级联。

注意 :SRL32没有专用的复位引脚。如果需要复位,可以通过在输入数据路径上添加逻辑实现,或者使用输出寄存器配合复位。

2.2 工作过程
  1. 移位操作 :在每个时钟上升沿(且CE有效时),内部32个寄存器的值依次向右移动一位。新数据从D输入进入第0级,原来第31级的数据移出丢失(除非通过Q31引出)。
  2. 读操作 :地址A[4:0]选择32个抽头中的一个(0~31),其当前值直接出现在输出Q上。这是 异步读 ,意味着Q随地址变化立即变化,不依赖时钟。
  3. 级联输出 :Q31输出第31级(最后一级)的值,可用于连接下一个SRL32的D输入,形成更长移位寄存器。

这种结构使得SRL32非常灵活:既可以作为简单的串行移位寄存器,又可以通过地址抽头实现可变的延迟线。

三、如何实例化SRL32?

在Xilinx的设计环境中,可以通过原语(Primitive)直接实例化SRL32。常用的原语有:

  • SRLC32E :带时钟使能的32位移位寄存器,支持级联输出(Q31)和可选抽头输出(Q)。
  • SRL16E :16位移位寄存器(使用半个LUT6)。
SRLC32E原语接口

verilog

复制代码
SRLC32E #(
   .INIT(32'h00000000)  // 初始值
) inst_name (
   .Q(Q),        // 抽头输出,由A决定
   .Q31(Q31),    // 最后一级输出(第31级),用于级联
   .A(A),        // 5位地址,选择抽头位置
   .CE(CE),      // 时钟使能
   .CLK(CLK),    // 时钟
   .D(D)         // 串行数据输入
);
  • A的范围是0~31,决定哪个抽头连接到Q。当需要固定延迟时,可以将A设为常数,此时Q输出固定延迟后的数据。
  • Q31始终输出第31级的值,用于级联下一级SRL。
  • INIT参数设置32个寄存器的初始值。如果不指定,默认全0。

四、级联多个SRL32实现更长移位寄存器

单个SRL32提供32位延迟。要构建64、96、128甚至更长的移位寄存器,只需将多个SRL32级联。

4.1 级联方法
  • 将第一个SRL32的Q31连接到第二个SRL32的D输入。
  • 所有SRL32共享相同的时钟和时钟使能。
  • 如果需要抽头输出,可以用地址选择每个SRL32的Q输出,但注意这些抽头是异步的。

例如,构建64位移位寄存器:

verilog

复制代码
wire [31:0] q31_tmp;  // 每级的Q31输出
wire [63:0] tap;      // 如果需要所有抽头,可能需要多级组合

// 第一级:低32位
SRLC32E #(.INIT(0)) srl0 (
   .Q(tap[31:0]?),    // 如果需要抽头,需要额外的多路选择
   .Q31(q31_tmp[0]),
   .A(addr_low),      // 地址控制低32位的抽头
   .CE(ce),
   .CLK(clk),
   .D(din)
);

// 第二级:高32位
SRLC32E #(.INIT(0)) srl1 (
   .Q(tap[63:32]?),
   .Q31(q31_tmp[1]),  // 可用于再下一级
   .A(addr_high),
   .CE(ce),
   .CLK(clk),
   .D(q31_tmp[0])
);
4.2 级联延迟与性能

级联多个SRL32时,数据路径上只有Q31到D的组合逻辑,没有额外触发器,因此级联延迟非常小(仅为LUT内部布线延迟),可以支持很高的工作频率。但要注意,抽头输出Q是组合的,如果多个SRL的抽头需要组合成大范围的多路选择,可能会引入较大的组合延迟,建议在需要同步输出时,用触发器重新寄存。

五、SRL32与触发器链、BRAM的对比

实现移位寄存器有多种方式:触发器链、SRL、BRAM。它们的适用场景不同:

实现方式 资源消耗 最大深度 性能 灵活性 典型应用
触发器链 每位移位需1个FF 任意 高(可流水) 灵活,每个抽头可直接访问 小深度(<64),需要多抽头且高性能的场景
SRL32 每32位消耗1个LUT6 32的倍数 抽头需通过地址选择 中等深度(32~几千),延迟线、FIFO
BRAM 每18Kb可配置 很大 较高 需配合计数器生成地址 深度很大(>512),如FIFO、行缓冲
  • SRL32的优势 :用LUT实现移位寄存器,比用触发器链节省大量资源(1个LUT6可替代32个触发器)。同时,由于LUT位于逻辑单元内,布线灵活,适合中等深度的延迟线。
  • SRL32的局限
  • 抽头输出是异步的,如果需要在时钟沿同步采样,需外加触发器。
  • 没有专用复位,复位需要额外逻辑。
  • 不支持异步清零/置位。

六、设计实例与应用场景

6.1 可编程延迟线

许多数字系统需要可变的延迟,例如时钟相位调整、脉冲展宽。用SRL32可以轻松实现:

verilog

复制代码
module variable_delay #(
   parameter MAX_DELAY = 32
)(
   input clk,
   input ce,
   input [4:0] delay,    // 0~31
   input din,
   output reg dout
);
wire q_tap;

SRLC32E srl (
   .Q(q_tap),
   .Q31(),
   .A(delay),
   .CE(ce),
   .CLK(clk),
   .D(din)
);

always @(posedge clk) dout <= q_tap;  // 同步输出,避免组合毛刺
endmodule
6.2 FIFO的存储体

异步FIFO通常使用BRAM作为存储体,但小深度FIFO(如16~64深度)用SRL实现更节省资源。FPGA厂商提供的FIFO IP核通常会自动选择用SRL还是BRAM,取决于深度配置。

6.3 流水线平衡

在高速设计中,经常需要插入流水线寄存器来平衡延迟。用SRL可以方便地在数据路径上插入固定延迟,而不必手动添加大量触发器。

七、使用SRL的注意事项

  1. 时钟使能 :SRL支持时钟使能,当CE无效时,数据保持不变。这在需要暂停移位的场景很有用。
  2. 初始化 :SRL可以像BRAM一样在配置时初始化,通过INIT参数指定初始值。如果不初始化,上电后SRL的内容是随机的(通常为0,但取决于工艺)。
  3. 复位 :SRL内部寄存器没有复位引脚。如果设计需要复位,可以在数据路径上添加一个选择器:当复位有效时,将D输入强制为0,同时让CE保持有效,这样移位寄存器会在几个时钟周期后清零。或者,可以使用输出触发器并复位输出。
  4. 功耗 :SRL工作时,每个时钟周期内部32个寄存器都会翻转,功耗比用BRAM高,但比用触发器链低。在深度较大且翻转频繁时,考虑用BRAM更省电。
  5. 同步读 :如果需要同步读抽头,务必在Q后加一级触发器,否则组合逻辑可能产生毛刺或时序违例。

八、本章总结

问题 答案
一个6-input LUT如何实现32位移位寄存器? LUT6本质是一个64×1的RAM,在移位寄存器模式下,将其中的32个存储单元组织成串行移位链,通过内部写地址指针实现移位,并通过5位地址选择抽头输出。
核心优势 1个LUT6替代32个触发器,大幅节省资源,同时保持较高性能。
如何级联? 通过Q31输出连接到下一级的D输入,实现深度扩展。
主要应用 可变延迟线、小深度FIFO、流水线平衡等。
注意事项 无复位、异步抽头输出、需要时钟使能、初始化等。

通过合理使用SRL,可以在FPGA设计中实现资源与性能的平衡。

相关推荐
FPGA小迷弟17 小时前
FPGA 时序约束基础:从时钟定义到输入输出延迟的完整设置
前端·学习·fpga开发·verilog·fpga
daxi1501 天前
Verilog入门实战——第3讲:流程控制语句(if-else / case / 循环结构)
fpga开发·fpga
biubiuibiu1 天前
工业机器人编程语言详解:多样化选择与应用
fpga开发·机器人
lf2824814311 天前
04 DDS信号发生器
fpga开发
szxinmai主板定制专家1 天前
基于 STM32 + FPGA 船舶电站控制器设计与实现
arm开发·人工智能·stm32·嵌入式硬件·fpga开发·架构
ARM+FPGA+AI工业主板定制专家2 天前
基于ARM+FPGA+AI的船舶状态智能监测系统(二)软硬件设计,模拟量,温度等采集与分析
arm开发·人工智能·目标检测·fpga开发
szxinmai主板定制专家2 天前
基于ZYNQ MPSOC船舶数据采集仪器设计(一)总体设计方案,包括振动、压力、温度、流量等参数
arm开发·人工智能·嵌入式硬件·fpga开发
FPGA小迷弟2 天前
高频时钟设计:FPGA 多时钟域同步与时序收敛实战方案
前端·学习·fpga开发·verilog·fpga
szxinmai主板定制专家2 天前
基于ZYNQ MPSOC船舶数据采集仪器设计(三)振动,流量,功耗,EMC,可靠性测试
arm开发·人工智能·嵌入式硬件·fpga开发