FIR Filter Transposed Form VHDL

S

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;
 
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;
 
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;
 
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?
 
On Tuesday, October 8, 2013 11:04:30 AM UTC-4, 1999o...@gmail.com 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 multiplication results.
 
Il giorno martedě 8 ottobre 2013 17:43:12 UTC+2, 1999o...@gmail.com ha scritto:
On Tuesday, October 8, 2013 11:04:30 AM UTC-4, 1999o...@gmail.com 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 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!!
 
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, 1999o...@gmail.com ha scritto:

On Tuesday, October 8, 2013 11:04:30 AM UTC-4, 1999o...@gmail.com 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 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!!

I tried to implement delay chain after multiplication, but i see always the first 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);
 
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?
 
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?
 
Il giorno mercoledě 9 ottobre 2013 14:08:12 UTC+2, 1999o...@gmail.com ha scritto:
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?

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 tried all 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 the adder, but i don't know thing to change more.
 
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.
 
Il giorno giovedě 10 ottobre 2013 15:19:09 UTC+2, 1999o...@gmail.com 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!!! :)
 
Il giorno giovedě 10 ottobre 2013 15:19:09 UTC+2, 1999o...@gmail.com 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
 

Welcome to EDABoard.com

Sponsor

Back
Top