基于FPGA的FIR complier IP核 学习资料(一)

第一次写博客,想想还有点儿小激动呢!哈哈哈!下面步入正题!

由于项目的需要,必须在进行FFT变换之前进行数字下变频处理,此时用到了滤波器(我用的是低通滤波器)。关于滤波器的原理什么的这里不做讨论。本来还想着自己写一个滤波器,结果发现人家都已经给你了IP核,你只需要配置一下参数就能够直接拿来用了,又何必再去花时间自己写呢。

滤波系数集

进行IP核配置的时候关键是滤波系数集,我的系数集是用matlab得到的(补写了一篇关于Kaiser窗口FIR滤波器设计参数估算的文档,可以点击查看)。程序如下:

M=39;wn=0.45;
filt1  = fir1(M, wn, 'low', kaiser(M+1,4.538), 'scale');
filt=round(1000.*filt1);

得出的系数是:

1    1    -1    -3    0    6    2    -9    -7    12    15    -13    -29    9    49    5    -83    -47    179    413    413    179    -47    -83    5    49    9    -29    -13    15    12    -7    -9    2    6    0    -3    -1    1    1

以上四十个系数是分为两组的。原因如下:项目中是先将雷达接收信号分为I路(同相分量)和Q路(正交分量),然后再进行滤波。所以需要两组滤波系数,I路对应的系数集为[1,-3,6,-9,12,-13,9,5,-47,413,179,-83,49,-29,15,-7,2,0,-1,1],Q路对应的系数集为[1,-1,0,2,-7,15,-29,49,-83,179,413,-47,5,9,-13,12,-9,6,-3,1]。(至于这两组系数为什么要这么分,我还在研究中。目前来看,这么分之后,后续操作的结果和预期的是一样的,其他的分割方法得到的最终结果像屎一样)。

仿真数据的由来

另外还有一个是仿真数据的由来问题,我是先用matlab产生雷达回波的模拟信号,存储为“.coe”的二进制文件,文件内容如下所示:

MEMORY_INITIALIZATION_RADIX=2;//二进制表示
MEMORY_INITIALIZATION_VECTOR=
011111111111
011110011010
011001110110
010010101111
001001110000
............

之后就是将文件中的数据加载到rom核内,加载的方法如下所示:

 点击load init file前面的方框,打对号,然后点击browse,选择之前保存的模拟数据的coe文件。至于rom核的其他参数的设置,在第一页会让你选择native或axi4,这是两种不同标准的引脚表示,native相对axi4来说是比较老的,虽然表示不同,但是大同小异,native相对来说比较直观。还有read width、read depth,根据自己数据的位宽和数量设置就行,其他的默认就行,这里不再赘述。

下面是关于IP核的配置问题

(既然需要用到滤波器IP核,我觉得这时候对ise的操作已经熟悉,有些步骤就简要说明了)。

首先是建立工程,然后点右键点击工程,选择“new sourse”,再选择IP,名称随自己的意,然后一路点击next或者finish,到达IP核的参数配置界面(第一页):

图中1部分表示选择的输入滤波系数的方式,选择“vector”,则需要在“coefficient vector”的后面输入滤波系数;如果选择“coe file”,则需要点击“coefficient file”后面的“browse”,选择需要加载的系数文件(文件的格式需要是“.coe”)。系数文件的格式如下:

radix=10;  //表示是十进制表示法
coefdata=
1,
-3,
6,
-9,
12,
-13,
9,
5,
-47,
413,
179,
-83,
49,
-29,
15,
-7,
2,
0,
-1,
1;   //注意结尾是分号

我这里是将I路和Q路分开之后进行滤波,所以配置了两个滤波器IP核(其实可以只配置一个IP核的,这个在后面会进行说明),图中2部分也就填写了1。图中3部分是选择滤波器的类型,我这里选择的是单速率(数据输入和输出的频率是一样的)。图中4部分是选择IP核的工作频率和数据输入的频率,举例说明,当工作频率为200MHz,数据输入频率为200MHz,那么此时的工作时钟和IP核的rfd输出口的仿真波形如图所示:

