what is incorrect about my usage of array with port entity?

B

brian_farmer

library ieee;
library work;
use ieee.std_logic_1164.all;

use ieee.numeric_std.all;


entity delay_line_interleaved is
generic(
numtaps : integer := 18;
wordlength_in : integer := 14;
coefflen : integer := 20
);
port(
-- INPUT PORTS --
clkin : in std_logic;
rst : in std_logic;
ena : in std_logic;
in_pddc : in std_logic_vector(wordlength_in-1 downto 0); --enough
bits here and other places to handle number of adds?
-- OUTPUT PORTS --
dv_out : out std_logic;
x_delay_line : out array (0 to coefflen-1) of
std_logic_vector(wordlength_in-1 downto 0)
);
end entity;
 
T

Tricky

library ieee;
library work;
use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

entity delay_line_interleaved is
        generic(
                numtaps         : integer := 18;
                wordlength_in   : integer := 14;
                coefflen                : integer := 20
                );
        port(
                -- INPUT PORTS --
                clkin           : in std_logic;
                rst                     : in std_logic;
                ena                     : in std_logic;
                in_pddc         : in std_logic_vector(wordlength_in-1 downto 0); --enough
bits here and other places to handle number of adds?
                -- OUTPUT PORTS --
                dv_out          : out std_logic;
                x_delay_line    : out array (0 to coefflen-1) of
std_logic_vector(wordlength_in-1 downto 0)
                );
end entity;

you cant just declare an array like that, you have to declare a type -
for this case you'll need to put it in a package:

type x_delay_line_t is array(integer range <>) of
std_logic_vector(wordlength_in-1 downto 0);

then you can declare your port:

x_delay_line : out x_delay_line_t(0 to cefflen-1)

unfortunately, you'll have to move wordlength_in to the package as a
constant instead of it being a generic on the entity.


Another thing I wonder- are you planning doing arithmatic with
in_pddc? why not use unsigned/signed types in the ports instead of
std_logic_vector and you wont have to do any type conversions.
 
B

brian_farmer

you cant just declare an array like that, you have to declare a type -
for this case you'll need to put it in a package:

type x_delay_line_t is array(integer range <>) of
std_logic_vector(wordlength_in-1 downto 0);

then you can declare your port:

x_delay_line : out x_delay_line_t(0 to cefflen-1)

unfortunately, you'll have to move wordlength_in to the package as a
constant instead of it being a generic on the entity.

Another thing I wonder- are you planning doing arithmatic with
in_pddc? why not use unsigned/signed types in the ports instead of
std_logic_vector and you wont have to do any type conversions.



Thank you for your help.

You can see the segment of code I used your suggestions with:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

package filter_coefficients is

constant wordlength_in : integer := 14;
constant filter_order : integer := 18;
constant coeff_len : integer := 12;
--constant coeff_len : integer := 20;
constant output_trun : integer := 10;
-- constant output_trun : integer := 0;
constant wordlength_out : integer := 12;
-- constant wordlength_out : integer := 40;

type reg_delay_line_type is array (0 to filter_order-1) of
signed(wordlength_in-1 downto 0);


library ieee;
library work;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.filter_coefficients.all;


entity delay_line_interleaved is
generic(
numtaps : integer := filter_order;
wordlength_in : integer := wordlength_in;
coeff_len : integer := coeff_len;
filter_order : integer := filter_order
);
port(
-- INPUT PORTS --
clkin : in std_logic;
rst : in std_logic;
ena : in std_logic;
in_pddc : in signed(wordlength_in-1 downto 0); --enough bits here
and other places to handle number of adds?
-- OUTPUT PORTS --
dv_out : out std_logic;
x_delay_line : out reg_delay_line_type
);
end entity;



And why did I do it the way that I did it? Because I don't know as
much as you. I have mostly taught myself with one Xilinx class in
Class about 10 years ago.

Do you have a book that you would recommend?
 
A

Andy

There are multiple ways to handle this.

One is to put all the constants in the package, where they are in one
place when you need to change them. You don't really need generics in
this case, since the package constants give you the same information.
Consider if the generic is assigned a different value in the
instantiation, changing your package constant values will have no
effect.

Another way is to use the package only for those things that cannot be
done with generics. (for instance, the size of the words in the array
definition).

Another is to use generics for things like filter order, etc. but use
unconstrained types for the ports (you still have to constrain the
word length in the array). Then your archtecture can determine the
width of ports based on the length of the signal bound to the port
(i.e. port_name'length). You can also make the array index
unconstrained, even though you must constrain the size of the elements
in the array.

If you know your data types will not exceed 31 bits (unsigned), then
you could use integer subtype ports, and an array of integer words.
You would need generics to tell you the effective length of the
integer subtypes.

You can also use an unconstrained SLV (or signed/unsigned), the
dimension of which is the product of the number of words and the
length of the words. This can be calculated from generics, and no
package is necessary, but you would have to use conversion functions
inside and outside the architecture to convert back and forth between
the big SLV and the array of smaller SLVs.

In addition to declaring ports as numeric_std.(un)signed, you could
also use the fixed point types if you will be using fixed point
arithmetic in your delay line/filter.

Experience and personal taste can guide you to which of these
techniques (or combination thereof) you want to use.

Andy
 
T

Tricky

... no, you can simply use the attribute "delay_word'length" inside, then
eliminate the generic altogether. Then it's impossible to accidentally change
the port width without changing the generic, or vice-versa.

Here I really meant that you are forcing all your instantiations to
have arrays of fixed length data type, the data type length inside the
array cannot change from instance to instance. Although not really
used, by many, it could be useful.
 
A

Andy

There are multiple ways to handle this.

One is to put all the constants in the package, where they are in one
place when you need to change them. You don't really need generics in
this case, since the package constants give you the same information.
Consider if the generic is assigned a different value in the
instantiation, changing your package constant values will have no
effect.

Another way is to use the package only for those things that cannot be
done with generics. (for instance, the size of the words in the array
definition).

Another is to use generics for things like filter order, etc. but use
unconstrained types for the ports (you still have to constrain the
word length in the array). Then your archtecture can determine the
width of ports based on the length of the signal bound to the port
(i.e. port_name'length). You can also make the array index
unconstrained, even though you must constrain the size of the elements
in the array.

If you know your data types will not exceed 31 bits (unsigned), then
you could use integer subtype ports, and an array of integer words.
You would need generics to tell you the effective length of the
integer subtypes.

You can also use an unconstrained SLV (or signed/unsigned), the
dimension of which is the product of the number of words and the
length of the words. This can be calculated from generics, and no
package is necessary, but you would have to use conversion functions
inside and outside the architecture to convert back and forth between
the big SLV and the array of smaller SLVs.

In addition to declaring ports as numeric_std.(un)signed, you could
also use the fixed point types if you will be using fixed point
arithmetic in your delay line/filter.

Experience and personal taste can guide you to which of these
techniques (or combination thereof) you want to use.

Andy

I forgot to mention that when you use a package that is tightly
associated with an entity/architecture, put the package at the top of
that file that contains the entity and architecture. This way, they
get compiled together (at the same time, not into one object), and are
always available together. If you use configurations and component
declarations, you can also put the component declaration in that
package. Whatever architecture is instantiating the component will
need to reference the package for the types anyway, so it might as
well get the component declaration from there too.

Andy
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,024
Latest member
ARDU_PROgrammER

Latest Threads

Top