Vivado hilbert变换的实现

1 待解决的问题

1、如何生成希尔伯特滤波器IP核的系数;
2、希尔伯特滤波器的硬件如何实现;

2 实现流程

1、MATLAB产生希尔伯特滤波器的输入数据(正弦波信号);
2、将输入数据经过希尔伯特变换,把实信号变成复信号。

2.1 希尔伯特滤波器的输入数据生成

步骤:MATLAB产生一个正弦波------将正弦波导出为coe文件----将coe文件导入到ROM IP核中-----调用ROM IP,将该IP的输出作为希尔伯特滤波器的输入数据
具体而言:
1、coe文件的生成

close all;
clear all;
clc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%           参数定义
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
L=1024;          % AD9238采样点数
ADC_bit=12;      % 采样位数

fc=5e6;          % 信号频率
fs=65e6;         % 采样频率
% L=1920;        % 采样点数
yinzi=100;       % 缩减因子,避免出现  D 必须为小于 flintmax 的非负整数。

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              产生信号
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
t=0:1/fs:(L-1)/fs;
st=sin(2*pi*fc*t);

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              信号处理
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
y=st/yinzi;                        % 估计信号幅度,不能归一化来解决  
yt=round(y*(2^(ADC_bit-1)-1));     % 12bit量化



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%              绘图
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
figure(1);
plot(st);hold on;
title('原信号');

figure(2);
plot(y,'-r');hold on;
legend('缩减后的信号');

figure(3);
plot(yt);hold on;
legend('量化后的信号');

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%            信号幅度估计
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
ST_FFT=fftshift(fft(st));    % 傅里叶变换
P_ST=abs(ST_FFT)/L;          % 幅度谱
u_st=max(P_ST);              % 得到波束1接收到的信号的幅度值
fprintf('u_st信号的幅度值为%g\n',u_st);

Y_FFT=fft(y,L);     % 傅里叶变换
P_Y=abs(Y_FFT)/L;   % 幅度谱
u_y=max(P_Y);       % 得到波束1接收到的信号的幅度值
fprintf('u_y信号的幅度值为%g\n',u_y);

YT_FFT=fft(yt,L);   % 傅里叶变换
P_YT=abs(YT_FFT)/L; % 幅度谱
u_yt=max(P_YT);     % 得到波束1接收到的信号的幅度值
fprintf('u_yt信号的幅度值为%g\n',u_yt);

