Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Problem in implementing difference equation of Digital notch filter

Status
Not open for further replies.

jawad04

Newbie level 4
Joined
Sep 10, 2015
Messages
5
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
90
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
// Engineer: Jawad Yousaf
// 
// 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
// Additional Comments: 
// 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.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top