- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 advanceLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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 .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Does anyone understand what the code is supposed to do? It's apparently not what we know as a low pass filter.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks. Do you have any idea why the code is behaving weird when the frequencies are low?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For low frequencies you also need to reset your counter in some way e.g. at zero crossing.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes I do reset it at zero crossing, but it mutes the output when the frequencies are low and then behaves exactly as expected...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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');
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks a lot, kaz.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page