天天看點

Verilog上機實驗題目3:FIR濾波器FIR濾波器的設計

相關文章:

[Verilog上機實驗題目1:8位數字顯示的簡易頻率計]

[Verilog上機實驗題目2:11位巴克碼序列峰值檢測器]

[Verilog上機實驗題目3:FIR濾波器]

[Verilog上機實驗題目4:哈夫曼編碼器]

FIR濾波器的設計

 濾波器就是對特定的頻率或者特定頻率以外的頻率進行消除的電路,被廣泛應用于通信系統和信号處理系統中。從功能角度,數字濾波器對輸入離散信号的數字代碼進行運算處理,以達到濾除頻帶外信号的目的。

有限沖擊響應(FIR)濾波器就是一種常用的數字濾波器,采用對已輸入樣值的權重形成它的輸出。對于輸入序列X[n]的FIR濾波器可用下圖所示的結構示意圖來表示,其中X[n]是輸入資料流。各級的輸入連接配接和輸出連接配接被稱為抽頭,系數(b0,b1...)被稱為抽頭系數。一個M階的FIR濾波器将會有M+1個抽頭。通過移位寄存器用每個時鐘邊沿處 的資料流采樣值乘以抽頭系數,并将它們加起來形成輸出。

Verilog上機實驗題目3:FIR濾波器FIR濾波器的設計

FIR濾波器電路有兩個主要功能子產品:移位寄存器組子產品Shift_reg用于儲存串行進入濾波器的資料;乘加計算子產品Caculater用于進行FIR計算。

頂層代碼子產品

module FIR(
	input clk,rst,
	input [3:0] Data_in,
	output[9:0] Data_out
 );
// 聲明抽頭類型為wire
	wire[3:0] 	samples_0, 	samples_1, 	samples_2, 	samples_3, 	samples_4, 	samples_5, 	samples_6, 	samples_7, 	samples_8; 
// 移位寄存器組子產品執行個體化
	shift_reg U1(.Data_in(Data_in),.clk(clk),.rst(rst), 	.samples_0(samples_0), 	.samples_1(samples_1), 	.samples_2(samples_2), 	.samples_3(samples_3), 	.samples_4(samples_4), 	.samples_5(samples_5), 	.samples_6(samples_6), 	.samples_7(samples_7), 	.samples_8(samples_8)); 
// 乘加計算子產品執行個體化
	caculator U2(.Data_out(Data_out), 	.samples_0(samples_0), 	.samples_1(samples_1), 	.samples_2(samples_2), 	.samples_3(samples_3), 	.samples_4(samples_4), 	.samples_5(samples_5), 	.samples_6(samples_6), 	.samples_7(samples_7), 	.samples_8(samples_8));  
endmodule  
           

shift_reg子產品用于存儲輸入的資料流,本例中存儲8個4位寬輸入資料信号,也作為caculator子產品的輸入。

移位寄存器shift_reg子產品

module shift_reg( 	 input clk,rst, 	 input[3:0] Data_in, 	 output reg[3:0] 	 samples_0, 	samples_1, 	samples_2, 	samples_3, 	samples_4, 	samples_5, 	 samples_6, 	samples_7, 	samples_8  );  
 // 初始化清零,将資料一位一位移進,進行計算
 [email protected](posedge clk or negedge rst)
	 begin
		 if(!rst)
			 begin
				samples_0<=4'b0;
				samples_1<=4'b0;
				samples_2<=4'b0;
				samples_3<=4'b0;
				samples_4<=4'b0;
				samples_5<=4'b0;
				samples_6<=4'b0;
				samples_7<=4'b0;
				samples_8<=4'b0;
			 end
		 else 
			begin
				samples_0<=Data_in;
				samples_1<=samples_0;
				samples_2<=samples_1;
				samples_3<=samples_2;
				samples_4<=samples_3;
				samples_5<=samples_4;
				samples_6<=samples_5;
				samples_7<=samples_6;
				samples_8<=samples_7;
			end
	 end
 endmodule
           

