基于FPGA实现CIC升采样滤波器verilog HDL代码总结

一、概述

上文中我们总结了CIC基本原理设计,本文将基于xilinx FPGA通过verilog HDL实现CIC升采样及仿真情况总结如下,作为相关项目开发参考。

二、设计说明

系统工作时钟50M
正弦信号频率50M/16/8=0.390625MHz
正弦信号采样频率50M/16=3.125Msps,每个正弦波周期采集8个点
正弦信号升采样频率50M/2=25Msps,即8倍内插
CIC升采样滤波器实现框图及内部信号定义:
在这里插入图片描述

三、代码实现

1、顶层代码

module top(
input				wire					sclk,
input				wire					rst_n,
input				wire	[31:0]	        phase_init,
input				wire	[31:0]          freq_para,	         
output              wire	[23:0]		    dataout
);

wire [7:0] sin_data;
wire data_valib;

pro_sin pro_sin_inst(
.sclk      (sclk), //系统时钟50M
.rst_n     (rst_n),
.phase_init(phase_init),//初始相位
.freq_para (freq_para),//频率配置字
.data_v    (data_valib),
.dataout   (sin_data)
);

cic_filter cic_filter_inst(
.sclk    (sclk),    //系统频率为50M
.rst_n   (rst_n),
.datain  (sin_data),
.data_v  (data_valib),
.dataout (dataout)
);
endmodule

2、产生正弦信号代码(调用了xilinx RAM IP)

module pro_sin(
input				wire						sclk, //系统时钟50M
input				wire						rst_n,
input				wire 		[31:0]	        phase_init,//初始相位
input				wire		[31:0]          freq_para,//频率配置字
output              reg                         data_v,//输出有效标识
output			    wire		[7:0]		     dataout
);

reg  [31:0] phase;//相位累加器
wire [7:0]	addr;

parameter  DIV=16-1; //分频系数,用于产生采样频率50M/16=3.125Msps的正弦信号
reg  [5:0] div_cnt;//分频计数器
reg		   div_flag;

always@(posedge sclk or negedge rst_n)
begin
			if(rst_n==1'b0)
				div_cnt<=6'd0;
			else if(div_cnt==DIV)
				div_cnt<=6'd0;	
			else 
			    div_cnt<=div_cnt+1'b1;
end

always@(posedge sclk or negedge rst_n)
begin
			if(rst_n==1'b0)
				div_flag<=1'b0;
			else if(div_cnt==6'd0)
				div_flag<=1'b1;
			else
				div_flag<=1'b0;
end

always@(posedge sclk or negedge rst_n)
begin
			if(rst_n==1'b0)
				phase<=phase_init;
			else if(div_flag==1'b1)
				phase<=phase+freq_para;	//频率配置字由f1=M*fs/2^N计算得到M值。
end

always@(posedge sclk or negedge rst_n)
begin
			if(rst_n==1'b0)
				data_v<=1'b0;
			else
				data_v<=1'b1;
end

assign addr=phase[31:24];

blk_mem_gen_0 blk_mem_gen_0_inst (
  .clka(sclk),    // input wire clka
  .ena(1'b1),      // input wire ena
  .wea(1'b0),      // input wire [0 : 0] wea
  .addra(addr),   // input wire [7 : 0] addra
  .dina('d0),     // input wire [7 : 0] dina
  .douta(dataout)  // output wire [7 : 0] douta
);

endmodule

3、CIC升采样滤波实现代码

module cic_filter(
input					wire				sclk,    //系统频率为50M
input					wire				rst_n,   //复位信号
input					wire	[7:0]	    datain,  //DDS输入的8为正弦波信号
input					wire	            data_v,  //输入信号的有效标识
output				    wire	[23:0]      dataout  
);

parameter DIV=16-1; //分频系数,信号采样频率:50M/16=3.125Msps
parameter DIV_R=2-1;//分频系数,8倍内插后的信号采样频率:50M/2=25Msps
parameter W=24;//8倍内插后的信号位宽

reg [5:0] div_cnt;   //原采样率分频计数器
reg [4:0] div_cnt_r; //内插后采样率分频计数器
reg       div_flag;  //16倍分频标识
reg       div_flag_r;//8倍内插后的分频标识
//梳妆滤波器寄存器
reg [W-1:0]  comb1_r;
reg [W-1:0]  comb2_r;
reg [W-1:0]  comb3_r;
wire [W-1:0]  comb1_w;
wire [W-1:0]  comb2_w;
wire [W-1:0]  comb3_w;
//积分器寄存器
reg [W-1:0]  integrator1_r;
reg [W-1:0]  integrator2_r;
reg [W-1:0]  integrator3_r;
wire [W-1:0]  integrator1_w;
wire [W-1:0]  integrator2_w;
wire [W-1:0]  integrator3_w;

//对50M系统时钟进行16分频
always@(posedge sclk or negedge rst_n)
begin
		  if(rst_n==1'b0)
			  div_cnt<=6'd0;
		  else if(div_cnt==DIV)
		      div_cnt<=6'd0;
		  else
		      div_cnt<=div_cnt+1'b1;
end

always@(posedge sclk or negedge rst_n)
begin
		  if(rst_n==1'b0)
				div_flag<=1'b0;
		  else if(div_cnt==6'd0)
		  		div_flag<=1'b1;
		  else
		  		div_flag<=1'b0;
end
//对50M系统时钟进行2分频
always@(posedge sclk or negedge rst_n)
begin
		  if(rst_n==1'b0)
			    div_cnt_r<=5'd0;
		  else if(div_cnt_r==DIV_R)
		        div_cnt_r<=5'd0;
		  else
		  		div_cnt_r<=div_cnt_r+1'b1;
end

always@(posedge sclk or negedge rst_n)
begin
			if(rst_n==1'b0)
					div_flag_r<=1'b0;
			else if(div_cnt_r==5'd0)
					div_flag_r<=1'b1;
		    else
		  		    div_flag_r<=1'b0; 
end
//梳妆滤波器
assign  comb1_w={{16{datain[7]}},datain}-comb1_r;
assign  comb2_w=comb1_w-comb2_r;
assign  comb3_w=comb2_w-comb3_r;

always@(posedge sclk or negedge rst_n)
begin
			if(rst_n==1'b0)
			begin
					comb1_r<='d0;
					comb2_r<='d0;
					comb3_r<='d0;			
			end
			else if((data_v==1'b1)&&(div_flag==1'b1))
			begin
					comb1_r<={{16{datain[7]}},datain};
					comb2_r<=comb1_w;
					comb3_r<=comb2_w;
			end
			else if(data_v==1'b0)
			begin
					comb1_r<='d0;
					comb2_r<='d0;
					comb3_r<='d0;				
			end			
end
//积分器
assign  integrator1_w=comb3_w+integrator1_r;
assign  integrator2_w=integrator1_w+integrator2_r;
assign  integrator3_w=integrator2_w+integrator3_r;

always@(posedge sclk or negedge rst_n)
begin
			if(rst_n==1'b0)
			begin
					integrator1_r<='d0;
					integrator2_r<='d0;
					integrator3_r<='d0;			
			end
			else if((data_v==1'b1)&&(div_flag_r==1'b1))
			begin
					integrator1_r<=integrator1_w;
					integrator2_r<=integrator2_w;
					integrator3_r<=integrator3_w;
			end			
end
assign dataout=integrator3_w;

endmodule

四、仿真结果

在这里插入图片描述

  • 3
    点赞
  • 63
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值