FPGA实现希尔伯特变换的全流程解析:从原理到硬件实现
FPGA实现希尔伯特变换的全流程解析:从原理到硬件实现
引言
上一篇文章介绍了实信号转换为复信号的两种方法:希尔伯特变换和混频法,这篇文章就结合实际的项目详细的讲解一下FPFA实现希尔伯特变换的全部过程。
希尔伯特变换作为信号处理中的核心工具,在通信系统、医学成像、雷达信号处理等地方广泛应用。FPGA因其并行处理能力和可重构特性,成为实现实时希尔伯特变换的理想平台。本文将深入探讨基于FPGA的希尔伯特变换实现全流程,涵盖数学原理、滤波器设计、硬件架构和代码实现,并结合MATLAB仿真与FPGA验证案例进行剖析。
一、希尔伯特变换原理与数学建模
1.1 希尔伯特变换的定义
希尔伯特变换的时域表达式为:
H[x(t)]=1π∫−∞∞x(τ)t−τdτH[x(t)] = \\frac{1}{\\pi}\\int_{- \\infty}^{\\infty}\\frac{x( \\tau)}{t- \\tau}d \\tauH[x(t)]=π1∫−∞∞t−τx(τ)dτ
其频域传递函数为:
H(ω)=−j(sin(ω))={−j,ω>0j,ω0\\\\ j\\quad, \\omega < 0\\end{cases}H(ω)=−j(sin(ω))={−j,ω>0j,ω<0
该变换将正频率分量相移-90°,负频率分量相移+90°,生成正交信号对。
1.2 解析信号的构造
将原信号 $ x(t) $ 与其希尔伯特变换 $\\hat{x}(t) $ 组合为解析信号:
z(t)=x(t)+jx^(t)=A(t)ejϕ(t)z(t) = x(t) + j \\hat{x}(t) = A(t) e^{j \\phi (t)}z(t)=x(t)+jx^(t)=A(t)ejϕ(t)
其中 A(t)A(t)A(t) 为瞬时幅度, ϕ(t)ϕ(t)ϕ(t) 为瞬时相位,可进一步解调出频率和相位信息。
二、希尔伯特滤波器的设计
2.1 FIR滤波器设计要点
- 幅度特性:全通滤波器,通带增益为1
- 相位特性:正频率-90°相移,负频率+90°相移
- 阶数选择:必须为偶数阶(N=2k),且在0Hz和Nyquist频率处增益为0
2.2 MATLAB滤波器设计流程
1、生成滤波器系数的matlab代码
% 使用fdesign.hilbert 设计滤波器d = fdesign.hilbert(\'N,TW\', 64, 0.1); % 64阶,过渡带宽0.1*FsHd = design(d, \'equiripple\', \'SystemObject\', true);% 系数量化(16位定点)coef = Hd.Numerator;q_coef = fi(coef, 1, 16, 15); % 符号位1,总位宽16,小数位15%绘制滤波器系数的频率响应图[h,w] = freqz(coef); % 频率响应% 幅度谱(幅度取线性值)figure()subplot(2,1,1)plot(w/pi,abs(h),\'r\',\'LineWidth\',1.5)grid onaxis([0 1 -0.1 1.2])title(\'Magnitude spectrum of the filter\')ylabel(\'Magnitude\')% 幅度谱(幅度取dB值)subplot(2,1,2)plot(w/pi,db(h),\'b\',\'LineWidth\',1.5)grid onaxis([0 1 -80 10])xlabel(\'Normalized Frequency (\\times\\pi rad/sample)\')ylabel(\'Magnitude (dB)\')
关键参数:
- 通带波纹:<0.1dB(对应绝对误差<5‰)
- 阻带衰减:>60dB(确保正交精度)
- 量化处理:将< 2−152^{-15}2−15 的系数归零,优化硬件资源
图1 滤波器的频率响应图
2 滤波器系数保存为.coe文件
h = q_coef.int; %获取滤波器系数的十进制表示法len = length(h);fp = fopen(\'fir_data.coe\',\'wt\');%创建并打开存储滤波器系数的文件fprintf(fp,\'Radix = 10;\\n\');%以十进制的方式写入滤波器系数fprintf(fp,\'CoefData =\'); for i=1 : len dat = h(i); if(i == len) fprintf(fp,\'%d;\',dat); else fprintf(fp,\'%d,\\n\',dat);end endfclose(fp);%关闭文件
最终生成一个存储滤波器系数的文件“fir_data.coe”。在FPGA实现中需要调用这个文件用于实现希尔伯特滤波器。
三、FPGA实现架构
3.1 系统架构设计
module hilbert_transform ( input i_clk, // 系统时钟 input i_rst, // 复位信号 input [15:0] i_din, // 输入信号(16位定点) input i_en,// 输入信号有效 output [15:0] o_idata, // 同相分量 output [15:0] o_qdata, // 正交分量 output o_vld// 输出信号有效); wire [15:0] w_qdata;wire w_qvld;wire [15:0] w_idata;wire w_ivld;// FIR滤波器IP核实例化 fir_hilbert u_fir_hilbert ( .aresetn(~i_rst), .aclk(i_clk), // input wire aclk .s_axis_data_tvalid(i_en ), // input wire s_axis_data_tvalid .s_axis_data_tready( ), // output wire s_axis_data_tready .s_axis_data_tdata(i_din), // input wire [15 : 0] s_axis_data_tdata .m_axis_data_tvalid(w_qvld ), // output wire m_axis_data_tvalid .m_axis_data_tdata(w_qdata ) // output wire [15 : 0] m_axis_data_tdata); // 延迟补偿模块 delay_data u_delay_data ( .i_clk (i_clk), .i_rst (i_rst), .i_din(i_din), .i_en(i_en ), .o_dout(w_idata ), .o_vld(w_ivld ) ); assign o_qdata = w_qdata; assign o_idata = w_idata; assign o_vld = w_ivld & w_qvld; endmodule
3.2 Xilinx FIR IP核配置
-
打开IP界面 →\\rightarrow→ 搜索\"fir\"关键字→\\rightarrow→ 双击“FIR Compiler” 进入FIR IP的参数配置界面
-
设置IP名称“fir_hilbert” →\\rightarrow→ 选择Filter Options栏 →\\rightarrow→选择“COE File”选项采用coe文件的方式导入滤波系数→\\rightarrow→选择之前matlab生成的“fir_data.coe”文件 →\\rightarrow→ 滤波器类型选择“Single Rate”
-
选择Implementation栏 →\\rightarrow→ 设置输出数据为从低位截取“Truncate LSBs” →\\rightarrow→ 输出数据位宽设置为“16”
-
其他参数保持默认,最后点击“OK”完成FIR IP的参数配置
四、关键实现技术
4.1 相位补偿技术
由于FIR滤波器引入固定延迟 D=(N−1)2+D0D= \\frac {(N-1)} {2} + D_0D=2(N−1)+D0 (D0D_0D0 表示IP核引入的延时,在IP核的配置界面可以看到具体数值,界面见下图红框)
所以在具体工程中需要对原始信号进行延迟匹配的操作:
// 延迟补偿模块module delay_data(input i_clk, input i_rst, input[15:0]i_din,// 输入的原始数据 input i_en, output[15:0]o_dout,// 对齐延迟后的数据 output o_vld); parameter S_DELAY = 32 + 40 + 1; // 65阶滤波器延迟32周期,IP延时40,输出打一拍 reg [15:0] r_delay_chain [0:S_DELAY-1];reg [S_DELAY-1:0] r_delay_chain_en;integer i;always @(posedge i_clk) begin r_delay_chain[0] <= i_din; for (i=1; i<S_DELAY; i=i+1) r_delay_chain[i] <= r_delay_chain[i-1];endalways @(posedge i_clk) begin if(i_rst) r_delay_chain_en <= \'h0; else r_delay_chain_en <= {r_delay_chain_en[S_DELAY-2:0],i_en};end assign o_dout = r_delay_chain[S_DELAY-1]; // 对齐延迟后的数据assign o_vld = r_delay_chain_en[S_DELAY-1]; endmodule
4.2 资源优化策略
- 系数对称性利用:希尔伯特滤波器系数满足h(n)=−h(N−1−n)h(n)=-h(N-1-n)h(n)=−h(N−1−n),减少50%乘法器
- 折叠结构:采用4级折叠,将64阶滤波器分解为16个基本单元
- 位宽压缩:中间结果采用18位动态位宽,输出截断至16位
五、系统验证与误差分析
5.1 MATLAB-FPGA联合验证流程
- 测试信号生成:
fs = 100e3; % 采样率100kHzt = 0:1/fs:0.1;f1 = 10e3; f2 = 30e3;x = 0.5*sin(2*pi*f1*t) + 0.3*cos(2*pi*f2*t);
- FPGA仿真数据导出:
generate string file_iq_i = \"fpga_i.txt\"; string file_iq_q = \"fpga_q.txt\"; integer out_file_iq_i; integer out_file_iq_q; initial begin out_file_iq_i = $fopen(file_iq_i,\"w\"); out_file_iq_q = $fopen(file_iq_q,\"w\"); endalways @(posedge i_clk)beginif(w_iqvld)begin$fwrite(out_file_iq_i,\"%d\\n\",$signed(w_idata)); $fwrite(out_file_iq_q,\"%d\\n\",$signed(w_qdata)); endend endgenerate
- 误差分析:
% 读取FPGA输出数据fpga_i = load(\'fpga_i.txt\'); fpga_q = load(\'fpga_q.txt\'); % 计算正交误差ideal_phase = angle(hilbert(x))’;actual_phase = angle(fpga_i + 1j*fpga_q);phase_error = rms(ideal_phase - actual_phase); % 典型值<0.05 rad
- 资源消耗:
5.2 实测性能指标
六、结论
本文详细论述了FPGA实现希尔伯特变换的完整流程。通过MATLAB的fdesign.hilbert设计64阶等纹波FIR滤波器,结合Xilinx 的FIR Compiler IP核实现,最终在Virtex-7 FPGA硬件平台实现200MHz处理速率的希尔波特变换。实测结果表明,该方案相位误差小于1°,满足多数通信系统的正交解调需求。
七、预告
本篇文章介绍了实信号转换为复信号的第一种方法(希尔伯特变换)在FPGA上的实现的具体过程,下一篇文章将详细讲解实信号转换为复信号的第二种方法(混频法)在FPGA上的具体实现过程。感兴趣的小伙伴可以关注一下博主