FIR Filter Transposed Form VHDL

Discussion in 'VHDL' started by Ste_ee, Oct 7, 2013.

  1. Ste_ee

    Ste_ee Guest

    Hi to all! I did this filter: 128 order, with 8 bit input and 16 bit coefficients (2 complement).
    But i don't understand because the multiplication doesn't work. My VHDL is very simple and behavioral:

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_signed.ALL;
    use IEEE.STD_LOGIC_arith.ALL;

    entity fir128 is
    port(
    input: in std_logic_vector(7 downto 0);
    clk : in std_logic;
    output: out std_logic_vector(200 downto 0)
    );
    end fir128;

    architecture Behavioral of fir128 is

    type mult_type is array (128 downto 0) of std_logic_vector(23 downto 0);
    signal sig_coeff : mult_type;

    type add_type is array (128 downto 0) of std_logic_vector(200 downto 0);
    signal sig_add : add_type;

    type memory is array (128 downto 0) of std_logic_vector(15 downto 0);
    signal coeff : memory :=(
    "0000000000000111",
    "0000000000000101",
    "0000000000000001",
    "1111111111111100",
    "1111111111111001",
    "1111111111111000",
    "1111111111111100",
    "0000000000000010",
    "0000000000001001",
    "0000000000001100",
    "0000000000001001",
    "0000000000000001",
    "1111111111110110",
    "1111111111101111",
    "1111111111101111",
    "1111111111111001",
    "0000000000001000",
    "0000000000010111",
    "0000000000011011",
    "0000000000010010",
    "1111111111111110",
    "1111111111100110",
    "1111111111011000",
    "1111111111011101",
    "1111111111110110",
    "0000000000011000",
    "0000000000110100",
    "0000000000111001",
    "0000000000100000",
    "1111111111110010",
    "1111111111000100",
    "1111111110101110",
    "1111111111000001",
    "1111111111110111",
    "0000000000111011",
    "0000000001101010",
    "0000000001101000",
    "0000000000101111",
    "1111111111010101",
    "1111111110000011",
    "1111111101100111",
    "1111111110010111",
    "0000000000000110",
    "0000000010000011",
    "0000000011001110",
    "0000000010111000",
    "0000000000111101",
    "1111111110001101",
    "1111111011111101",
    "1111111011011100",
    "1111111101010010",
    "0000000000111011",
    "0000000100110100",
    "0000000110111011",
    "0000000101101111",
    "0000000001000111",
    "1111111010100101",
    "1111110101000110",
    "1111110011111101",
    "1111111001011100",
    "0000000101110100",
    "0000010110110011",
    "0000101000001101",
    "0000110101001110",
    "0000111010000010",
    "0000110101001110",
    "0000101000001101",
    "0000010110110011",
    "0000000101110100",
    "1111111001011100",
    "1111110011111101",
    "1111110101000110",
    "1111111010100101",
    "0000000001000111",
    "0000000101101111",
    "0000000110111011",
    "0000000100110100",
    "0000000000111011",
    "1111111101010010",
    "1111111011011100",
    "1111111011111101",
    "1111111110001101",
    "0000000000111101",
    "0000000010111000",
    "0000000011001110",
    "0000000010000011",
    "0000000000000110",
    "1111111110010111",
    "1111111101100111",
    "1111111110000011",
    "1111111111010101",
    "0000000000101111",
    "0000000001101000",
    "0000000001101010",
    "0000000000111011",
    "1111111111110111",
    "1111111111000001",
    "1111111110101110",
    "1111111111000100",
    "1111111111110010",
    "0000000000100000",
    "0000000000111001",
    "0000000000110100",
    "0000000000011000",
    "1111111111110110",
    "1111111111011101",
    "1111111111011000",
    "1111111111100110",
    "1111111111111110",
    "0000000000010010",
    "0000000000011011",
    "0000000000010111",
    "0000000000001000",
    "1111111111111001",
    "1111111111101111",
    "1111111111101111",
    "1111111111110110",
    "0000000000000001",
    "0000000000001001",
    "0000000000001100",
    "0000000000001001",
    "0000000000000010",
    "1111111111111100",
    "1111111111111000",
    "1111111111111001",
    "1111111111111100",
    "0000000000000001",
    "0000000000000101",
    "0000000000000111");


    signal zero : std_logic_vector(200 downto 0):=(others=>'0');

    begin
    process(clk)
    begin

    if clk'event and clk='1' then
    sig_add(128)<= zero + sig_coeff(128);

    for i in 128 downto 0 loop

    sig_coeff(i)<= input*coeff(i);

    if i = 0 then
    sig_add(0) <= sig_add(1)+sig_coeff(0);
    else
    sig_add(i-1)<=sig_add(i)+sig_coeff(i-1);
    end if;

    end loop;
    end if;
    end process;

    output<=sig_add(0);

    end Behavioral;
     
    Ste_ee, Oct 7, 2013
    #1
    1. Advertising

  2. Ste_ee

    Ste_ee Guest

    Il giorno lunedì 7 ottobre 2013 21:05:32 UTC+2, Ste_ee ha scritto:
    > Hi to all! I did this filter: 128 order, with 8 bit input and 16 bit coefficients (2 complement).
    >
    > But i don't understand because the multiplication doesn't work. My VHDL is very simple and behavioral:
    >
    >
    >
    > library IEEE;
    >
    > use IEEE.STD_LOGIC_1164.ALL;
    >
    > use IEEE.STD_LOGIC_signed.ALL;
    >
    > use IEEE.STD_LOGIC_arith.ALL;
    >
    >
    >
    > entity fir128 is
    >
    > port(
    >
    > input: in std_logic_vector(7 downto 0);
    >
    > clk : in std_logic;
    >
    > output: out std_logic_vector(200 downto 0)
    >
    > );
    >
    > end fir128;
    >
    >
    >
    > architecture Behavioral of fir128 is
    >
    >
    >
    > type mult_type is array (128 downto 0) of std_logic_vector(23 downto 0);
    >
    > signal sig_coeff : mult_type;
    >
    >
    >
    > type add_type is array (128 downto 0) of std_logic_vector(200 downto 0);
    >
    > signal sig_add : add_type;
    >
    >
    >
    > type memory is array (128 downto 0) of std_logic_vector(15 downto 0);
    >
    > signal coeff : memory :=(
    >
    > "0000000000000111",
    >
    > "0000000000000101",
    >
    > "0000000000000001",
    >
    > "1111111111111100",
    >
    > "1111111111111001",
    >
    > "1111111111111000",
    >
    > "1111111111111100",
    >
    > "0000000000000010",
    >
    > "0000000000001001",
    >
    > "0000000000001100",
    >
    > "0000000000001001",
    >
    > "0000000000000001",
    >
    > "1111111111110110",
    >
    > "1111111111101111",
    >
    > "1111111111101111",
    >
    > "1111111111111001",
    >
    > "0000000000001000",
    >
    > "0000000000010111",
    >
    > "0000000000011011",
    >
    > "0000000000010010",
    >
    > "1111111111111110",
    >
    > "1111111111100110",
    >
    > "1111111111011000",
    >
    > "1111111111011101",
    >
    > "1111111111110110",
    >
    > "0000000000011000",
    >
    > "0000000000110100",
    >
    > "0000000000111001",
    >
    > "0000000000100000",
    >
    > "1111111111110010",
    >
    > "1111111111000100",
    >
    > "1111111110101110",
    >
    > "1111111111000001",
    >
    > "1111111111110111",
    >
    > "0000000000111011",
    >
    > "0000000001101010",
    >
    > "0000000001101000",
    >
    > "0000000000101111",
    >
    > "1111111111010101",
    >
    > "1111111110000011",
    >
    > "1111111101100111",
    >
    > "1111111110010111",
    >
    > "0000000000000110",
    >
    > "0000000010000011",
    >
    > "0000000011001110",
    >
    > "0000000010111000",
    >
    > "0000000000111101",
    >
    > "1111111110001101",
    >
    > "1111111011111101",
    >
    > "1111111011011100",
    >
    > "1111111101010010",
    >
    > "0000000000111011",
    >
    > "0000000100110100",
    >
    > "0000000110111011",
    >
    > "0000000101101111",
    >
    > "0000000001000111",
    >
    > "1111111010100101",
    >
    > "1111110101000110",
    >
    > "1111110011111101",
    >
    > "1111111001011100",
    >
    > "0000000101110100",
    >
    > "0000010110110011",
    >
    > "0000101000001101",
    >
    > "0000110101001110",
    >
    > "0000111010000010",
    >
    > "0000110101001110",
    >
    > "0000101000001101",
    >
    > "0000010110110011",
    >
    > "0000000101110100",
    >
    > "1111111001011100",
    >
    > "1111110011111101",
    >
    > "1111110101000110",
    >
    > "1111111010100101",
    >
    > "0000000001000111",
    >
    > "0000000101101111",
    >
    > "0000000110111011",
    >
    > "0000000100110100",
    >
    > "0000000000111011",
    >
    > "1111111101010010",
    >
    > "1111111011011100",
    >
    > "1111111011111101",
    >
    > "1111111110001101",
    >
    > "0000000000111101",
    >
    > "0000000010111000",
    >
    > "0000000011001110",
    >
    > "0000000010000011",
    >
    > "0000000000000110",
    >
    > "1111111110010111",
    >
    > "1111111101100111",
    >
    > "1111111110000011",
    >
    > "1111111111010101",
    >
    > "0000000000101111",
    >
    > "0000000001101000",
    >
    > "0000000001101010",
    >
    > "0000000000111011",
    >
    > "1111111111110111",
    >
    > "1111111111000001",
    >
    > "1111111110101110",
    >
    > "1111111111000100",
    >
    > "1111111111110010",
    >
    > "0000000000100000",
    >
    > "0000000000111001",
    >
    > "0000000000110100",
    >
    > "0000000000011000",
    >
    > "1111111111110110",
    >
    > "1111111111011101",
    >
    > "1111111111011000",
    >
    > "1111111111100110",
    >
    > "1111111111111110",
    >
    > "0000000000010010",
    >
    > "0000000000011011",
    >
    > "0000000000010111",
    >
    > "0000000000001000",
    >
    > "1111111111111001",
    >
    > "1111111111101111",
    >
    > "1111111111101111",
    >
    > "1111111111110110",
    >
    > "0000000000000001",
    >
    > "0000000000001001",
    >
    > "0000000000001100",
    >
    > "0000000000001001",
    >
    > "0000000000000010",
    >
    > "1111111111111100",
    >
    > "1111111111111000",
    >
    > "1111111111111001",
    >
    > "1111111111111100",
    >
    > "0000000000000001",
    >
    > "0000000000000101",
    >
    > "0000000000000111");
    >
    >
    >
    >
    >
    > signal zero : std_logic_vector(200 downto 0):=(others=>'0');
    >
    >
    >
    > begin
    >
    > process(clk)
    >
    > begin
    >
    >
    >
    > if clk'event and clk='1' then
    >
    > sig_add(128)<= zero + sig_coeff(128);
    >
    >
    >
    > for i in 128 downto 0 loop
    >
    >
    >
    > sig_coeff(i)<= input*coeff(i);
    >
    >
    >
    > if i = 0 then
    >
    > sig_add(0) <= sig_add(1)+sig_coeff(0);
    >
    > else
    >
    > sig_add(i-1)<=sig_add(i)+sig_coeff(i-1);
    >
    > end if;
    >
    >
    >
    > end loop;
    >
    > end if;
    >
    > end process;
    >
    >
    >
    > output<=sig_add(0);
    >
    >
    >
    > end Behavioral;


    I changed with this, but output is ever X.

    for i in 128 downto 0 loop
    sig_coeff(i)<= input*coeff(i);
    if i = 128 then
    sig_add(128)<= zero + sig_coeff(128);
    else
    sig_add(i)<=sig_add(i+1)+sig_coeff(i);
    end if;
     
    Ste_ee, Oct 7, 2013
    #2
    1. Advertising

  3. Ste_ee

    Ste_ee Guest

    Il giorno lunedì 7 ottobre 2013 21:05:32 UTC+2, Ste_ee ha scritto:
    > Hi to all! I did this filter: 128 order, with 8 bit input and 16 bit coefficients (2 complement).
    >
    > But i don't understand because the multiplication doesn't work. My VHDL is very simple and behavioral:
    >
    >
    >
    > library IEEE;
    >
    > use IEEE.STD_LOGIC_1164.ALL;
    >
    > use IEEE.STD_LOGIC_signed.ALL;
    >
    > use IEEE.STD_LOGIC_arith.ALL;
    >
    >
    >
    > entity fir128 is
    >
    > port(
    >
    > input: in std_logic_vector(7 downto 0);
    >
    > clk : in std_logic;
    >
    > output: out std_logic_vector(200 downto 0)
    >
    > );
    >
    > end fir128;
    >
    >
    >
    > architecture Behavioral of fir128 is
    >
    >
    >
    > type mult_type is array (128 downto 0) of std_logic_vector(23 downto 0);
    >
    > signal sig_coeff : mult_type;
    >
    >
    >
    > type add_type is array (128 downto 0) of std_logic_vector(200 downto 0);
    >
    > signal sig_add : add_type;
    >
    >
    >
    > type memory is array (128 downto 0) of std_logic_vector(15 downto 0);
    >
    > signal coeff : memory :=(
    >
    > "0000000000000111",
    >
    > "0000000000000101",
    >
    > "0000000000000001",
    >
    > "1111111111111100",
    >
    > "1111111111111001",
    >
    > "1111111111111000",
    >
    > "1111111111111100",
    >
    > "0000000000000010",
    >
    > "0000000000001001",
    >
    > "0000000000001100",
    >
    > "0000000000001001",
    >
    > "0000000000000001",
    >
    > "1111111111110110",
    >
    > "1111111111101111",
    >
    > "1111111111101111",
    >
    > "1111111111111001",
    >
    > "0000000000001000",
    >
    > "0000000000010111",
    >
    > "0000000000011011",
    >
    > "0000000000010010",
    >
    > "1111111111111110",
    >
    > "1111111111100110",
    >
    > "1111111111011000",
    >
    > "1111111111011101",
    >
    > "1111111111110110",
    >
    > "0000000000011000",
    >
    > "0000000000110100",
    >
    > "0000000000111001",
    >
    > "0000000000100000",
    >
    > "1111111111110010",
    >
    > "1111111111000100",
    >
    > "1111111110101110",
    >
    > "1111111111000001",
    >
    > "1111111111110111",
    >
    > "0000000000111011",
    >
    > "0000000001101010",
    >
    > "0000000001101000",
    >
    > "0000000000101111",
    >
    > "1111111111010101",
    >
    > "1111111110000011",
    >
    > "1111111101100111",
    >
    > "1111111110010111",
    >
    > "0000000000000110",
    >
    > "0000000010000011",
    >
    > "0000000011001110",
    >
    > "0000000010111000",
    >
    > "0000000000111101",
    >
    > "1111111110001101",
    >
    > "1111111011111101",
    >
    > "1111111011011100",
    >
    > "1111111101010010",
    >
    > "0000000000111011",
    >
    > "0000000100110100",
    >
    > "0000000110111011",
    >
    > "0000000101101111",
    >
    > "0000000001000111",
    >
    > "1111111010100101",
    >
    > "1111110101000110",
    >
    > "1111110011111101",
    >
    > "1111111001011100",
    >
    > "0000000101110100",
    >
    > "0000010110110011",
    >
    > "0000101000001101",
    >
    > "0000110101001110",
    >
    > "0000111010000010",
    >
    > "0000110101001110",
    >
    > "0000101000001101",
    >
    > "0000010110110011",
    >
    > "0000000101110100",
    >
    > "1111111001011100",
    >
    > "1111110011111101",
    >
    > "1111110101000110",
    >
    > "1111111010100101",
    >
    > "0000000001000111",
    >
    > "0000000101101111",
    >
    > "0000000110111011",
    >
    > "0000000100110100",
    >
    > "0000000000111011",
    >
    > "1111111101010010",
    >
    > "1111111011011100",
    >
    > "1111111011111101",
    >
    > "1111111110001101",
    >
    > "0000000000111101",
    >
    > "0000000010111000",
    >
    > "0000000011001110",
    >
    > "0000000010000011",
    >
    > "0000000000000110",
    >
    > "1111111110010111",
    >
    > "1111111101100111",
    >
    > "1111111110000011",
    >
    > "1111111111010101",
    >
    > "0000000000101111",
    >
    > "0000000001101000",
    >
    > "0000000001101010",
    >
    > "0000000000111011",
    >
    > "1111111111110111",
    >
    > "1111111111000001",
    >
    > "1111111110101110",
    >
    > "1111111111000100",
    >
    > "1111111111110010",
    >
    > "0000000000100000",
    >
    > "0000000000111001",
    >
    > "0000000000110100",
    >
    > "0000000000011000",
    >
    > "1111111111110110",
    >
    > "1111111111011101",
    >
    > "1111111111011000",
    >
    > "1111111111100110",
    >
    > "1111111111111110",
    >
    > "0000000000010010",
    >
    > "0000000000011011",
    >
    > "0000000000010111",
    >
    > "0000000000001000",
    >
    > "1111111111111001",
    >
    > "1111111111101111",
    >
    > "1111111111101111",
    >
    > "1111111111110110",
    >
    > "0000000000000001",
    >
    > "0000000000001001",
    >
    > "0000000000001100",
    >
    > "0000000000001001",
    >
    > "0000000000000010",
    >
    > "1111111111111100",
    >
    > "1111111111111000",
    >
    > "1111111111111001",
    >
    > "1111111111111100",
    >
    > "0000000000000001",
    >
    > "0000000000000101",
    >
    > "0000000000000111");
    >
    >
    >
    >
    >
    > signal zero : std_logic_vector(200 downto 0):=(others=>'0');
    >
    >
    >
    > begin
    >
    > process(clk)
    >
    > begin
    >
    >
    >
    > if clk'event and clk='1' then
    >
    > sig_add(128)<= zero + sig_coeff(128);
    >
    >
    >
    > for i in 128 downto 0 loop
    >
    >
    >
    > sig_coeff(i)<= input*coeff(i);
    >
    >
    >
    > if i = 0 then
    >
    > sig_add(0) <= sig_add(1)+sig_coeff(0);
    >
    > else
    >
    > sig_add(i-1)<=sig_add(i)+sig_coeff(i-1);
    >
    > end if;
    >
    >
    >
    > end loop;
    >
    > end if;
    >
    > end process;
    >
    >
    >
    > output<=sig_add(0);
    >
    >
    >
    > end Behavioral;


    The input is "impulse":
    stim_proc: process
    begin
    input<=(others=>'0');
    wait for 10 ns;
    input<="00000001";
    wait for 10 ns;
    input<=(others=>'0');
    wait;
    end process;
     
    Ste_ee, Oct 7, 2013
    #3
  4. Ste_ee

    Guest

    Some comments:

    1. Replace IEEE.STD_LOGIC_signed.ALL and IEEE.STD_LOGIC_arith.ALL (generally considered evil) with ieee.numeric_std.all, and used the signed type instead of std_logic_vector. See www.gstitt.ece.ufl.edu/vhdl/refs/vhdl_math_tricks_mapld_2003.pdf for more info.

    2. sig_add(128)<= zero + sig_coeff(128) doesn't add any value.

    3. 201 significant bits for intermediate values and the result (from an 8-bit input and 16-bit coefficients) are way overkill.

    4. It looks like you're trying to do this in one clock cycle, but signals don't get updated until the process suspends, so in this case it will take 129 clock cycles to get the wrong answer.

    5. There is no input delay chain - there should be a shift register or other memory that stores inputs, then multiply input(0..128) * coeff(0..128).

    6. If this is not a homework assignment, have you considered using a FIR core?
     
    , Oct 8, 2013
    #4
  5. Ste_ee

    Guest

    On Tuesday, October 8, 2013 11:04:30 AM UTC-4, wrote:
    > Some comments:
    >
    >
    >
    > 1. Replace IEEE.STD_LOGIC_signed.ALL and IEEE.STD_LOGIC_arith.ALL (generally considered evil) with ieee.numeric_std.all, and used the signed type instead of std_logic_vector. See www.gstitt.ece.ufl.edu/vhdl/refs/vhdl_math_tricks_mapld_2003.pdf for more info.
    >
    >
    >
    > 2. sig_add(128)<= zero + sig_coeff(128) doesn't add any value.
    >
    >
    >
    > 3. 201 significant bits for intermediate values and the result (from an 8-bit input and 16-bit coefficients) are way overkill.
    >
    >
    >
    > 4. It looks like you're trying to do this in one clock cycle, but signalsdon't get updated until the process suspends, so in this case it will take129 clock cycles to get the wrong answer.
    >
    >
    >
    > 5. There is no input delay chain - there should be a shift register or other memory that stores inputs, then multiply input(0..128) * coeff(0..128).
    >
    >
    >
    > 6. If this is not a homework assignment, have you considered using a FIR core?


    Sorry - I didn't read the subject and see that it's a transposed form filter. In #5 the delay chain is not at the input, but at the multiplication results.
     
    , Oct 8, 2013
    #5
  6. Ste_ee

    Ste_ee Guest

    Il giorno martedì 8 ottobre 2013 17:43:12 UTC+2, ha scritto:
    > On Tuesday, October 8, 2013 11:04:30 AM UTC-4, wrote:
    >
    > > Some comments:

    >
    > >

    >
    > >

    >
    > >

    >
    > > 1. Replace IEEE.STD_LOGIC_signed.ALL and IEEE.STD_LOGIC_arith.ALL (generally considered evil) with ieee.numeric_std.all, and used the signed type instead of std_logic_vector. See www.gstitt.ece.ufl.edu/vhdl/refs/vhdl_math_tricks_mapld_2003.pdf for more info.

    >
    > >

    >
    > >

    >
    > >

    >
    > > 2. sig_add(128)<= zero + sig_coeff(128) doesn't add any value.

    >
    > >

    >
    > >

    >
    > >

    >
    > > 3. 201 significant bits for intermediate values and the result (from an8-bit input and 16-bit coefficients) are way overkill.

    >
    > >

    >
    > >

    >
    > >

    >
    > > 4. It looks like you're trying to do this in one clock cycle, but signals don't get updated until the process suspends, so in this case it will take 129 clock cycles to get the wrong answer.

    >
    > >

    >
    > >

    >
    > >

    >
    > > 5. There is no input delay chain - there should be a shift register or other memory that stores inputs, then multiply input(0..128) * coeff(0..128).

    >
    > >

    >
    > >

    >
    > >

    >
    > > 6. If this is not a homework assignment, have you considered using a FIR core?

    >
    >
    >
    > Sorry - I didn't read the subject and see that it's a transposed form filter. In #5 the delay chain is not at the input, but at the multiplication results.


    Thank you for answer!
    True, the signals get update out of process.
    The filter is for exam of laboratory and FIR Core would be too easy, and i don't learn :).
    Unfortunately there isn't an exam about signal processing, then i don't understand how will the better size of adders. At the output of filter there is generally a DAC, but it hasn't 30, 40 bit in input.Then i have to truncate the data?
    But i believe there is already 1 FF after the multiplication.
    For first thing i will try to insert the delay chain on input and i will let you know!!
     
    Ste_ee, Oct 8, 2013
    #6
  7. Ste_ee

    Ste_ee Guest

    Il giorno martedì 8 ottobre 2013 19:35:24 UTC+2, Ste_ee ha scritto:
    > Il giorno martedì 8 ottobre 2013 17:43:12 UTC+2, ha scritto:
    >
    > > On Tuesday, October 8, 2013 11:04:30 AM UTC-4, wrote:

    >
    > >

    >
    > > > Some comments:

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > 1. Replace IEEE.STD_LOGIC_signed.ALL and IEEE.STD_LOGIC_arith.ALL (generally considered evil) with ieee.numeric_std.all, and used the signed type instead of std_logic_vector. See www.gstitt.ece.ufl.edu/vhdl/refs/vhdl_math_tricks_mapld_2003.pdf for more info.

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > 2. sig_add(128)<= zero + sig_coeff(128) doesn't add any value.

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > 3. 201 significant bits for intermediate values and the result (from an 8-bit input and 16-bit coefficients) are way overkill.

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > 4. It looks like you're trying to do this in one clock cycle, but signals don't get updated until the process suspends, so in this case it will take 129 clock cycles to get the wrong answer.

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > 5. There is no input delay chain - there should be a shift register or other memory that stores inputs, then multiply input(0..128) * coeff(0..128).

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > >

    >
    > >

    >
    > > > 6. If this is not a homework assignment, have you considered using a FIR core?

    >
    > >

    >
    > >

    >
    > >

    >
    > > Sorry - I didn't read the subject and see that it's a transposed form filter. In #5 the delay chain is not at the input, but at the multiplicationresults.

    >
    >
    >
    > Thank you for answer!
    >
    > True, the signals get update out of process.
    >
    > The filter is for exam of laboratory and FIR Core would be too easy, and i don't learn :).
    >
    > Unfortunately there isn't an exam about signal processing, then i don't understand how will the better size of adders. At the output of filter thereis generally a DAC, but it hasn't 30, 40 bit in input.Then i have to truncate the data?
    >
    > But i believe there is already 1 FF after the multiplication.
    >
    > For first thing i will try to insert the delay chain on input and i will let you know!!


    I tried to implement delay chain after multiplication, but i see always thefirst 3 coefficients and then 0. The adders don't work..i don't know.. i tried the delay chain on input too, but nothing.Look this:

    process(clk)
    begin
    if clk'event and clk='1' then
    for i in 127 downto 0 loop
    sig_coeff(i)<= input*coeff(i);

    delaymult1(i)<=sig_coeff(i);
    delaymult2(i)<=delaymult1(i);

    if i = 127 then
    sig_add(i)<= "000000000"& delaymult2(i);
    else
    sig_add(i)<=sig_add(i+1)+delaymult2(i);

    end if;
    end loop;
    end if;
    end process;
    output<=add(0);
     
    Ste_ee, Oct 9, 2013
    #7
  8. Ste_ee

    Guest

    You may have been closer in your 2nd post, but it looks like you have too many delay elements, not too few! In the addition, you want to add the immediate result of the multiplication with the delayed result of the neighboring multiplication, however since both operands are flip-flip outputs it doesn't look like you're doing that. Either directly use the multiplication result (instead of storing it in a signal), or use a variable for the multiplication result, which will not create a register if it's assigned before it's used (google or look in your textbook for variables vs. signals).

    For the bit widths, it sounds like you haven't learned that yet, but I'm not sure how much help I can be since I've always had the luxury of using FPGA cores or DSP software libraries. However, some things to look at or try:
    1. Notice what happens when you multiply 2's complement integer numbers (try it with all combinations of positive/negative maximum values): you get 2 sign bits, feel free to throw one away, or use a fixed point library (google "vhdl fixed point").
    2. Put you coefficient into a spreadsheet and multiply each positive coefficient by the maximum positive input and each negative coefficient by the maximum negative input, then sum the results, that will give you the worst-case (though unlikely) # of bits required. Usually coefficients are scaled such that the worst-case result is the sum of the number of input + coefficient bits, or in your case 24. Try it first though, as I could be completely wrong. For your DAC output, yes, truncate the data using the most significant relevant bits.

    Other notes: if you reset the registers you can start seeing valid data (the impulse response which will be the coefficients) immediately, as opposed to 128 clock cycles of invalid data. Are you running the simulation long enough?
     
    , Oct 9, 2013
    #8
  9. Ste_ee

    Guest

    You may have been closer in your 2nd post, but it looks like you have too many delay elements, not too few! In the addition, you want to add the immediate result of the multiplication with the delayed result of the neighboring multiplication, however since both operands are flip-flip outputs it doesn't look like you're doing that. Either directly use the multiplication result (instead of storing it in a signal), or use a variable for the multiplication result, which will not create a register if it's assigned before it's used (google or look in your textbook for variables vs. signals).

    For the bit widths, it sounds like you haven't learned that yet, but I'm not sure how much help I can be since I've always had the luxury of using FPGA cores or DSP software libraries. However, some things to look at or try:
    1. Notice what happens when you multiply 2's complement integer numbers (try it with all combinations of positive/negative maximum values): you get 2 sign bits, feel free to throw one away, or use a fixed point library (google "vhdl fixed point").
    2. Put your coefficients into a spreadsheet and multiply each positive coefficient by the maximum positive input and each negative coefficient by the maximum negative input, then sum the results, that will give you the worst-case (though unlikely) # of bits required. Usually coefficients are scaled such that the worst-case result is the sum of the number of input + coefficient bits, or in your case 24. Try it first though, as I could be completely wrong. For your DAC output, yes, truncate the data using the most significant relevant bits.

    Other notes: if you reset the registers you can start seeing valid data (the impulse response which will be the coefficients) immediately, as opposed to 128 clock cycles of invalid data. Are you running the simulation long enough?
     
    , Oct 9, 2013
    #9
  10. Ste_ee

    Ste_ee Guest

    Il giorno mercoledì 9 ottobre 2013 14:08:12 UTC+2, ha scritto:
    > You may have been closer in your 2nd post, but it looks like you have toomany delay elements, not too few! In the addition, you want to add the immediate result of the multiplication with the delayed result of the neighboring multiplication, however since both operands are flip-flip outputs it doesn't look like you're doing that. Either directly use the multiplication result (instead of storing it in a signal), or use a variable for the multiplication result, which will not create a register if it's assigned before it's used (google or look in your textbook for variables vs. signals).
    >
    >
    >
    > For the bit widths, it sounds like you haven't learned that yet, but I'm not sure how much help I can be since I've always had the luxury of using FPGA cores or DSP software libraries. However, some things to look at or try:
    >
    > 1. Notice what happens when you multiply 2's complement integer numbers (try it with all combinations of positive/negative maximum values): you get 2 sign bits, feel free to throw one away, or use a fixed point library (google "vhdl fixed point").
    >
    > 2. Put your coefficients into a spreadsheet and multiply each positive coefficient by the maximum positive input and each negative coefficient by the maximum negative input, then sum the results, that will give you the worst-case (though unlikely) # of bits required. Usually coefficients are scaled such that the worst-case result is the sum of the number of input + coefficient bits, or in your case 24. Try it first though, as I could be completely wrong. For your DAC output, yes, truncate the data using the most significant relevant bits.
    >
    >
    >
    > Other notes: if you reset the registers you can start seeing valid data (the impulse response which will be the coefficients) immediately, as opposed to 128 clock cycles of invalid data. Are you running the simulation long enough?


    The numbers of bits of coefficients were been calculated in function of their maximum value, plus sign. But now i don't know more thing to do, i triedall delay and without delay, on input too, but on testbench i always have
    XXXXXXX1°coeff-2°coeff-3°coeff000000000000000 and never all coefficients.
    I tried to reset registers but i always have the same result. I did understand that the output of multiplier must to be synchronous with output of theadder, but i don't know thing to change more.
     
    Ste_ee, Oct 9, 2013
    #10
  11. Ste_ee

    Guest

    The multiplier outputs shouldn't be registered - only the adder outputs should be registered (assuming the input is properly synchronized). Note that every signal assignment in a clocked process will create a register. If youlook at a previous post (below), you're creating registers for sig_coeff(), delaymult1(), delaymult2() and sig_add(). However you only want to createregisters for sig_add() and use immediate values for everything else.

    > sig_coeff(i)<= input*coeff(i);
    >
    > delaymult1(i)<=sig_coeff(i);
    > delaymult2(i)<=delaymult1(i);
    >
    > if i = 127 then
    > sig_add(i)<= "000000000"& delaymult2(i);
    > else
    > sig_add(i)<=sig_add(i+1)+delaymult2(i);


    Is your testbench set up properly, e.g. same clock rate, etc.? I usually use something like this:

    input <= (others => '0');
    wait until rising_edge(clk);
    input <= "00000001";
    wait until rising_edge(clk);
    input <= (others => '0');

    And if I'm trying to wait for multiple clock periods, let's say 10:

    wait for CLOCK_PERIOD * 10;

    When looking at the simulation results, don't just look at the final output, also look at any intermediate result(s) you can find.
     
    , Oct 10, 2013
    #11
  12. Ste_ee

    Ste_ee Guest

    Il giorno giovedì 10 ottobre 2013 15:19:09 UTC+2, ha scritto:
    > The multiplier outputs shouldn't be registered - only the adder outputs should be registered (assuming the input is properly synchronized). Note that every signal assignment in a clocked process will create a register. If you look at a previous post (below), you're creating registers for sig_coeff(), delaymult1(), delaymult2() and sig_add(). However you only want to create registers for sig_add() and use immediate values for everything else.
    >
    >
    >
    > > sig_coeff(i)<= input*coeff(i);

    >
    > >

    >
    > > delaymult1(i)<=sig_coeff(i);

    >
    > > delaymult2(i)<=delaymult1(i);

    >
    > >

    >
    > > if i = 127 then

    >
    > > sig_add(i)<= "000000000"& delaymult2(i);

    >
    > > else

    >
    > > sig_add(i)<=sig_add(i+1)+delaymult2(i);

    >
    >
    >
    > Is your testbench set up properly, e.g. same clock rate, etc.? I usually use something like this:
    >
    >
    >
    > input <= (others => '0');
    >
    > wait until rising_edge(clk);
    >
    > input <= "00000001";
    >
    > wait until rising_edge(clk);
    >
    > input <= (others => '0');
    >
    >
    >
    > And if I'm trying to wait for multiple clock periods, let's say 10:
    >
    >
    >
    > wait for CLOCK_PERIOD * 10;
    >
    >
    >
    > When looking at the simulation results, don't just look at the final output, also look at any intermediate result(s) you can find.


    At the end i solved with structural description!!! :)
     
    Ste_ee, Oct 12, 2013
    #12
  13. Ste_ee

    Ste_ee Guest

    Il giorno giovedì 10 ottobre 2013 15:19:09 UTC+2, ha scritto:
    > The multiplier outputs shouldn't be registered - only the adder outputs should be registered (assuming the input is properly synchronized). Note that every signal assignment in a clocked process will create a register. If you look at a previous post (below), you're creating registers for sig_coeff(), delaymult1(), delaymult2() and sig_add(). However you only want to create registers for sig_add() and use immediate values for everything else.
    >
    >
    >
    > > sig_coeff(i)<= input*coeff(i);

    >
    > >

    >
    > > delaymult1(i)<=sig_coeff(i);

    >
    > > delaymult2(i)<=delaymult1(i);

    >
    > >

    >
    > > if i = 127 then

    >
    > > sig_add(i)<= "000000000"& delaymult2(i);

    >
    > > else

    >
    > > sig_add(i)<=sig_add(i+1)+delaymult2(i);

    >
    >
    >
    > Is your testbench set up properly, e.g. same clock rate, etc.? I usually use something like this:
    >
    >
    >
    > input <= (others => '0');
    >
    > wait until rising_edge(clk);
    >
    > input <= "00000001";
    >
    > wait until rising_edge(clk);
    >
    > input <= (others => '0');
    >
    >
    >
    > And if I'm trying to wait for multiple clock periods, let's say 10:
    >
    >
    >
    > wait for CLOCK_PERIOD * 10;
    >
    >
    >
    > When looking at the simulation results, don't just look at the final output, also look at any intermediate result(s) you can find.


    A the end i solved with structural description!! Thank you very much, really
     
    Ste_ee, Oct 12, 2013
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. dhaanya nair
    Replies:
    0
    Views:
    3,934
    dhaanya nair
    Feb 26, 2004
  2. mindenpilot

    Re: fir decimation filter in VHDL

    mindenpilot, Nov 19, 2005, in forum: VHDL
    Replies:
    1
    Views:
    2,414
    saras
    Nov 21, 2005
  3. Maarten
    Replies:
    5
    Views:
    3,407
  4. Emel
    Replies:
    0
    Views:
    3,659
  5. Emel
    Replies:
    0
    Views:
    913
Loading...

Share This Page