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块,同时保持滤波功能正确。
- 验收指标:
实施步骤
步骤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% |
| Fmax | 180 MHz | 120 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.rptD. 常见问题解答
- Q: TDM实现后功能不正确? A: 检查tap_cnt计数范围是否覆盖所有抽头,以及累加器清零时机是否在第一个抽头计算前。
- Q: 如何进一步提升Fmax? A: 将累加器拆分为两级流水线,或使用DSP48E1的预加器功能。



