Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
13 years ago

Low Pass Frequency Filter in Verilog

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

19 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- 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.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

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

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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;
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

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

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

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

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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');
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    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.