AM=(u_st/yinzi)*(2^(ADC_bit-1)-1)/u_yt;  % 扩大倍数



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%            MATLAB生成coe文件
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%.coe文件中
% 第一行为定义数据格式, 2代表 ROM 的数据格式为二进制。
% 从第 3 行开始到第最后一行,是这个  L(数据长度为1024* ADC_bit(16bit) 大小 ROM 的初始化数据。
% 第一行到倒数第二行的数字后面用逗号,最后一行数字结束用分号。
fid=fopen('data_in.coe','w');  % w表示write
% fid=fopen('data.txt','w');  % w表示write
fprintf(fid,'Memory_Initialization_Radix = 2;\r\n'); % 二进制
fprintf(fid,'Memory_Initialization_Vector = \r\n');
for p=1:L
    B_s=dec2bin(yt(p)+(yt(p)<0)*2^ADC_bit,ADC_bit);
    for q=1:ADC_bit  % 12位,依次判断这12位的数值
        if B_s(q)=='1'
            data=1;
        else
            data=0;
        end
        fprintf(fid,'%d',data);
    end
    
    %  下面if语句的目的
    %  每行数字后面用逗号(,),最后一行数字结束用分号(;)
    if (p<L)
        fprintf(fid,',\r\n'); 
    else
        fprintf(fid,';\r\n');    % 分号(;)  结束标志位
    end
   
end
fclose(fid);

2、将coe文件导入到ROM IP核中
如何MATLAB生成的数据导入到FPGA,ROM IP实现 具体见该博客的2.1节

2.2 生成希尔伯特滤波器IP核的系数文件

需要注意的是,matlab生成的系数文件有一定的要求。必须保证相邻非零系数之间有一个0。

2.2.1 生成hilbert滤波器的系数,即生成系数coe文件

1、打开MATLAB的FDATOOL,设置好参数,并生成滤波器。如下图所示

在这里插入图片描述

2、导出滤波器系数,用数组h_hilbert表示。并在MATLAB中,将系数生成coe文件,实现代码如下:

close all;
clear all;
clc;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%           参数定义
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Quantify_bit=16;  % 希尔伯特滤波器量化位数 16位

fc=10e6;          % 信号频率
fs=65e6;          % 采样频率


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%            希尔伯特滤波器
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%  50阶
h_hilbert=[-0.00590097650222754,9.43634831392954e-16,-0.00592861323210342,-2.35672047624096e-16,-0.00882355094551652,1.88156326605263e-18,-0.0125967335950592,-8.81824807467578e-16,-0.0174619206426258,1.47113177594992e-15,-0.0237310276515661,-5.39946714016346e-16,-0.0318877221102664,2.65287762614106e-16,-0.0427583109535232,-5.89104004757738e-18,-0.0578928531993323,3.13510365619452e-16,-0.0806543322511701,-4.84766911383691e-16,-0.119801339972733,1.88465096830876e-16,-0.207626768075381,-1.51969570132042e-16,-0.635083803394948,0,0.635083803394948,1.51969570132042e-16,0.207626768075381,-1.88465096830876e-16,0.119801339972733,4.84766911383691e-16,0.0806543322511701,-3.13510365619452e-16,0.0578928531993323,5.89104004757738e-18,0.0427583109535232,-2.65287762614106e-16,0.0318877221102664,5.39946714016346e-16,0.0237310276515661,-1.47113177594992e-15,0.0174619206426258,8.81824807467578e-16,0.0125967335950592,-1.88156326605263e-18,0.00882355094551652,2.35672047624096e-16,0.00592861323210342,-9.43634831392954e-16,0.00590097650222754];

L=length(h_hilbert);



%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%            MATLAB生成coe文件
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%.coe文件中
% 第一行为定义数据格式, 2代表 ROM 的数据格式为二进制。
% 从第 3 行开始yong到第最后一行,是这个  L(数据长度为1024* ADC_bit(16bit) 大小 ROM 的初始化数据。
% 第一行到倒数第二行的数字后面用逗号,最后一行数字结束用分号。

yt=round(h_hilbert*(2^(Quantify_bit-1)-1));     % 12bit量化


fid=fopen('fir_hilbert_50order.coe','w');  % w表示write
fprintf(fid,'Radix = 10;\r\n'); % 10进制
fprintf(fid,'coefdata = \r\n');
for p=1:L

    fprintf(fid,'%d',yt(p));  % 写入数据
    

    %  下面if语句的目的
    %  每行数字后面用逗号(,),最后一行数字结束用分号(;)
    if (p<L)
        fprintf(fid,' \r\n'); 
    else
        fprintf(fid,';\r\n');    % 分号(;)  结束标志位
    end
   
end
fclose(fid);

AM=yt./h_hilbert;
% plot(AM);
plot( AM );


3、打开coe文件,观察系数规律。可以看出,0在每相邻的系数之间。
在这里插入图片描述

4、根据Xilinx的pg149文档的图3-22,可以看出,希尔伯特滤波器的设计是正确的。
在这里插入图片描述

2.2.2 调用FIR IP核

1、在ip目录搜索FIR
2、设置FIR滤波器参数,设置如下
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
注意点:在FIR IP的implementation一栏,coefficient Width=16,如上图所示。这个值是根据在生成希尔伯特滤波器的系数的coe文件时,有一个参数,即希尔伯特滤波器量化位数Quantify_bit。该值在MATLAB仿真中设置的是16,所以coefficient Width=16。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2.3 顶层模块

2.3.1 新建源文件,编写源文件

`timescale 1ns / 1ps
/*  实现流程:
   1、MATLAB产生希尔伯特滤波器的输入数据(ROM IP);
   2、将输入数据变成复信号,输出数据的实部和虚部(FIR IP)。

*/
module top(
    input sys_clk,  //50MHz时钟
    input rst_n     //复位,低电平有效
    );

  
/* 
     模块功能:利用ROM IP产生输入信号
*/       
wire [11:0] rom_data1; //ROM读出数据
reg   [9:0] rom_addr1; //ROM输入地址
//产生ROM地址读取数据
always @ (posedge sys_clk or negedge rst_n)
   begin
       if(!rst_n)
           rom_addr1 <= 10'd0;
       else
           rom_addr1 <= rom_addr1+1'b1;
 end
   //实例化ROM      
rom_ip rom_ip_inst (
     .clka(sys_clk),    // input wire clka
     .addra(rom_addr1),  // input wire [9 : 0] addra
     .douta(rom_data1)   // output wire [11 : 0] douta
 );



/* 
    模块功能:希尔伯特变换
*/ 
wire [11:0] real_data1;
wire [11:0] imag_data1;

v_hilbert v_hilbert_inat(
   .sys_clk   (sys_clk   )  ,
   .rom_data1 (rom_data1 )  ,
   .real_data1(real_data1)  ,
   .imag_data1(imag_data1)
);


/* 
    模块功能:ila波形观测
*/  
ila_0 ila_0_inst (
	.clk(sys_clk), // input wire clk


	.probe0(rom_addr1), // input wire [9:0]  probe0  
	.probe1(rom_data1), // input wire [11:0]  probe1 
	.probe2(real_data1), // input wire [11:0]  probe2 
	.probe3(imag_data1) // input wire [11:0]  probe3
);          

endmodule

2.3.2 编写v_hilbert源文件

`timescale 1ns / 1ps


module v_hilbert(
    input           sys_clk     ,//input
    input  [11:0]   rom_data1   ,
    
    output [11:0]   real_data1  ,//output
    output [11:0]   imag_data1
);
 
// 在FIR IP的implementation一栏,coefficient Width=16,
// 这个值是根据在生成希尔伯特滤波器的系数的coe文件时,
// 有一个参数,即希尔伯特滤波器量化位数Quantify_bit。
// 该值在MATLAB仿真中设置的是16,所以coefficient Width=16。
// 所以滤波器的输入值dataInputTemp1的位宽也为16,
wire [16-1:0]   dataInputTemp1;
assign dataInputTemp1 = {rom_data1[11],rom_data1[11],rom_data1[11],rom_data1[11], rom_data1};//将12位扩展为16位           


wire m_axis_data_tvalid;
wire [47:0] m_axis_data_tdata1;
fir_hilbert fir_hilbert_inst (
    .aclk               (sys_clk            ),    // input wire aclk
    .s_axis_data_tvalid (1                  ),   // input wire s_axis_data_tvalid
    .s_axis_data_tready (                   ),   // output wire s_axis_data_tready
    .s_axis_data_tdata  (dataInputTemp1     ),   // input wire [15 : 0] s_axis_data_tdata
    .m_axis_data_tvalid (m_axis_data_tvalid ),   // output wire m_axis_data_tvalid
    .m_axis_data_tdata  (m_axis_data_tdata1 )    // output wire [47 : 0] m_axis_data_tdata
);



//assign real_data =  m_axis_data_tdata[15:0];
//assign imag_data =  m_axis_data_tdata[46:31];

assign real_data1 =  m_axis_data_tdata1[11:0];
assign imag_data1 =  m_axis_data_tdata1[42:31]; 
    
   
endmodule

2.3.3 新建约束文件,编写约束文件

############## clock and reset define##################
create_clock -period 20 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports {sys_clk}]
set_property PACKAGE_PIN U18 [get_ports {sys_clk}]
set_property IOSTANDARD LVCMOS33 [get_ports {rst_n}]
set_property PACKAGE_PIN N15 [get_ports {rst_n}]

2.3.4 结构示意图

在这里插入图片描述

3 ILA结果

1、设置触发条件
2、结果
在这里插入图片描述

可以看出,希尔伯特变换后的实部和原信号一样;虚部与原信号相差90度。说明希尔伯特变换成功。

4 完成工程文件链接

完整工程文件

  • 15
    点赞
  • 79
    收藏
    觉得还不错? 一键收藏
  • 21
    评论
评论 21
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值