7.3 Verilog Serial FIR Filter Design
Category Verilog Tutorial
Serial FIR Filter Design
Design Description
The design parameters remain unchanged, consistent with the parameters of the parallel FIR filter. That is, the input frequency is a mixed signal of sine waves at 7.5 MHz and 250 KHz. After passing through the FIR filter, the high-frequency signal at 7.5MHz is filtered out, leaving only the 250KHz signal.
Input Frequencies: 7.5MHz and 250KHz
Sampling Frequency: 50MHz
Stop Band: 1MHz-6MHz
Order: 15 (N=15)
Serial design means that within 16 clock cycles, 16 delayed data points are sequentially multiplied and added in turn, and then the filtered value is output under the clock drive. Considering the symmetry of the FIR filter coefficients, the period for calculating a filter output value can be reduced to 8. In the serial design, only one multiplication operation is performed each cycle, so only one multiplier is needed in the design. At this time, data needs to be effectively input once every 8 clock cycles, but to ensure the correctness of the output signal frequency, the working clock needs to be 8 times the sampling frequency, that is, 400MHz. The advantage of this method is low resource consumption, but it requires a high operating frequency, and data cannot be continuously output.
Serial Design
The multiplier module code used in the design can refer to the multiplier in the previous pipeline design.
For fast simulation, the multiplication can also be directly completed with the multiplication sign *
. A macro definition SAFE_DESIGN is added to the design to choose which multiplier to use.
FIR filter coefficients can be generated by matlab, see the appendix for details.
Example
/**********************************************************
>> 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, // System working clock, 400MHz
input en , // Input data valid signal
input [11:0] xin, // Input mixed frequency signal data
output valid, // Output data valid signal
output [28:0] yout // Output data
);
//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 coefficient
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) Input data shift part
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 ; //Count for 8 cycles
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
If (!rstn) begin
yout_r <= 'b0;
end
else if (valid_r) begin
yout_r <= sum;
end
end
assign yout = yout_r;
//(5) Output data valid delay, that is, the first 15 filtered values of the filtered data are discarded
reg [4:0] cnt_valid;
always @(posedge clk or negedge rstn) begin
if (!rstn) begin
cnt_valid <= 'b0;
end
else if (valid_r && cnt_valid != 5'd16) begin
cnt_valid <= cnt_valid + 1'b1;
end
end
assign valid = (cnt_valid == 5'd16) & valid_r;
endmodule
testbench
The testbench is written as follows, with the main function being to continuously input a mixed signal data of 250KHz and 7.5MHz sine waves without interruption. The mixed signal data to be input can also be generated by MATLAB, see the appendix for details.
In which, the operating frequency is 400MHz, but both the input data and the input data valid signal should maintain a frequency of 50MHz.
Example
module test;
//input
reg clk;
reg rst_n;
reg en;
reg [11:0] xin;
//output
wire [28:0] yout;
wire valid;
parameter SIMU_CYCLE = 64'd1000;
parameter SIN_DATA_NUM = 200;
//=====================================
// 8*50MHz clk generating
localparam TCLK_HALF = (10_000 >>3);
initial begin
clk = 1'b0;
forever begin
# TCLK_HALF clk = ~clk;
end
end
//============================
// reset and finish
initial begin
rst_n = 1'b0;
# 30 rst_n = 1'b1;
# (TCLK_HALF * 2 * 8 * SIMU_CYCLE);
$finish;
end
//=======================================
// read cos data into register
reg [11:0] stimulus [0: SIN_DATA_NUM-1];
integer i;
initial begin
$readmemh("../tb/cosx0p25m7p5m12bit.txt", stimulus);
en = 0;
i = 0;
xin = 0;
# 200;
forever begin
repeat(7) @(negedge clk); //Leave 7 cycles, give data on the 8th cycle
en = 1;
xin = stimulus[i];
@(negedge clk);
en = 0; //The input data valid signal only needs to last for one cycle
if (i == SIN_DATA_NUM-1) i = 0;
else i = i + 1;
end
end
fir_serial_low u_fir_serial(
.clk (clk),
.rstn (rst_n),
.en (en),
.xin (xin),
.valid (valid),
.yout (yout));
endmodule
Simulation Results
From the simulation results below, it can be seen that after the FIR filter, the signal only has one low-frequency signal (250KHz), and the high-frequency signal (7.5MHz) is filtered out. To make the waveform more aesthetically pleasing, the filtered data after 16 are taken as the valid output.
After local amplification of the waveform, it is shown in the following figure. At this time, the input data valid signal en and the output data valid signal valid are pulse signals with the same period (50MHz), not continuously valid. However, the working clock is 400MHz, so the output will also appear as a 250KHz frequency sine wave signal under a 50MHz sampling frequency.
Appendix: MATLAB Usage (Consistent with "Parallel FIR Filter Design")
Generate FIR Filter Coefficients
Open MATLAB
7.3 Serial FIR Filter Design in Verilog