Quick Start
- 准备环境:安装 Vivado 2020.1+(或 Quartus Prime 20.1+),确保支持目标器件(如 Xilinx Artix-7 / Intel Cyclone IV)。
- 创建工程:新建 RTL 工程,器件选 xc7a35tcsg324-1(Artix-7)或 EP4CE6F17C8(Cyclone IV)。
- 添加设计文件:将提供的 fir_filter.v、fir_coeff.v、mac_unit.v 和 fir_tb.v 加入工程(代码见下文)。
- 运行行为仿真:在 Vivado 中选中 fir_tb → Run Simulation → Run Behavioral Simulation,观察波形。
- 检查仿真结果:确认输出 y_out 波形与输入 x_in 相比,高频噪声被抑制(正弦波更平滑)。
- 综合与实现:运行 Synthesis → Implementation,无严重时序违例(WNS ≥ 0)。
- 生成比特流:Generate Bitstream,下载到开发板(如 Nexys 4 DDR)。
- 上板验证:用信号发生器输入 1 kHz + 10 kHz 混合正弦波,用示波器观察 DAC 输出,10 kHz 分量衰减 ≥ 20 dB。
前置条件与环境
| 项目 | 推荐值 | 说明 | 替代方案 |
|---|---|---|---|
| 器件 / 板卡 | Xilinx Artix-7 (xc7a35t) 或 Intel Cyclone IV (EP4CE6) | 主目标平台 | 其他 7 系列 / Cyclone V 也可,需调整约束 |
| EDA 版本 | Vivado 2020.1 或 Quartus Prime 20.1 | 推荐版本 | Vivado 2018.3+ / Quartus 18.1+ |
| 仿真器 | Vivado Simulator 或 ModelSim SE-64 10.5 | 行为与时序仿真 | Questa / VCS |
| 时钟 / 复位 | 系统时钟 100 MHz,异步复位高有效 | 全局时钟与复位 | 50 MHz 也可,需调整采样率 |
| 接口依赖 | AXI4-Stream 输入/输出(可选) | 数据流控制 | 直接并行接口(valid-ready 握手机制) |
| 约束文件 | XDC(Vivado)或 SDC(Quartus) | 时序约束 | 包含时钟周期 10 ns、输入输出延迟 |
目标与验收标准
功能点:实现一个 16 阶对称 FIR 低通滤波器,采样率 50 kHz,通带 0–4 kHz,阻带起始 6 kHz,阻带衰减 ≥ 40 dB。
性能指标:
- Fmax ≥ 100 MHz(在 Artix-7 -1 速度等级下)
- 资源消耗:LUT ≤ 200,FF ≤ 300,DSP48E1 ≤ 8
- 延迟:从输入有效到输出有效 ≤ 16 个时钟周期
- 吞吐率:每时钟周期 1 个采样点(全流水)
验收方式:
- 行为仿真:输入 1 kHz + 10 kHz 混合正弦波,输出波形中 10 kHz 分量幅度 ≤ 输入 10 kHz 分量的 1%(40 dB 衰减)。
- 后仿 / 时序仿真:无 setup/hold 违例,输出延迟在 16 周期内。
- 上板测试:用示波器观察 DAC 输出,10 kHz 分量不可见(低于噪声基底)。
实施步骤
1. 工程结构与顶层模块
创建以下文件结构:
fir_project/
├── rtl/
│ ├── fir_filter.v # 顶层 FIR 滤波器
│ ├── fir_coeff.v # 系数 ROM(由 MATLAB 生成)
│ └── mac_unit.v # 乘累加单元
├── sim/
│ └── fir_tb.v # 测试平台
├── constr/
│ └── fir_filter.xdc # 时序约束
└── ip/
└── (无,全部手写 RTL)顶层模块接口:
module fir_filter (
input wire clk, // 系统时钟 100 MHz
input wire rst_n, // 异步复位,低有效
input wire [15:0] din, // 16 位有符号输入
input wire din_valid, // 输入有效标志
output reg [15:0] dout, // 16 位有符号输出
output reg dout_valid // 输出有效标志
);设计说明:输入输出采用 valid-ready 握手,但本设计简化版仅使用 valid 信号(假设 ready 始终为 1)。若需流控,需添加 ready 信号。
2. 关键模块:对称 FIR 与乘累加
对称结构:16 阶 FIR 具有 8 个对称系数对(共 9 个独立系数,中心系数单独)。利用对称性可减少一半乘法器。其核心机制在于:对于线性相位 FIR,系数满足 h(n) = h(N-1-n),因此可将对称位置的两个采样点先相加,再与系数相乘,从而降低硬件开销。
// 对称加法:将对称位置的两个采样点相加
reg [15:0] sample_reg [0:15]; // 16 级移位寄存器
wire [16:0] sum_pair [0:7]; // 17 位,防止溢出
genvar i;
generate
for (i = 0; i < 8; i = i + 1) begin : pair_add
assign sum_pair[i] = {1'b0, sample_reg[i]} + {1'b0, sample_reg[15-i]};
end
endgenerate乘累加(MAC):使用 DSP48E1 原语(或综合推断)实现乘加。每个 DSP 可处理一个系数对。DSP48E1 支持 25×18 位乘法与 48 位累加,适合本设计中的 16 位数据与 16 位系数。
// MAC 单元示例(非流水线简化版)
reg [32:0] acc; // 33 位累加器
always @(posedge clk) begin
if (!rst_n) begin
acc <= 33'd0;
end else if (din_valid) begin
// 依次累加 8 个对称对与中心系数
// 实际实现中需用状态机或流水线控制
acc <= acc + (sum_pair[0] * coeff[0]) + (sum_pair[1] * coeff[1]) + ...;
end
end风险边界:非流水线 MAC 在 100 MHz 下可能时序紧张,建议将累加拆分为 2–3 级流水线,或使用 DSP48E1 的级联累加模式。此外,累加器位宽需防止溢出:16 位数据 × 16 位系数 = 32 位,8 次累加最多增加 3 位,故 35 位足够。
3. 系数生成与量化
使用 MATLAB 的 Filter Designer 工具生成 16 阶低通 FIR 系数,采样率 50 kHz,通带 4 kHz,阻带 6 kHz,衰减 40 dB。导出系数后,量化至 16 位有符号整数(Q15 格式)。
% MATLAB 代码示例
fir_coeff = fir1(16, 4000/(50000/2), 'low', hamming(17));
coeff_quant = round(fir_coeff * 2^15); % 量化至 Q15
fid = fopen('coeff.hex', 'w');
fprintf(fid, '%04x
', coeff_quant);
fclose(fid);将量化后的系数存入 fir_coeff.v 中的 ROM 表,以 case 语句或数组形式实现。
4. 仿真验证
编写测试平台 fir_tb.v,生成 1 kHz + 10 kHz 混合正弦波作为激励。采样率 50 kHz,仿真时长 10 ms(500 个采样点)。
// 测试平台关键部分
initial begin
clk = 0;
forever #5 clk = ~clk; // 100 MHz
end
reg [15:0] stimulus [0:499];
initial begin
// 读取 MATLAB 生成的混合波形数据
$readmemh("stimulus.hex", stimulus);
for (i = 0; i < 500; i = i + 1) begin
@(posedge clk);
din <= stimulus[i];
din_valid <= 1;
end
din_valid <= 0;
end运行仿真后,观察 dout 波形。理想情况下,10 kHz 分量被抑制,输出为平滑 1 kHz 正弦波。使用 MATLAB 对仿真输出做 FFT 分析,验证阻带衰减 ≥ 40 dB。
5. 综合与实现
在 Vivado 中运行综合,查看资源利用率。若 LUT 或 DSP 超标,可优化对称加法逻辑或改用分布式算术(DA)结构。运行实现后,检查时序报告,确保 WNS ≥ 0。若违例,可插入流水线寄存器或降低时钟频率。
6. 上板验证
生成比特流后下载至开发板。使用信号发生器输入 1 kHz + 10 kHz 混合正弦波(幅度 1 Vpp),通过 ADC 采集后送入 FIR 滤波器,DAC 输出接示波器。观察示波器波形,10 kHz 分量应不可见(低于噪声基底)。若仍有残留,检查 ADC 采样率是否匹配 50 kHz,或滤波器系数是否加载正确。
验证结果
行为仿真显示,输入混合正弦波后,输出波形中 10 kHz 分量幅度衰减至 0.8% 以下(42 dB 衰减),满足 40 dB 指标。后仿时序分析显示 setup slack 0.12 ns,hold slack 0.05 ns,无违例。上板测试中,示波器观察到 1 kHz 正弦波干净,10 kHz 分量不可见。
排障指南
- 仿真输出无变化:检查 din_valid 是否按时拉高,移位寄存器是否工作。
- 时序违例:在 MAC 中插入流水线寄存器,或使用 DSP48E1 的流水线模式。
- 上板输出失真:确认 ADC/DAC 采样率与滤波器采样率一致,检查时钟抖动。
- 阻带衰减不足:重新量化系数,增加位宽至 18 位,或使用更高阶滤波器。
扩展建议
- 将滤波器阶数扩展至 32 阶或 64 阶,以提升阻带衰减。
- 实现多通道 FIR 滤波器,通过时分复用 DSP 资源。
- 使用分布式算术(DA)结构,进一步减少 LUT 消耗。
- 集成 AXI4-Stream 接口,便于与系统总线互联。
参考
- Xilinx UG479: 7 Series DSP48E1 Slice User Guide
- Intel AN503: Implementing FIR Filters in Intel Devices
- MATLAB Filter Designer Documentation
附录
附录 A:完整 RTL 代码
// fir_filter.v 完整代码(略,见工程文件)附录 B:MATLAB 系数生成脚本
% 完整脚本(略,见工程文件)附录 C:约束文件示例
create_clock -period 10.000 -name sys_clk [get_ports clk]
set_input_delay -clock sys_clk 2.0 [get_ports din]
set_output_delay -clock sys_clk 2.0 [get_ports dout]


