Forum Discussion

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

Filter iir trasposed structure

Hello everybody,

I have a problem...

I try to relized a simple iir filter (to simply this i choose the first order) with one tap, only one mobile average coeff (b0=1) and only one auto-regressive coeff (a1=2),

so implement this using std_logic_vector signal to realize the delay for every clock impulse.

I implement two lpm moltiplicator to realized input moltiplication (b*input) and output moltiplication (a*output).. so these performe moltiplication always (because i don't use the clock with pipeline).

So when i sum the mobile part (pnum) with autoregressive part (pden) there is a delay due to signal in the adder operation because the autoregressive part depend of the output y.. See program iir_1 with image 01:confused:

I think to resolve this problem introduce a delay in the mobile part but i can't resolve this problem with this.. because then i don't sum the auto regressive part in the first adder so the output don't change and go to 0... See program iir_1_delay with image 02:(

Someone can help me, please?

thank you!

The program is structured with array because i had tried to implement an 3 order iir filter.. so in this case (1°order) i use only the first element..

17 Replies

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

    --- Quote Start ---

    You should get as you say 1,4,12,28,64,... try use signed type instead of full width integer.

    The code is direct translation of your diagram so it must work. You have some strange initial values on y1,y2...what are those?

    --- Quote End ---

    The strange value assigned at my debug variables is because i don't assign a standard value when i write out port..

    so it assign the first value that is..-(2^32)-1, when i impose a value y1 or y2 they become these numer. At the begin i'm expected 0.. but i note that when i use for the first time alter compiler..

    So i haven't use the signed type before.. what type i must use??? can you write me something example..

    and you can tell me why the scale of

    subtype bits11 is integer range -1023 to 1024; -- 11 bit

    when i define variable like...

    a: bits11;

    if i don't impose the default value they are initializated to least value and not to zero.

    so.. thank you!:rolleyes:
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    assume input x is 16 bits signed

    y_out is 16 bits signed

    coeffs 16 bits signed

    then you can either use integer computation or signed.

    to simplify example, let us assume we can truncate y_int below without check,

    I also assume a coeff of say 2 means 2 in terms of gain.

    This code is untested but should give you an idea.

    
    signal y1 : signed(32 downto 0) := (others => '0');
    signal y2 : signed(33 downto 0) := (others => '0');
    signal y_int : signed(34 downto 0) := (others => '0');
    constant b0 : signed(15 downto 0) := x"0001"; 
    constant b1 : signed(15 downto 0) := x"0002"; 
    constant b2 : signed(15 downto 0) := x"0003"; 
    constant a1 : signed(15 downto 0) := x"0002"; 
    constant a2 : signed(15 downto 0) := x"0001"; 
    begin
    process
    begin
    wait until clk = '1';
       y1 <= x*b2  + y_int(15 downto 0)*a2;        -- 16*16 + 16*16cbits, needs 33 bits
       y2 <= x*b1  + y_int(15 downto 0)*a1 + y1; -- 16*16 + 16*16 + 33bits, needs 34 bits
    end process;
    y_int <= x*b0 + y2; -- 16 * 16 + 34 bits, requires 35 bits
    y <= y_int(15 downto 0);
    
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    assume input x is 16 bits signed

    y_out is 16 bits signed

    coeffs 16 bits signed

    then you can either use integer computation or signed.

    to simplify example, let us assume we can truncate y_int below without check,

    I also assume a coeff of say 2 means 2 in terms of gain.

    This code is untested but should give you an idea.

    
    signal y1 : signed(32 downto 0) := (others => '0');
    signal y2 : signed(33 downto 0) := (others => '0');
    signal y_int : signed(34 downto 0) := (others => '0');
    constant b0 : signed(15 downto 0) := x"0001"; 
    constant b1 : signed(15 downto 0) := x"0002"; 
    constant b2 : signed(15 downto 0) := x"0003"; 
    constant a1 : signed(15 downto 0) := x"0002"; 
    constant a2 : signed(15 downto 0) := x"0001"; 
    begin
    process
    begin
    wait until clk = '1';
       y1 <= x*b2  + y_int(15 downto 0)*a2;        -- 16*16 + 16*16cbits, needs 33 bits
       y2 <= x*b1  + y_int(15 downto 0)*a1 + y1; -- 16*16 + 16*16 + 33bits, needs 34 bits
    end process;
    y_int <= x*b0 + y2; -- 16 * 16 + 34 bits, requires 35 bits
    y <= y_int(15 downto 0);
    

    --- Quote End ---

    Ok. thank you for your response..

    in your code there isn't extension of sign.. so when compile there are some errors.. due to different dimension of register...

    so i put they of the same length ignoring for this time the correct length of the registers..

    do you know some function that extent the sign automatically?

    I simulate this example of qsim and this is correct.. thank you!:o

    i show this on the file sim_solution.pdf with coeff b0=1 b1=2 b3=3 a1=2 a2=1
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    example resize:

    for above y1 <= x*b2 + y_int(15 downto 0)*a2;

    try this

    y1 <= resize(x,33)*resize(b2,33) + resize(y_int(15 downto 0),33)*resize(a2,33);
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I already recommended you use numeric_std for the signed/unsigned types. Using std_logic_vector is just messy, and there is no need to use the LPM library. why are you insisting on this?

    Secondly - your attempt to use shared variables shows lack of understanding of VHDL, and given your postings here and elsewhere, I suspect your knowledge of digital logic could also use some revision.

    I also recommend you try using modelsim as well.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I already recommended you use numeric_std for the signed/unsigned types. Using std_logic_vector is just messy, and there is no need to use the LPM library. why are you insisting on this?

    Secondly - your attempt to use shared variables shows lack of understanding of VHDL, and given your postings here and elsewhere, I suspect your knowledge of digital logic could also use some revision.

    I also recommend you try using modelsim as well.

    --- Quote End ---

    I'm sorry.. i'm only a student of vhdl.. i started use vhdl two mouths ago, so i read only some notes. but i must use vhdl.:(

    if you help me i can improve my knowledge. thanks.