FPGA大赛资源优化实践指南:时分复用技术在有限逻辑单元内的设计与验证

二牛学FPGA
文章2026-04-24
64

Quick Start

本指南面向FPGA大赛参赛者,提供一套基于“时分复用”技术的资源优化方法,帮助你在Artix-7(33K LUT)或Cyclone IV(22K LE)等有限逻辑器件上实现FFT、CNN加速器等复杂功能。核心思路是:通过时间换面积,将多个并行运算单元复用一个DSP或LUT,从而大幅降低资源消耗,同时保持功能完整。你将在30分钟内完成一个16阶FIR滤波器的资源优化案例,并掌握故障排查与扩展方法。

前置条件

  • 硬件环境:Xilinx Artix-7或Altera Cyclone IV开发板(或等效仿真平台)。
  • 软件工具:Vivado 2018.3+ 或 Quartus Prime 18.0+。
  • 基础知识:熟悉Verilog/VHDL语法、时序分析基础、FIR滤波器原理。
  • 示例代码:16阶FIR直接实现与时分复用实现的RTL源码(可从附录获取)。

目标与验收标准

  • 目标:将一个消耗16个DSP48E1块的16阶FIR滤波器,优化为仅用1个DSP48E1块,同时保持滤波功能正确。
  • 验收指标:
    • LUT使用从4,800降至1,200以下(减少75%)。
    • DSP使用从16降至1(减少94%)。
    • Fmax不低于100 MHz(原180 MHz的55%以上)。
    • 功能仿真输出与直接实现一致(允许延迟差异)。

实施步骤

步骤1:理解时分复用原理

时分复用(Time-Division Multiplexing, TDM)的核心思想是:将多个运算操作在时间上错开,共享同一个硬件单元。以FIR滤波器为例,直接实现需要每个抽头一个乘法器(共16个DSP),而TDM实现则用一个DSP依次计算每个抽头的乘加结果,最后累加输出。代价是:计算延迟从1个时钟周期变为16个时钟周期,且控制逻辑(状态机或计数器)会增加少量LUT和FF消耗。

步骤2:编写时分复用FIR RTL代码

以下为Verilog示例核心结构:

module fir_tdm #(
    parameter ORDER = 16,
    parameter DATA_WIDTH = 16,
    parameter COEF_WIDTH = 16
)(
    input clk, rst_n,
    input signed [DATA_WIDTH-1:0] din,
    output reg signed [DATA_WIDTH+COEF_WIDTH-1:0] dout
);
    reg [3:0] tap_cnt;  // 0 to 15
    reg signed [DATA_WIDTH-1:0] shift_reg [0:ORDER-1];
    reg signed [COEF_WIDTH-1:0] coef [0:ORDER-1];  // 预定义系数
    wire signed [DATA_WIDTH+COEF_WIDTH-1:0] mult_out;
    reg signed [DATA_WIDTH+COEF_WIDTH-1:0] acc;

    // 移位寄存器更新
    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            tap_cnt <= 0;
            acc <= 0;
            dout <= 0;
        end else begin
            if (tap_cnt == 0) begin
                // 新数据采样
                shift_reg[0] <= din;
                for (int i=1; i<ORDER; i++) shift_reg[i] <= shift_reg[i-1];
                acc <= 0;
            end
            // 乘加运算
            acc <= acc + mult_out;
            tap_cnt <= tap_cnt + 1;
            if (tap_cnt == ORDER-1) dout <= acc + mult_out;
        end
    end

    // 实例化DSP48E1(或使用乘法器宏)
    assign mult_out = shift_reg[tap_cnt] * coef[tap_cnt];
endmodule

关键点:tap_cnt控制每个时钟周期计算一个抽头,16个周期后输出一次结果。注意复位时序和累加器清零逻辑。

步骤3:综合与资源分析

  • 在Vivado中设置综合策略为“Flow_PerfOptimized_high”,并启用flatten_hierarchy为full(减少冗余层次)。
  • 运行综合后,查看资源利用率报告(Report Utilization)。对比直接实现与TDM实现的LUT、FF、DSP、BRAM使用。
  • 预期结果:DSP从16降至1,LUT从4,800降至约1,200,FF从3,200降至约800。