caculator子產品用于進行8輸入信号與抽頭系數的乘法和累加,并産生濾波後的信号data_out,抽頭系數具有對稱性,本例直接給出。

caculator子產品

module caculator(
	 input [3:0] 	samples_0, 	samples_1, 	samples_2, 	samples_3, 	samples_4, 	samples_5, 	samples_6, 	samples_7, 	samples_8, 	 
	 output [9:0] Data_out
);
	 wire[3:0] 	 out_t_1, 	 out_t_2, 	 out_t_3, 	 out_t_4;
 	 wire[7:0] 	 out1, 	 out2, 	 out3, 	 out4, 	 out5;
 // 将相同系數的2個輸入信号先相加指派給out_t
	 assign out_t_1 = samples_0 + samples_8;
	 assign out_t_2 = samples_1 + samples_7;
	 assign out_t_3 = samples_2 + samples_6;
	 assign out_t_4 = samples_3 + samples_5;
// 定義抽頭系數為參數COEF
	parameter COEF1 = 4'b0010;
	parameter COEF2 = 4'b0011;
	parameter COEF3 = 4'b0110;
	parameter COEF4 = 4'b1010;
	parameter COEF5 = 4'b1100;
// 加法樹乘法器執行個體   
	 mul_addtree U1(.mul_a(COEF1),.mul_b(out_t_1),.mul_out(out1));
	 mul_addtree U2(.mul_a(COEF2),.mul_b(out_t_2),.mul_out(out2));
	 mul_addtree U3(.mul_a(COEF3),.mul_b(out_t_3),.mul_out(out3));
	 mul_addtree U4(.mul_a(COEF4),.mul_b(out_t_4),.mul_out(out4));
	 mul_addtree U5(.mul_a(COEF5),.mul_b(samples_4),.mul_out(out5));
// 将所有的out加起來組成輸出信号
	assign Data_out = out1 +   out2 + out3 + out4 + out5;
endmodule
           

 加法樹乘法器子產品

// 加法樹乘法器子產品   将out_t與對應的抽頭系數相乘指派給out
module mul_addtree(
	input [3:0]mul_a,mul_b,
	output [7:0] mul_out
);
	wire[7:0]stored0, stored1,stored2,stored3;
	wire[7:0] add01,add23;
	
	assign stored0 = mul_b[0] ? {4'b0,mul_a} : 8'b0;
	assign stored1 = mul_b[1] ? {3'b0,mul_a,1'b0} : 8'b0;
	assign stored2 = mul_b[2] ? {2'b0,mul_a,2'b0} : 8'b0;
	assign stored3 = mul_b[3] ? {1'b0,mul_a,3'b0} : 8'b0;
	
	assign add01 = stored0 + stored1;
	assign add23 = stored2 + stored3;
// 分成2級的原因是為了加快硬體運作速度
	assign mul_out = add01 + add23;
endmodule
           

測試代碼如下

// 測試代碼  16MHz周期是1/16M=0.0625us微秒=62.5ns納秒,測試時間基準 1ns/10ps
 `timescale 1ns/10ps;
module 	FIR_tb;
	reg clk,rst;
	reg[3:0] Data_in;
	wire[9:0] Data_out;
	initial
		begin
			clk = 'b0;
			Data_in = 'b0;
			forever
				begin
					#31.25 clk <= ~clk ;	//時鐘周期62.5ns
					#31.25 Data_in <= Data_in + 1'b1 ;	//斜坡波形
				end
		end
	
	initial
		begin
			rst = 1'b0;
			#150 rst = 1'b1;	//異步複位信号,一般等待2到3個周期再複位
		end
	
// FIR濾波器執行個體
FIR v1(.clk(clk),.rst(rst),.Data_in(Data_in),.Data_out(Data_out));
endmodule
           

仿真結果如下圖所示,輸入信号為斜坡信号,輸出信号為經過FIR濾波器後的信号。

Verilog上機實驗題目3:FIR濾波器FIR濾波器的設計
Verilog上機實驗題目3:FIR濾波器FIR濾波器的設計

繼續閱讀