图4还可以选择 “sample period”,此时需要填写“input sample period”。举例说明,如果填写为1,那么仿真波形图如上图所示,如果填写2(相当于工作时钟是数据输入时钟的二倍),那么图形就如下所示:

上方的为IP核的rfd输出口的仿真波形,下方的为工作时钟仿真波形

 点击next进入第二页,如下所示:

图中1部分选择的是脉动乘累加结构,2部分选择滤波系数非对称,3部分选择有符号数,4部分选择整型系数,5、6部分默认就行, 7部分选择有符号数据输入,8部分选择输入数据的位宽(我的是12位宽的),9部分由于没有小数,所以选择0,10部分选择输出数据的精度(我选择的是全精度,也可以选择截断,这时候可以自定义输出数据的位宽),11部分选择寄存器输出(此时相当于有一个寄存器,当rdy这个信号低电平时,输出端口的数据寄存器来,不会改变输出)。

点击next进入第三页,如下所示:

这一页,基本上都默认即可。红色框框内的引脚选择,看你自己的习惯了,我刚开始是选择了ce(使能)引脚,仿真时候出现了意想不到的结果,后面会说明。 

再点击next,出现综合信息,然后点击generate,静待IP核的生成。

程序的编写和仿真

本项目中数字下变频的整体思路是这样的:首先接受雷达回波信号以500MHz的采样率进行采样,采样精度为12位。然后进行希尔伯特变换,分为I、Q两路。由于采样率过高,数据量较大,给后期的信号处理带来很大的压力,所以还需要进行抽取,项目中用到的是2抽取。抽取之后分别对I、Q两路进行低通滤波处理。

verilog程序的顶层包括了时钟分频模块、rom数据模块、希尔伯特变换及2抽取模块、I路滤波模块、Q路滤波模块。实例化部分如下所示:

//锁相环,利用系统时钟,分频得到500MHz,250MHz,125MHz三种不同的时钟
myclk mypll(
            // Clock in ports
            .CLK_IN1_P(sys_clk_p),    // input clk_in1_p
            .CLK_IN1_N(sys_clk_n),    // input clk_in1_n
            // Clock out ports
            .CLK_OUT1(clk500),     // output clk_out1
            .CLK_OUT2(clk250),     // output clk_out2 ,用来做2抽取的
            .CLK_OUT3(clk125)     // output clk_out3 ,用来做4抽取的
            );  

//rom核的实例化,根据地址取数据
my_memory ddc2_datain_inst (
     						.clka(clk500),    // input wire clka
							.ena(rden_rom),      // input wire ena
							.addra(address),  // input wire [12 : 0] addra
							.douta(datain)  // output wire [11 : 0] douta
								  );

//将回波采样数据分为I路和Q路,并进行2抽取                                   											
ddc2_iq ddc2_iq_inst(	
                     .rst(local_rst),
				     .clk(clk500),
					 .ena(iqin_en),
					 .din(datain),
					 .outen(iqout_en),
					 .douti(i_out),
					 .doutq(q_out)
						);

