Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17255 Discussions

Low Pass Frequency Filter in Verilog

Altera_Forum
Honored Contributor II
7,416 Views

Hello,  

I am trying to implement a low pass frequency filter in Verilog. I know that the input is a sine wave that oscilates around 0. The threshold is 500hz. Here is my code: 

module filter(clk, in, out); 

input signed [11:0]in; 

output signed [13:0]out; 

input clk; 

reg [17:0]counter; 

wire [13:0]out; 

reg q; 

reg [11:0]true; 

reg s; 

initial begin counter=18'b000000000000000000; q=1; true=12'b000000000000; s=1; end 

always @(posedge clk) begin  

if(counter[17]==0) counter=counter+1; 

if(~q==s) begin s=q; counter=18'b00000000000000; end 

end 

always @(negedge in[11]) begin  

true={counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17]};  

q=~q;  

end  

assign out=(in & true)<<< 2; 

endmodule  

 

The output is just 0 for no matter what frequency of the input.(The input is converted in a 2's complement system) 

Will be very happy to hear how to fix my program... but if it desperately stupid, would like to see a code for LPFF. 

Thanks in advance
0 Kudos
19 Replies
Altera_Forum
Honored Contributor II
5,713 Views

You could use signaltap to check what your system is doing. 

While I'm not a Verilog specialist, I see that you use one bit of your 'in' vector as a clock, and this isn't a good idea. You could have metastability issues between your two always blocks, and your second block is sensitive to glitches. Your design would be a lot safer if you could include both parts inside the always @(posedge clk) block, and for example detect a falling edge on in[11] by comparing the signal to it's previous value.
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

Here is my new code: 

module filter(in,out,clk); 

input signed [11:0] in; 

output signed [13:0] out; 

input clk; 

wire [13:0]out; 

reg [17:0]counter; 

reg q; 

reg [11:0]t; 

assign out=(~in & t) <<< 2; 

always @(posedge clk) begin 

if(counter[17]==0) counter=counter+1; 

if((q==0) & (in[11]==1)) begin q=in[11];  

t={counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17]}; 

counter=18'b000000000000000000; 

end 

if((q==1) & (in[11]==0)) q=in[11]; 

end 

endmodule 

The output is still 0.... what do I do wrong?
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

The new code is working great for lower bites...(if you set the controlling bite of the counter 12 for example) but it seems not to work that great for 15,16,17... the output is just 0. Can someone explain why??? Moreover the output is still zero for frequencies as 1khz even if the counter is set on the 12th bite, but it works perfectly in the range higher than that. 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

 

--- Quote Start ---  

Here is my new code: 

module filter(in,out,clk); 

input signed [11:0] in; 

output signed [13:0] out; 

input clk; 

wire [13:0]out; 

reg [17:0]counter; 

reg q; 

reg [11:0]t; 

assign out=(~in & t) <<< 2; 

always @(posedge clk) begin 

if(counter[17]==0) counter=counter+1; 

if((q==0) & (in[11]==1)) begin q=in[11];  

t={counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17],counter[17]}; 

counter=18'b000000000000000000; 

end 

if((q==1) & (in[11]==0)) q=in[11]; 

end 

endmodule 

The output is still 0.... what do I do wrong? 

--- Quote End ---  

 

 

in my opinion you should assign the counter to : counter <= counter + 1 , the register counter is a D ff and it is under , in this case you are specified the edge-sensitive behavior of the circuit (posedge clk) so you have to put the none-Blocking (<= )assignments for your registers .
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

Does anyone understand what the code is supposed to do? It's apparently not what we know as a low pass filter.

0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

It is supposed to do the following: 

If the frequency of the input is lower or equal than the threshold frequency the output will look exactly as the input, 

else the output will be 0.
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

 

--- Quote Start ---  

It is supposed to do the following: 

If the frequency of the input is lower or equal than the threshold frequency the output will look exactly as the input, 

else the output will be 0. 

--- Quote End ---  

 

 

