相關文章:
[Verilog上機實驗題目1:8位數字顯示的簡易頻率計]
[Verilog上機實驗題目2:11位巴克碼序列峰值檢測器]
[Verilog上機實驗題目3:FIR濾波器]
[Verilog上機實驗題目4:哈夫曼編碼器]
FIR濾波器的設計
濾波器就是對特定的頻率或者特定頻率以外的頻率進行消除的電路,被廣泛應用于通信系統和信号處理系統中。從功能角度,數字濾波器對輸入離散信号的數字代碼進行運算處理,以達到濾除頻帶外信号的目的。
有限沖擊響應(FIR)濾波器就是一種常用的數字濾波器,采用對已輸入樣值的權重形成它的輸出。對于輸入序列X[n]的FIR濾波器可用下圖所示的結構示意圖來表示,其中X[n]是輸入資料流。各級的輸入連接配接和輸出連接配接被稱為抽頭,系數(b0,b1...)被稱為抽頭系數。一個M階的FIR濾波器将會有M+1個抽頭。通過移位寄存器用每個時鐘邊沿處 的資料流采樣值乘以抽頭系數,并将它們加起來形成輸出。
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濾波器後的信号。