Continue to Site

# Problem in implementing difference equation of Digital notch filter

Status
Not open for further replies.

##### Newbie level 4
I am trying to implement a digital notch filter in Vertex-4. I have to implement a difference equation. I am taking input from ADC which is going to filter block and the output of filter is going to DAC.

My code is given below. But its not working accurately:

Code Verilog - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: EMC Lab
//
// Create Date:    10:41:49 09/07/2015
// Design Name:
// Module Name:    dnf
// Project Name: Active Filter
// Target Devices: Xilinx 4
// Tool versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Purpose is to implement the difference equation for Digital Notch Filter
//
//      y(k) = 0.9975x(k) - 1.9911x(k-1) + 0.9975x(k-2) + 1.9911y(k-1)-0.9950y(k-2)
//
//////////////////////////////////////////////////////////////////////////////////
//module dnf(input_current, clk_in,filter_out, reset, da_out, clk_5kHz
//    );

module dnf(clk_in, reset, da_out, clk_5kHz, clk_50Hz,input_current,y_t,y_t22);
//module dnf(clk_in, reset, da_out, clk_5kHz, clk_50Hz,input_current);

// Declartion of input signals
input clk_in;                           // Input clock of FPGA
input reset;
//      input [9:0] input_current;          // Input current from wire

// Declaration of output signals

//      output [13:0] filter_out;           // Output of digital notch filter
output [13:0] da_out;               // DAC output of nothch filter
output clk_5kHz, clk_50Hz;                      // Sample clock for DAC
output [9:0] input_current;
output signed [49:0] y_t;
output signed [49:0] y_t22;

// Defining parameters for fractional coverstions of difference equation
parameter xt2con = 65372;           // 16 bit value of 0.9975
parameter xt1con = 130488;          //  16 bit value of 1.9911
parameter yt2con = 65208;           // 16 bit value of 0.9950

// Paramter definiation for the clock divdier
parameter cnt_value_5k = 2500;      //counter value where division is required
//      parameter cnt_value_50 = 250000;        //counter value where division is required for 50 Hz clock from 50MHz
parameter cnt_value_50h = 50;          //counter value where division is required for 50 Hz clock from 5kHz

// Internal variables
//      reg [15:0] xt2con = 65372;
//      reg [15:0] xt1con = 130488;     //  16 bit value of 1.9911
//      reg [15:0] yt2con = 65208;          // 16 bit value of 0.9950

reg clk_5k;                         // for 5KHz clock
reg clk_50h;                        // for 50 Hz clock
reg [15:0] cnt_5k;              // Counter for 5KHZ clock
reg [19:0] cnt_50h;             // Counter for 50Hz clock
reg [9:0] input_current;        // Analoge to Digital Output Input Current
wire[13:0] filter_out;          // Digital Output of Digital Notch Filter

wire clk_5kHz;
wire clk_50Hz;
//      wire filter_out;
//      wire da_out;

// Variable for difference Equation
reg signed [9:0] x_t1;
reg signed [9:0] x_t2;
reg signed [9:0] y_t1;
reg signed [9:0] y_t2;
reg signed [49:0] y_t;
reg signed [49:0] y_t22;
reg [13:0] dac_data;

// Declaring initial values of difference equation variables
//      initial
//      begin
//               x_t1 = 0;
//               x_t2   = 0;
//               y_t1   = 0;
//               y_t    = 0;
//               y_t2   = 0;
//      end

// Clock Generation for Sample Instant (Sawtooth Signal)
//5KHz Clock Generation from 50MHz clock

always @(posedge clk_in)
begin
if(reset)
begin
cnt_5k = 0;
clk_5k = 0;
input_current=0;                    // Sample input current in terms of counter
end
else if (cnt_5k < cnt_value_5k)
begin
cnt_5k = cnt_5k + 1;
input_current=input_current+1;// Sample input current in terms of counter
end
else if (cnt_5k == cnt_value_5k)
begin
cnt_5k = 0;
input_current=0;// Sample input current in terms of counter
clk_5k = ~clk_5k;
end
end

// Clock Generation for Sample Input Signal  (50Hz Square Wave)
//50Hz Clock Generation from 50MHz clock

always @(posedge clk_5k)
begin
if(reset)
begin
cnt_50h = 0;
clk_50h = 0;
end
else if (cnt_50h < cnt_value_50h)
begin
cnt_50h = cnt_50h + 1;
end
else if (cnt_50h == cnt_value_50h)
begin
cnt_50h = 0;
clk_50h = ~clk_50h;
end
//                      input_current=clk_50h;
end

// Filter Output

