mohamis
New Contributor
3 years agoWhy do I get the following relsult in my FIR filter output
Hello,
I want to simulate my FIR filter in Verilog. But I get the wrong result. For example, when simulating a complete sinusoidal wave as input, I get the following result:
Here is my code in Verilog:
`timescale 1ms / 1ps // Module Name: FIR_Filter module FIR_Filter(clk, reset, my_data_in, my_data_out); parameter N = 8; input clk, reset; input signed [N-1:0] my_data_in; output reg signed [N-1:0] my_data_out; // coefficients defination // Moving Average Filter, 3rd order //wire [7:0] b0 = 8'b0_0001010; //wire [7:0] b1 = 8'b0_0010000; //wire [7:0] b2 = 8'b0_0101000; //wire [7:0] b3 = 8'b0_1000000; //wire [7:0] b4 = 8'b0_0101000; //wire [7:0] b5 = 8'b0_0010000; //wire [7:0] b6 = 8'b0_0001010; wire signed [N-1:0] x1, x2, x3, x4, x5, x6; // Create delays i.e x[n-1], x[n-2], .. x[n-N] // Instantiate D Flip Flops DFF DFF0(clk, reset, my_data_in, x1); // x[n-1] DFF DFF1(clk, reset, x1, x2); // x[x[n-2]] DFF DFF2(clk, reset, x2, x3); // x[n-3] DFF DFF3(clk, reset, x3, x4); DFF DFF4(clk, reset, x4, x5); DFF DFF5(clk, reset, x5, x6); // Multitiplication wire signed [N-1:0] Multi0, Multi1, Multi2, Multi3, Multi4, Multi5, Multi6; assign Multi0 = (my_data_in>>4)+(my_data_in>>6); assign Multi1 = (my_data_in>>3); assign Multi2 = (my_data_in>>4)+(my_data_in>>2); assign Multi3 = (my_data_in>>1); assign Multi4 = (my_data_in>>4)+(my_data_in>>2); assign Multi5 = (my_data_in>>3); assign Multi6 = (my_data_in>>4)+(my_data_in>>6); //assign Multi0 = my_data_in * b0; //assign Multi1 = x1 * b1; //assign Multi2 = x2 * b2; //assign Multi3 = x3 * b3; //assign Multi4 = x4 * b4; //assign Multi5 = x5 * b5; ///assign Multi6 = x6 * b6; // Addition operation wire signed [N-1:0] Add_final_value; assign Add_final_value = Multi0 + Multi1 + Multi2 + Multi3 + Multi4 + Multi5 + Multi6; // Final calculation to output always@(posedge clk) my_data_out <= Add_final_value; endmodule module DFF(clk, reset, my_data_in, data_delayed); parameter N = 8; input clk, reset; input [N-1:0] my_data_in; output reg [N-1:0] data_delayed; always@(posedge clk) begin if (reset) data_delayed <= 0; else data_delayed <= my_data_in; end endmodule
Input data is in 2's complement format, between -64 and 63. So, despite the fact that FIR filter coefficients' sum is larger than one, we are sure that the output won't overflow. but as you can see in the image, overflow has been occurred in our output. I do not know what the reason is. one important point to note is that our output is always positive.
- You are using logical right shift for signed variables which corrupts the sign bit. Try arithmetic shift.