Quick Start
- 在Vivado 2021.1中新建工程,器件选择
xc7a35tcsg324-1(Artix-7)。 - 创建顶层模块
top.v,例化I2S控制器、FIR滤波器与PWM输出模块。 - 编写I2S接收模块
i2s_receiver.v,从WM8731编解码器接收24位立体声数据,采样率48 kHz。 - 实现16阶低通FIR滤波器
fir_filter.v,系数采用汉明窗设计,截止频率8 kHz,直接型结构。 - 编写PWM输出模块
pwm_output.v,将滤波后的16位音频数据转换为1位PWM信号,载波频率384 kHz(8×48 kHz)。 - 编写测试平台
tb_top.v,生成48 kHz采样率的1 kHz正弦波测试激励,通过文本文件读写波形数据。 - 运行行为仿真(100 ms),观察
i2s_data_out与pwm_out波形,确认滤波后波形无混叠且幅度正确。 - 综合、实现,检查时序余量(setup slack > 0),生成比特流并下载至Nexys4 DDR板卡。
- 将耳机插入板载音频输出接口,播放1 kHz测试音,验证声音清晰无失真。
- 预期结果:仿真中滤波后波形平滑,上板后听到纯净1 kHz音调,无高频噪声。
前置条件与环境
| 项目 | 推荐值 | 说明/替代方案 |
|---|---|---|
| 器件/板卡 | Xilinx Artix-7 xc7a35tcsg324-1(Nexys4 DDR) | 其他Artix-7板卡(如Basys3)需调整引脚约束 |
| EDA版本 | Vivado 2021.1 | Vivado 2019.1及以上均可,注意IP版本兼容 |
| 仿真器 | Vivado Simulator(xsim) | ModelSim/Questa(需编译库) |
| 时钟/复位 | 板载100 MHz时钟,异步复位(低有效) | 可改用PLL生成12.288 MHz音频主时钟 |
| 接口依赖 | WM8731音频编解码器(I2S + I2C配置) | 其他I2S编解码器(如ADAU1361)需调整时序 |
| 约束文件 | XDC文件:定义时钟周期、I/O标准(LVCMOS33)、输入延迟 | 手动编写或使用板卡官方约束模板 |
| 外设 | 3.5 mm耳机/音箱,Micro-USB供电与下载线 | 无 |
目标与验收标准
- 功能点:实现48 kHz采样率、16位量化、8 kHz低通滤波的实时音频处理,通过PWM驱动耳机输出。
- 性能指标:FIR滤波器通带纹波<40 dB;PWM载波频率384 kHz,无 audible 噪声。
- 资源消耗:LUT < 800,FF < 600,DSP48E1 < 20,BRAM < 2(基于xc7a35t)。
- 时序约束:主时钟100 MHz,建立时间余量>0.1 ns,保持时间余量>0 ns。
- 验收方式:仿真波形显示输入正弦波经滤波后高频分量被抑制;上板后播放1 kHz测试音,示波器测量PWM输出占空比变化与音频信号一致。
实施步骤
工程结构与顶层设计
// top.v - 顶层模块
module top (
input wire clk_100m,
input wire rst_n,
// I2S接口(连接WM8731)
input wire i2s_bclk,
input wire i2s_lrclk,
input wire i2s_din,
output wire i2s_dout,
// PWM输出(驱动耳机)
output wire pwm_out
);
// 例化I2S接收、FIR、PWM模块
// 注意:时钟域划分:i2s_bclk域(I2S接收)、clk_100m域(FIR与PWM)
// 使用异步FIFO或双触发器同步跨时钟域信号
endmodule
工程结构:src/(RTL文件)、sim/(测试平台)、constrs/(XDC约束)、ip/(如需PLL或FIFO IP)。
常见坑:I2S时钟(bclk)与系统时钟(100 MHz)不同源,必须做跨时钟域处理(双触发器同步或异步FIFO)。
排查:若仿真中数据错位,检查i2s_lrclk边沿对齐与数据位宽(24位 vs 16位)。
关键模块:I2S接收与发送
// i2s_receiver.v - I2S从机接收(左对齐24位)
module i2s_receiver (
input wire bclk,
input wire lrclk,
input wire din,
output reg [23:0] left_data,
output reg [23:0] right_data,
output reg data_valid
);
// 使用移位寄存器在bclk上升沿采集数据
// lrclk为低时左声道,高时右声道
// data_valid在24位接收完成后拉高一个bclk周期
endmodule
注意:WM8731默认格式为I2S(MSB对齐,左声道在lrclk下降沿后一个bclk开始),需根据数据手册调整移位时机。
常见坑:忘记处理lrclk边沿导致声道混淆;数据位宽不匹配(24位 vs 16位)导致截断或符号扩展错误。
排查:仿真中打印lrclk与din波形,检查数据对齐。
关键模块:FIR滤波器
// fir_filter.v - 16阶直接型低通FIR,系数对称
module fir_filter (
input wire clk,
input wire rst_n,
input wire [15:0] data_in,
input wire data_valid,
output reg [15:0] data_out,
output reg out_valid
);
// 系数(16个,使用signed 16位,Q1.15格式)
// 采用流水线加法树提高Fmax
// 每时钟处理一个乘法,16个周期输出一次结果
endmodule
原理:直接型结构,系数对称可减少乘法器数量(8个DSP48E1)。
时序:数据有效信号data_valid驱动状态机,每48 kHz采样率下滤波器有约2083个100 MHz时钟周期可用,无需流水线也可满足时序。
常见坑:系数未归一化导致输出溢出;乘法器位宽不足(建议32位累加后截断)。
排查:仿真中对比输入输出幅度,检查是否削顶。
关键模块:PWM输出
// pwm_output.v - 16位PWM调制器
module pwm_output (
input wire clk,
input wire rst_n,
input wire [15:0] data_in,
input wire data_valid,
output reg pwm_out
);
// 计数器从0到65535循环,比较器输出
// data_in作为阈值,计数器小于阈值时pwm_out=1
// 载波频率 = clk / 65536 ≈ 1525 Hz(若clk=100 MHz)→ 不满足要求
// 改用8位PWM(载波384 kHz):计数器0~255,data_in高8位
endmodule
注意:16位PWM在100 MHz下载波仅1.5 kHz,会引入可听噪声;需降位宽至8位(384 kHz)或使用sigma-delta调制。
常见坑:PWM输出未加RC低通滤波导致高频噪声;占空比变化速率与音频采样率不匹配导致失真。
排查:示波器测量PWM波形,观察占空比是否随音频变化。
时序与约束
# top.xdc - 时序约束
create_clock -period 10.000 -name clk_100m [get_ports clk_100m]
set_input_delay -clock clk_100m -max 5.0 [get_ports i2s_bclk]
set_output_delay -clock clk_100m -max 4.0 [get_ports pwm_out]
# 异步时钟域约束(i2s_bclk到clk_100m)
set_clock_groups -asynchronous -group [get_clocks -include_generated_clocks clk_100m] -group [get_clocks -include_generated_clocks i2s_bclk]
常见坑:未声明异步时钟组导致Vivado分析错误路径,产生大量违例。
排查:综合后查看时序报告,关注setup/hold slack;若异步路径有违例,检查CDC同步器是否正确。
验证与仿真
// tb_top.v - 测试平台片段
initial begin
// 生成1 kHz正弦波,采样率48 kHz,16位量化
for (i = 0; i < 48000; i++) begin
sample = $sin(2*3.14159*1000*i/48000) * 32767;
#20833; // 48 kHz周期约20.833 μs
end
end
仿真时长:至少100 ms(4800个采样点)以观察滤波效果。
验收点:滤波后波形无高频毛刺,幅度衰减符合预期。
排障指南
- 仿真无输出:检查测试平台时钟与复位生成,确认
rst_n在仿真开始时被释放。 - 数据错位:核对I2S接收模块的移位时机与WM8731数据手册,确保lrclk边沿对齐正确。
- PWM无变化:确认
data_valid信号在滤波完成后被拉高,检查PWM计数器是否在正确频率下运行。 - 上板后无声:检查XDC引脚约束与板卡原理图是否一致;用示波器测量PWM引脚是否有波形。
- 时序违例:查看综合后时序报告,若异步路径有违例,确认CDC同步器(双触发器或异步FIFO)已正确例化。
扩展建议
- 增加I2C配置:添加I2C控制器模块,在初始化时配置WM8731的采样率、增益等参数。
- 多级滤波:级联多个FIR滤波器实现更陡峭的滚降特性,或切换不同系数实现均衡器功能。
- Sigma-Delta调制:用二阶或三阶sigma-delta调制器替代PWM,降低带内噪声,提升音质。
- 动态范围控制:加入AGC(自动增益控制)或限幅器,防止信号过载失真。
- 多通道处理:扩展至多路音频输入输出,实现混音或空间音频效果。
参考与附录
- WM8731数据手册(Cirrus Logic)
- Vivado Design Suite User Guide: Synthesis (UG901)
- Xilinx Artix-7 FPGA数据手册(DS181)
- Nexys4 DDR板卡原理图与约束模板(Digilent)
- 附录A:FIR滤波器系数生成脚本(MATLAB/Python)
- 附录B:完整XDC约束文件示例

评论 0
暂无评论,快来抢沙发吧