always @(posedge clk_5k or posedge reset)
begin
if (reset)
begin
x_t1 = 0;
x_t2   = 0;
y_t1   = 0;
y_t    = 0;
y_t2   = 0;
y_t22  = 0;
dac_data = 0;
end
else
begin
y_t = (xt2con * x_t2) - (xt1con * x_t1) + (xt2con * input_current) - (yt2con * y_t2) + (xt1con * y_t1) ;
y_t22 =((xt2con >> 16) * x_t2) - ((xt1con >> 16) * x_t1) + ((xt2con >> 16) * input_current) - ((yt2con >> 16) * y_t2) - ((xt1con >> 16) * y_t1) ;

y_t2 = y_t1;
y_t1 = y_t2;
x_t2 = x_t1;
x_t1 = input_current;
dac_data = y_t22;
end

end

assign filter_out = y_t[13:0];

assign clk_5kHz = clk_5k;
assign clk_50Hz = clk_50h;

// Digital to Analoge Conversion

assign da_out = dac_data;
//assign da_out = {input_current[9:0],4'b0000};

endmodule

I need help to solve this. Thanks

Last edited by a moderator:

Please post the errors you are getting in order for others to assist you better!
Further more I see that you have modeled it using only 'blocking' statements.

Code:
always @(posedge clk_in)
begin
if(reset)
begin
cnt_5k = 0;
clk_5k = 0;
.
.

always @(posedge clk_5k)
begin
if(reset)
begin
cnt_50h = 0;
clk_50h = 0;
end

You have declared cnt_5* and clk_5* as registers so use non-blocking statements.
Possibly there are many other mistakes, but the above ones were most apparent!

btw - Is this your first Verilog code?

Last edited:

I am not getting any error in the code. But not getting proper output.
I need to implement this equation:
// y(k) = 0.9975x(k) - 1.9911x(k-1) + 0.9975x(k-2) + 1.9911y(k-1)-0.9950y(k-2)
//

I had generated 10 bit input_signal x(k) using counter.

I had converted the fractional numbers into integers like this.

Code:
// Defining parameters for fractional conversations of difference equation
parameter xt2con = 65372;			// 16 bit value of 0.9975
parameter xt1con = 130488;			//	16 bit value of 1.9911
parameter yt2con = 65208;			// 16 bit value of 0.9950

I had define the equation variables like this:

Code:
	// Variable for difference Equation
reg signed [9:0] x_t1;
reg signed [9:0] x_t2;
reg signed [9:0] y_t1;
reg signed [9:0] y_t2;
reg signed [49:0] y_t;
reg signed [49:0] y_t22;
reg [13:0] dac_data;

Finally the difference equation is implemented like this.

Code Verilog - [expand]1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
always @(posedge clk_5k or posedge reset)
begin
if (reset)
begin
x_t1 = 0;
x_t2   = 0;
y_t1   = 0;
y_t    = 0;
y_t2   = 0;
y_t22  = 0;
dac_data = 0;
end
else
begin
y_t = (xt2con * x_t2) - (xt1con * x_t1) + (xt2con * input_current) - (yt2con * y_t2) + (xt1con * y_t1) ;
y_t22 =((xt2con >> 16) * x_t2) - ((xt1con >> 16) * x_t1) + ((xt2con >> 16) * input_current) - ((yt2con >> 16) * y_t2) - ((xt1con >> 16) * y_t1) ;

y_t2 = y_t1;
y_t1 = y_t2;
x_t2 = x_t1;
x_t1 = input_current;
dac_data = y_t22;
end

end

I think the problem is in the difference equitation implementation part. I am not getting any error in code. But the output is not correct.
Thanks

Last edited by a moderator:

Code:
y_t2 = y_t1;
y_t1 = y_t2;

This does not work correctly, if your intention is to swap the values of y_t1 and y_t2.

Do Not Use blocking assignments in edge sensitive always blocks, they do not always infer registers. I think you need to review the sections in the LRM about non-blocking and blocking assignments and read the papers (recommendations) by cummings and sutherland on this topic.

Code:
parameter xt1con = 130488;			//	16 bit value of 1.9911
This is a 17 bit value not 16-bit!

I'm also wondering about the bit slicing here:
Code:
assign filter_out = y_t[13:0];

Your y_t is defined as a 50-bit value and each y_t calculation is only a 32-bit value max (in reality it will be less)
Code:
                begin     // 16      10        17      10       16          10              16      10        17      10
y_t = (xt2con * x_t2) - (xt1con * x_t1) + (xt2con * input_current) - (yt2con * y_t2) + (xt1con * y_t1) ;`
based on the bit widths above.

Another observation your calculations will probably be wrong as you've not taken into account signed math with 2's comp data. Nor have you don't a good job partitioning the calculation.

Status
Not open for further replies.