串行 FIR 滤波器设计
◆设计说明
设计参数不变,与并行 FIR 滤波器参数一致。即,输入频率为 7.5 MHz 和 250 KHz 的正弦波混合信号,经过 FIR 滤波器后,高频信号 7.5MHz 被滤除,只保留 250KMHz 的信号。
输入频率: 7.5MHz 和 250KHz
采样频率: 50MHz
阻带: 1MHz-6MHz
阶数: 15 (N=15)
串行设计,就是在 16 个时钟周期内对 16 个延时数据分时依次进行乘法、加法运算,然后在时钟驱动下输出滤波值。考虑到 FIR 滤波器系数的对称性,计算一个滤波输出值的周期可以减少到 8 个。串行设计时每个周期只进行一次乘法运算,所以设计中只需一个乘法器即可。此时数据需要每 8 个时钟周期有效输入一次,但是为了保证输出信号频率的正确性,工作时钟需要为采样频率的 8 倍,即 400MHz。这种方法的优点是资源耗费少,但是工作频率要求高,数据不能持续输出。
◆串行设计
设计中使用到的乘法器模块代码,可参考之前流水线式设计的乘法器。
为方便快速仿真,也可以直接使用乘号 “*” 完成乘法运算,设计中加入宏定义 SAFE_DESIGN 来选择使用哪种乘法器。
FIR 滤波器系数可由 matlab 生成,具体见附录。
/**********************************************************
>> Description : fir study with serial tech
>> V190403 : Fs:50Mhz, fstop:1-6Mhz, order:16, sys clk:400MHz
***********************************************************/
`define SAFE_DESIGN
module fir_serial_low(
input rstn,
input clk, // 系统工作时钟,400MHz
input en , // 输入数据有效信号
input [11:0] xin, // 输入混合频率的信号数据
output valid, // 输出数据有效信号
output [28:0] yout // 输出数据
);
//delay of input data enable
reg [11:0] en_r ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
en_r[11:0] <= 'b0 ;
end
else begin
en_r[11:0] <= {en_r[10:0], en} ;
end
end
//fir coeficient
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 ;
//(1) 输入数据移位部分
reg [2:0] cnt ;
integer i, j ;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
cnt <= 3'b0 ;
end
else if (en || cnt != 0) begin
cnt <= cnt + 1'b1 ; //8个周期计数
end
end
reg [11:0] xin_reg[15:0];
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
for (i=0; i< 16; i=i+1) begin
xin_reg[i] <= 12'b0;
end
end
else if (cnt == 3'd0 && en) begin //每8个周期读入一次有效数据
xin_reg[0] <= xin ;
for (j=0; j< 15; j=j+1) begin
xin_reg[j+1] <= xin_reg[j] ; // 数据移位
end
end
end
//(2) 系数对称,16个移位寄存器数据进行首位相加
reg [11:0] add_a, add_b ;
reg [11:0] coe_s ;
wire [12:0] add_s ;
wire [2:0] xin_index = cnt>=1