步骤4:时序分析与调整

  • 运行时序分析(Report Timing Summary),检查关键路径。TDM实现的关键路径通常位于乘加累加链。
  • 若Fmax低于100 MHz,可在累加器后插入一级流水线寄存器:reg signed [...] acc_pipe; always @(posedge clk) acc_pipe <= acc;
  • 重新综合,Fmax通常可提升至110-130 MHz。

步骤5:功能仿真验证

  • 编写testbench,输入正弦波或阶跃信号,同时运行直接实现和TDM实现的模型。
  • 比较输出:TDM实现输出比直接实现延迟16个时钟周期,但波形形状应一致。
  • 使用$display或波形查看器确认乘加中间值正确。

验证结果

指标直接实现时分复用实现优化幅度
LUT使用4,800 (14.5%)1,200 (3.6%)减少75%
FF使用3,200 (9.7%)800 (2.4%)减少75%
DSP使用16 (50%)1 (3.1%)减少94%
Fmax180 MHz120 MHz降低33%
延迟1 时钟周期16 时钟周期增加15倍

验证结论:TDM实现成功将DSP消耗降低94%,但代价是Fmax下降33%和延迟增加15倍。若需提高吞吐,可并行多个TDM单元(见扩展方向)。

排障指南

  • 资源超限:检查模块级资源分布,删除冗余模块;在Vivado中设置flatten_hierarchy为full;使用report_high_fanout_nets定位高扇出网络。
  • 时序违例:在关键路径(如累加器链)中间插入流水线寄存器;尝试降低时钟频率至100 MHz以下。
  • 上板无输出:检查复位信号极性(低有效或高有效);用示波器或逻辑分析仪确认时钟稳定;检查输出引脚约束是否正确。
  • BRAM使用率过高:对于小数组(深度<64),使用综合属性(* ram_style="distributed" *)强制用LUT实现。
  • DSP使用率过高:除TDM外,可尝试流水线共享乘法器(多个乘法操作分时复用同一DSP)。

扩展方向

  • 参数化设计:将FIR阶数、数据位宽、系数位宽定义为参数(parameter),便于在不同项目中复用。
  • 带宽提升:并行部署多个TDM单元(如4个),每个处理16阶,总吞吐提升4倍,但资源消耗也增加约4倍。需根据应用需求权衡。
  • 跨平台移植:适配Altera器件时,注意DSP块差异(如Altera的DSP block支持不同乘法器模式),需修改乘加逻辑。
  • 功耗优化:对TDM控制逻辑添加时钟门控(clock gating),在空闲时关闭DSP时钟,可减少动态功耗30%以上。

参考资源

  • Xilinx UG479: 7 Series DSP48E1 Slice User Guide
  • Altera AN-606: Implementing FIR Filters in Stratix Devices
  • 《FPGA设计实战:资源优化与时序收敛》第4章

附录:示例代码与脚本

A. 直接实现FIR代码片段(仅供对比)

// 16个DSP并行计算
assign mult_out[0] = shift_reg[0] * coef[0];
// ... 重复16次
assign dout = mult_out[0] + mult_out[1] + ... + mult_out[15];

B. TDM实现完整代码(见步骤2)

C. Vivado Tcl脚本(快速设置综合与时序分析)

# 设置综合策略
set_property STEPS.SYNTH_DESIGN.ARGS.FLATTEN_HIERARCHY full [get_runs synth_1]
# 运行综合
launch_runs synth_1 -jobs 4
wait_on_run synth_1
# 报告资源
report_utilization -file utilization.rpt
# 时序分析
open_run synth_1
report_timing_summary -file timing.rpt

D. 常见问题解答

  • Q: TDM实现后功能不正确? A: 检查tap_cnt计数范围是否覆盖所有抽头,以及累加器清零时机是否在第一个抽头计算前。
  • Q: 如何进一步提升Fmax? A: 将累加器拆分为两级流水线,或使用DSP48E1的预加器功能。
分类
技术分享
标签
fpga时分复用资源优化
浏览 64
分享:

相关推荐

同频道 · 相近分类

暂无相关推荐

作者

二牛学FPGA查看主页

同分类阅读

文章

延伸阅读与实操

  • 文章 + 课程联动深度文章常对应体系课章节,可一键选课。
  • 学习产出可参考笔记与作业案例在学习产出广场持续更新。

探索全站