Verilog实现并行FIR滤波器

大部分沿袭某个大佬的代码,也是学到了,没有语法错,写tb文件了,在后面的文章里,写得我头晕眼花的了

/*
输入频率:    7.5MHz 和 250KHz
采样频率:    50MHz
阻带:           1MHz ~ 6MHz
阶数:           15(N-1=15)
*/

module	RIF_filter(
	input					RSTN,									//复位信号,低有效
	input					CLK,									//时钟信号,即为采样频率
	input					EN,									//输入信号有效
	input	[11:0]		DATA_I,								//12位输入信号
	
	output				VAL,									//输出信号有效
	output 	 [28:0]  DATA_O);								//29位输出信号								
	
	
	reg [3:0]			EN_reg;
	
	always @(posedge CLK or negedge RSTN) begin
		if(!RSTN) begin
			EN_reg[3:0] <= 'b0;								// 复位时清零输入信号有效性寄存器
		end else begin
			EN_reg[3:0] <= {EN_reg[2:0],EN};				// 更新输入信号有效性寄存器
		end
	end
	
	reg [11:0] 			trans_reg [15:0];
	reg[3:0]			i;
	always @(posedge CLK or negedge RSTN) begin
		if(!RSTN) begin
			for(i = 0;i<15;i=i+1) begin
				trans_reg [i] <= 'b0;
			end
		end else if(EN) begin									// 迭代变量
		   for(i = 0;i<15;i=i+1) begin
				trans_reg[i+1] <= trans_reg [i];
			end
			trans_reg [0] <= DATA_I;							//更新trans数据
						
			
		end
	end
	
	reg [12:0]			add_reg [7:0];
	always @(posedge CLK or negedge RSTN) begin
		if(!RSTN) begin
			for(i=0;i<8;i=i+1) begin
				add_reg [i] <= 'b0;
			end
		end else if(EN_reg[0]) begin												// 更新加法运算的中间结果,使用上个周期的输入信号历史状态
			for(i=0;i<8;i=i+1) begin
				add_reg [i] <= trans_reg [i] + trans_reg [15-i];		 //这里使用的是上个周期的trans数据
			end
		end
	end
	
	// 滤波器系数,已经过一定倍数的放大
	wire        [11:0]   coe[7:0] ;
   assign coe[0]        = 12'd11 ;
   assign coe[1]        = 12'd31 ;
   assign coe[2]        = 12'd63 ;
   assign coe[3]        = 12'd104 ;
   assign coe[4]        = 12'd152 ;
   assign coe[5]        = 12'd198 ;
   assign coe[6]        = 12'd235 ;
   assign coe[7]        = 12'd255 ;
	
	reg [24:0]   			mout[7:0];
	
	always @(posedge CLK or negedge RSTN) begin
		if(!RSTN) begin
			for(i=0;i<8;i=i+1) begin
				mout [i] <= 'b0;
			end
		end else if(EN_reg[1]) begin						// 更新乘法运算的中间结果,使用上个周期的加法运算的中间结果和系数
			for(i=0;i<8;i=i+1) begin
			mout [i] <= add_reg [i] * coe [i];		 //这里使用的是上个周期的add_reg数据
			end
		end
	end

	
	wire mult_rdy = EN_reg[2];
	reg  VAL_r;
	always @(posedge CLK or negedge RSTN) begin
        if (!RSTN) begin
            VAL_r <= 'b0 ;
        end
        else begin
            VAL_r  <= mult_rdy ;						// 更新输出信号有效性
        end
   end
	
	
	
	 //加法运算时,分多个周期进行流水,优化时序,一次直接相加在时序上有危险
	reg        [28:0]    sum1 ;
	reg        [28:0]    sum2 ;
	reg        [28:0]    data_reg ;
	always @(posedge CLK or negedge RSTN) begin
		if (!RSTN) begin
			sum1   <= 29'd0 ;
			sum2   <= 29'd0 ;
			data_reg <= 29'd0 ;
      end
        else if(VAL_r) begin
            sum1   <= mout[0] + mout[1] + mout[2] + mout[3] ;
            sum2   <= mout[4] + mout[5] + mout[6] + mout[7] ;
            data_reg <= sum1 + sum2 ;
        end
    end
	 assign DATA_O = data_reg;
	 assign VAL = VAL_r;
	 
	
endmodule	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值