//I路滤波	
my_ifir ddc2_ifir_inst (
	                    .clk(clk250), // input clk
	                    .ce(1'b1), // input ce
	                    .rfd(rfd_i), // output rfd
	                    .rdy(rdy_i), // output rdy
	                    .din(i_out), // input [11 : 0] din
	                    .dout(idataout)); // output [21 : 0] dout	

//Q路滤波	
my_qfir ddc2_qfir_inst (
	                    .clk(clk250), // input clk
	                    .ce(1'b1), // input ce
	                    .rfd(rfd_q), // output rfd
	                    .rdy(rdy_q), // output rdy
	                    .din(q_out), // input [11 : 0] din
	                    .dout(qdataout)); // output [21 : 0] dout	

仿真文件如下所示:

module my_ddc_testbench;

	// Inputs
	reg rst;
	reg sys_clk_p;
	reg sys_clk_n;

	// Outputs
	wire clk500;
	wire clk250;
	wire clk125;
	wire outena;
	wire [21:0] idataout;
	wire [21:0] qdataout;

	// Instantiate the Unit Under Test (UUT)
	DDC2 uut (
		.rst(rst), 
		.sys_clk_p(sys_clk_p), 
		.sys_clk_n(sys_clk_n), 
		.clk500(clk500), 
		.clk250(clk250), 
		.clk125(clk125), 
		.outena(outena), 
		.idataout(idataout), 
		.qdataout(qdataout)
	);

	initial begin
		// Initialize Inputs
		rst = 0;
		sys_clk_p = 0;
		sys_clk_n = 1;

		// Wait 100 ns for global reset to finish
		#400;
		rst=1;
        
		// Add stimulus here

	end
always #5  sys_clk_p=~sys_clk_p; 
always #5  sys_clk_n=~sys_clk_n;     
endmodule

仿真波形如下图所示:

i_out和q_out是输入FIR IP核的数据,idataout和qdataout是经过滤波器IP核输出的数据,从输入到输出中间差了20+个周期,这个从之前的第四页的综合报告界面能看到。如下所示:

将idataout和qdataout的数据与用matlab仿真的数据进行了对比,如下:

matlab仿真的Q路滤波后的输出数据
matlab仿真的I路滤波后的输出数据
FPGA的FIR IP核输出的I、Q两路的数据

可以看出利用FPGA进行滤波是可行的!然而,当我拉到仿真波形图的最后的时候,发现多出一些不需要的数据,如下图:

红色框内的数据是多余的,为什么呢?!因为我始终把ce使能(由上面的实例化代码ce=1'b1),也就是当输入的数据变为0之后,IP核还在运行计算,还有数据输出,而这些输出是多余的,这就是编程时候的时序设计问题了,怪自己!啪啪啪!

我也是刚开始学,还有很多不懂的地方,写的东西肯定有很多不足的地方,希望大佬们能够指正,不胜感激!

未完待续。。。。。。

  • 9
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。 经导师精心指导并认可、获 98 分的毕业设计项目!【项目资源】:微信小程序。【项目说明】:聚焦计算机相关专业毕设及实战操练,可作课程设计与期末大作业,含全部源码,能直用于毕设,经严格调试,运行有保障!【项目服务】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。
对于基于FPGA的高通滤波器,可以使用FIR(Finite Impulse Response)IP核来实现。FIR滤波器是一种线性时不变滤波器,通过对输入信号的离散样本进行加权求和来实现滤波效果。在FPGA中,可以通过使用FIR IP核来快速实现高通滤波器。 FIR IP核通常提供了一些参数,例如滤波器的阶数、截止频率以及滤波器系数等。根据所需的滤波器规格,可以选择适当的参数值。一旦设置好参数,可以将FIR IP核实例化到FPGA设计中,并将输入信号和时钟连接到该IP核。 在FPGA中,FIR IP核通常采用流水线结构,以提高处理速度。输入信号经过滤波器系数的乘法和累加操作,得到输出信号。由于FPGA的并行计算能力,可以同时处理多个输入样本,从而实现高效的滤波操作。 使用FIR IP核进行高通滤波的具体步骤如下: 1. 根据滤波器要求设置FIR IP核的参数,包括阶数、截止频率等。 2. 实例化FIR IP核并将其连接到FPGA设计中。 3. 将输入信号和时钟连接到FIR IP核。 4. 根据需要,可以对输入信号进行预处理或后处理。 5. 在FPGA中生成时钟信号以驱动FIR IP核的工作。 6. 获取FIR IP核的输出信号,即滤波后的高通信号。 需要注意的是,具体的实现细节可能会根据所选用的FPGAFIR IP核的供应商而有所不同。因此,在使用FIR IP核进行高通滤波之前,建议参考相关文档和资源,以确保正确配置和使用IP核
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值