and what is the nature of your input(sine waves or any signal). Your filter sounds ideal pass/not pass but yo haven't explained your algorithm. 

How you going to detect frequency of input?
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

Yeah... I think you are right, and I should explain a little bit more about the idea of the code. 

The input is a sine wave. The design will be implemented on a Altera Cyclone FPGA, installed on a USRP. The input clock has a frequency of 64Mhz. The input signal is compared to a counter(whose frequency I can change... knowing the frequency of the clock). At every time that input goes from positive value to negative(we use the 2's complement properties here... and exactly the fact that if the signal is negative the first bit is 1 and if positive the first bit is 0) the control wave is restored to 0 and the comparison between the input signal and the control one is done one more time. 

Hope this helps, 

Sorry for not doing it from the start.
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

 

--- Quote Start ---  

Yeah... I think you are right, and I should explain a little bit more about the idea of the code. 

The input is a sine wave. The design will be implemented on a Altera Cyclone FPGA, installed on a USRP. The input clock has a frequency of 64Mhz. The input signal is compared to a counter(whose frequency I can change... knowing the frequency of the clock). At every time that input goes from positive value to negative(we use the 2's complement properties here... and exactly the fact that if the signal is negative the first bit is 1 and if positive the first bit is 0) the control wave is restored to 0 and the comparison between the input signal and the control one is done one more time. 

Hope this helps, 

Sorry for not doing it from the start. 

--- Quote End ---  

 

 

OK, so your sine input is running at system clock of 64MHz and for sine threshold of 500Hz you need to count up to 64000 (on 64MHz clock) for half cycle to see if sign bit changes(zero crossing) then pass it if so or more than 64000 clocks else mute it. Naturally you need to count 1/2 cycle and decide and may be you don't need to store that first half i.e. is it one check only to decide or you keep tracking your input in which case you need to store each half before deciding.  

My simplest algorithm would be: run counter 0 ~ 64000-1, checking sign bit regularly. if sign bit didn't change right to end pass input else mute. 

Thus you need first to determine the algorithm before writing code. We are also ignoring phase of sine input.
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

Thanks kaz... though, can you please explain what is the disadvantage of checking the whole period of the input instead of checking only one half? 

Thanks
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

 

--- Quote Start ---  

Thanks kaz... though, can you please explain what is the disadvantage of checking the whole period of the input instead of checking only one half? 

Thanks 

--- Quote End ---  

 

 

just to save on counting. Either way it works. It is also much easier to check is sign bit changed value relative to previous value. 

than to check if sign bit changed then changed back.
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

Thanks. Do you have any idea why the code is behaving weird when the frequencies are low?

0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

I haven't done verilog for years but in vhdl I will do this: 

 

clocked process: 

--run counter 0 @ 64000-1; 

sign_bit_d <= sign_bit; 

output <= input; 

if sign_bit /= sign_bit_d and count < 64000 then 

output <= (others => '0'); 

end if; 

end process;
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

For low frequencies you also need to reset your counter in some way e.g. at zero crossing.

0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

Yes I do reset it at zero crossing, but it mutes the output when the frequencies are low and then behaves exactly as expected...

0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

Well let me have a go at it in vhdl off my head(not tested) assuming sine phase starts at 0: 

let count be binary of suitable width e.g. 20 bits free running i.e. donot stop at 64000-1 

process begin wait until clk = '1'; count <= count +1; sign_bit_d <= sign_bit; if sign_bit /= sign_bit_d then count <= (others => '0'); mute <= '0'; if count < 64000-1 then mute <= '1'; end if; end if; end process; output <= input when mute = '0' else (others => '0');
0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

see my editing of code. Also it is too simplistic regarding mute as you need to keep it latched until next check so I leave that to you.

0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

Thanks a lot, kaz.

0 Kudos
Altera_Forum
Honored Contributor II
5,713 Views

I think my another last edit of code should work with mute as well. A check is done at zero crossing to reset count and update mute. 

Good luck.
0 Kudos
Reply