component instance with different generic parameters

Z

zvonko.bostjancic

Hi

I do not have much expirience in VHDL and I'm stuck at (I hope) very
basic problem. I have this generic component (register):

COMPONENT reg
GENERIC (
data_width : integer := 32
);
PORT(
enable : IN std_logic;
clk : IN std_logic;
rst : IN std_logic;
load : IN std_logic;
data_in : IN std_logic_vector(31 downto 0);
data_out : OUT std_logic_vector(31 downto 0)
);
END COMPONENT;

Then I need two instances of the register, one 32-bit and one 16-bit.
When creating instance of 16-bit component, I get this error: "Width
mismatch. Expected width 32, Actual width is 16 for dimension 1 of
mem_out_adata."

MEMWB_ADATA: reg
GENERIC MAP (
data_width => 16
)
PORT MAP(
clk => clk,
rst => reset,
enable => enable,
load => mem_reg_we,
data_in => mem_out_adata,
data_out => wb_in_adata
);

Can anyone advise, please?


Best regards,
Zvonko
 
P

paragon.john

Hi

I do not have much expirience in VHDL and I'm stuck at (I hope) very
basic problem. I have this generic component (register):

COMPONENT reg
GENERIC (
data_width : integer := 32
);
PORT(
enable : IN std_logic;
clk : IN std_logic;
rst : IN std_logic;
load : IN std_logic;
data_in : IN std_logic_vector(31 downto 0);
data_out : OUT std_logic_vector(31 downto 0)
);
END COMPONENT;

Then I need two instances of the register, one 32-bit and one 16-bit.
When creating instance of 16-bit component, I get this error: "Width
mismatch. Expected width 32, Actual width is 16 for dimension 1 of
mem_out_adata."

MEMWB_ADATA: reg
GENERIC MAP (
data_width => 16
)
PORT MAP(
clk => clk,
rst => reset,
enable => enable,
load => mem_reg_we,
data_in => mem_out_adata,
data_out => wb_in_adata
);

Can anyone advise, please?

Best regards,
Zvonko

Try this,

COMPONENT reg
GENERIC (
data_width : integer := 32
);
PORT(
enable : IN std_logic;
clk : IN std_logic;
rst : IN std_logic;
load : IN std_logic;
data_in : IN std_logic_vector(data_width-1 downto 0);
-- replaced 31 with data_width-1
data_out : OUT std_logic_vector(data_width-1 downto 0)
-- replaced 31 with data_width-1
);
END COMPONENT;

Regards,
John
 
Z

zvonko.bostjancic

Try this,

COMPONENT reg
GENERIC (
data_width : integer := 32
);
PORT(
enable : IN std_logic;
clk : IN std_logic;
rst : IN std_logic;
load : IN std_logic;
data_in : IN std_logic_vector(data_width-1 downto 0);
-- replaced 31 with data_width-1
data_out : OUT std_logic_vector(data_width-1 downto 0)
-- replaced 31 with data_width-1
);
END COMPONENT;

Regards,
John

Hi

OMG. I feel soooooooo stupid. I don't know how i've missed such an
obvious flaw... I should be ashamed.


Thanks again,
Zvonko
 
M

Martin Thompson

Hi

I do not have much expirience in VHDL and I'm stuck at (I hope) very
basic problem. I have this generic component (register):

COMPONENT reg
GENERIC (
data_width : integer := 32
);
PORT(
enable : IN std_logic;
clk : IN std_logic;
rst : IN std_logic;
load : IN std_logic;
data_in : IN std_logic_vector(31 downto 0);
data_out : OUT std_logic_vector(31 downto 0)
);
END COMPONENT;

Then I need two instances of the register, one 32-bit and one 16-bit.
When creating instance of 16-bit component, I get this error: "Width
mismatch. Expected width 32, Actual width is 16 for dimension 1 of
mem_out_adata."

MEMWB_ADATA: reg
GENERIC MAP (
data_width => 16
)
PORT MAP(
clk => clk,
rst => reset,
enable => enable,
load => mem_reg_we,
data_in => mem_out_adata,
data_out => wb_in_adata
);

Can anyone advise, please?

John's solution is good, you could also try this, which gets rid of
the generic:
COMPONENT reg
PORT(
enable : IN std_logic;
clk : IN std_logic;
rst : IN std_logic;
load : IN std_logic;
data_in : IN std_logic_vector;
data_out : OUT std_logic_vector;
);
END COMPONENT;

As long as you don't want to use this as the top-level entity, you can
let the compiler figure out the widths for you. It'll even work for
vectors which don't go all the way to '0'!

On potential gotcha - you need to be aware that this component will accept both
"directions" of vector ("high downto low" and "low to high"), so if
you internals care about this, you need to handle it. For a simple
register (which I guess this is), there's now problem just copying
them around.

You can use things like:

signal internal_sig : std_logic_vector(data_in'range);
-- gets a vector the same length and direction as the input data

Cheers,
Martin
 
A

Andy

John's solution is good, you could also try this, which gets rid of
the generic:


As long as you don't want to use this as the top-level entity, you can
let the compiler figure out the widths for you. It'll even work for
vectors which don't go all the way to '0'!

On potential gotcha - you need to be aware that this component will accept both
"directions" of vector ("high downto low" and "low to high"), so if
you internals care about this, you need to handle it. For a simple
register (which I guess this is), there's now problem just copying
them around.

You can use things like:

signal internal_sig : std_logic_vector(data_in'range);
-- gets a vector the same length and direction as the input data

Cheers,
Martin

Martin has some very good points. If you look at the standard packages
(like numeric_std), which define functions and operators on
unconstrained vector arguments, you'll often see them "normalize" the
range of the argument in a temporary variable (you could do something
similar with a signal or alias in an architecture)

variable temp : std_logic_vector(data_in'length-1 downto 0) :=
data_in;

That way temp is a copy of data_in with a "downto 0" range.

This is a good practice to get into when using unconstrained arguments
or ports.

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

No members online now.

Forum statistics

Threads
473,962
Messages
2,570,134
Members
46,690
Latest member
MacGyver

Latest Threads

Top