for language experts: Constants defined in an entity visible in all deeper inner entities

A

albert.neu

Constants defined in an entity visible in all deeper inner entities
===================================================================


Current VHDL:
A constant defined in an entity is only visible in that same entities
architecture and not in deeper inner entities!

entity test_top is

generic (
g_custom : integer);

constant c_from_top : integer := g_custom;

end test_top;




Why do we need this?
=================================================

There is a need for entities to have constants that are visible in all
deeper inner entities (& assoc. architectures)


Consider a
design with a deep hierarchy of levels:

level1 has a component-instance called level2
level2 has a component-instance called level3


entity level1 is
generic (g_abc : ...);
port ();
end level1;

architecture rtl of level1 is
begin
inst_level2: level2
generic map (g_abc => g_abc)
port map ();
end rtl;

entity level2 is
generic (g_abc : ...);
port ();
end level2;

architecture rtl of level2 is
begin
inst_level3: level3
generic map (g_abc => g_abc)
port map ();
end rtl;




This design has all the necessary generics, that can be set in level1.
The generics of level1 (g_abc) are propagated to all other levels (via
the above "generic map(g_abc => g_abc)"), so that everything is
correctly set up.


Now level1 to level3 are reusable:
(Let's say, that: )To reuse it (for a new design), all we need, is

to specify our CUSTOM component in level3!



OK. So now within level3 (deep down in the design), we include some
CUSTOM component instance:
Sometimes we want CUSTOMcomp1, sometimes CUSTOMcomp2, both with
*different generics* (e.g. integer vs std_logic)

entity level3 is
generic (g_abc : ...);
port ();
end level3;

architecture rtl_v1 of level3 is
begin
inst_component_with_new_generics1: CUSTOMcomp1
generic map (g_cus1 => ) -- set this generic! but where?
port map ();
end rtl;

architecture rtl_v2 of level3 is
begin
inst_component_with_new_generics2: CUSTOMcomp2
generic map (g_cus2 => )
port map ();
end rtl;




Here's the problem:
in our final design, we want:

level1-level2-level3-CUSTOMcomp1(with g_cus1 = 1)

and

level1-level2-level3-CUSTOMcomp1(with g_cus1 = 2)

and

level1-level2-level3-CUSTOMcomp2(with g_cus2 = '0')

and

level1-level2-level3-CUSTOMcomp2(with g_cus2 = '1')


(And we don't won't to have a lot of similar files copied, with only
minor changes!)



Consider:
level1-level2-level3-CUSTOMcomp1

We need to set the innermost generic: g_cus1
We cannot use some global constant in some package global_pack, to set
the generic,
because we want 2 instances of
level1-level2-level3-CUSTOMcomp1,
where each instance has its own (different) generic-definition (the one
instance: g_cus1 = 1; the other: g_cus1 = 2 -> see above)!

solution:
In order to set the generic (g_cus1), we would have to propagate it
through from level1!
But then we would *edit the source* of level1 to level3 to include a
way to propagate this generic (g_cus1) down from the top!

still a problem:
But we said, that we have different CUSTOM components, with *different
generics*:
level1-level2-level3-CUSTOMcomp1(with g_cus1 - integer)
level1-level2-level3-CUSTOMcomp2(with g_cus2 - std_logic)

So now we want to be able to propagate:
integer (for g_cus1 of CUSTOMcomp1)
std_logic (for g_cus2 of CUSTOMcomp2)

This is a big PROBLEM:
======================
We cannot propagate g_cus1 (an integer) and then reuse level1 to level3
and propagate g_cus2 (std_logic)
(In particular: we do *not* want to need to edit the source of level1
to level3, since that is our reusable part)
Hmmmm ...
We need a *different way* to propagate constants from the top, to an
inner component:









Here's a possible solution (VHDL language revision: let's go!)
==============================================================
==============================================================
Put a wrapper around level1-level2-level3-CUSTOMcomp1:
call it top1

entity top1 is
generic (g_abc : ...)
const_vis_lower (c_from_top1 : integer); -- visible in all deeper
inner components
port ();
end top1;


Put another wrapper around level1-level2-level3-CUSTOMcomp2:
call it top2

entity top2 is
generic (g_abc : ...)
const_vis_lower (c_from_top2 : std_logic); -- visible in all deeper
inner components
port ();
end top2;

A new keyword "const_vis_lower" (see above) introduces constants, that
can be used in deeper inner levels!



Now we change the 2 architectures from above:


use work.top1_const_vis_lower.all;
architecture rtl_v1 of level3 is
begin
inst_component_with_new_generics1: CUSTOMcomp1
generic map (g_cus1 => c_from_top1)
port map ();
end rtl;

use work.top2_const_vis_lower.all;
architecture rtl_v2 of level3 is
begin
inst_component_with_new_generics2: CUSTOMcomp2
generic map (g_cus2 => c_from_top2)
port map ();
end rtl;

As can be seen above, a package is included, to show the declaration of
the constant (c_from_top1, etc.): this constant will be obtained from a
higher outer level.

package top1_const_vis_lower is
const_vis_lower (c_from_top2 : std_logic);
end top1_const_vis_lower;

package top1_const_vis_lower is
const_vis_lower (c_from_top2 : std_logic);
end top1_const_vis_lower;

These packages again include the special directive "const_vis_lower",
so that when this package is used, the compiler knows the *type* of the
constant that will be passed from a higher outer level (similar to a C
header file!)








Something similar with todays VHDL
=================================================================

There is a dirty trick to do something similar with today's vhdl; but
it's *not* supported by synthesis tools:
configurations!!! (with generic_map_aspect and port_map_aspect)

Check out Synplicity FPGA Synthesis Reference Manual, December 2005
(reference.pdf), around page 10-65, to see how it's not supported!




architecture rtl of top_highest_lev is
begin -- rtl
gen_top: for iter in 0 to 3 generate
inst_level1: level1
generic map (g_abc => g_abc)
port map ();
end generate gen_top;
end rtl;
-- if iter = 0: level1-level2-level3-CUSTOMcomp1(with g_cus1 = 1)
-- if iter = 1: level1-level2-level3-CUSTOMcomp1(with g_cus1 = 2)
-- if iter = 2: level1-level2-level3-CUSTOMcomp2(with g_cus2 = '0')
-- if iter = 3: level1-level2-level3-CUSTOMcomp2(with g_cus2 = '1')

-- But how, where is the innermost generic set? In the configuration,
which
-- includes generic map:


configuration top_highest_lev_cfg of top_highest_lev is

for rtl


---------------------------------------------------------------------------
for gen_top (0)

for inst_level1 : level1
use entity work.level1(rtl);

for rtl

for inst_level2 : level2
use entity work.level2(rtl);

for rtl
for inst_level3 : level3
use entity work.level3(rtl_v1);

for rtl_v1
for inst_component_with_new_generics1: CUSTOMcomp1
use entity work.CUSTOMcomp1(rtl)
generic map (g_cus1 => 1)
port map ();
end for;
end for;
end for;
end for;
end for;

end for;
end for;

end for;


---------------------------------------------------------------------------
for gen_top (1)

for inst_level1 : level1
use entity work.level1(rtl);

for rtl

for inst_level2 : level2
use entity work.level2(rtl);

for rtl
for inst_level3 : level3
use entity work.level3(rtl_v1);

for rtl_v1
for inst_component_with_new_generics1: CUSTOMcomp1
use entity work.CUSTOMcomp1(rtl)
generic map (g_cus1 => 2)
port map ();
end for;
end for;
end for;
end for;
end for;

end for;
end for;

end for;


---------------------------------------------------------------------------
for gen_top (2)

for inst_level1 : level1
use entity work.level1(rtl);

for rtl

for inst_level2 : level2
use entity work.level2(rtl);

for rtl
for inst_level3 : level3
use entity work.level3(rtl_v2);

for rtl_v1
for inst_component_with_new_generics2: CUSTOMcomp2
use entity work.CUSTOMcomp2(rtl)
generic map (g_cus2 => '0')
port map ();
end for;
end for;
end for;
end for;
end for;

end for;
end for;

end for;


---------------------------------------------------------------------------
for gen_top (3)

for inst_level1 : level1
use entity work.level1(rtl);

for rtl

for inst_level2 : level2
use entity work.level2(rtl);

for rtl
for inst_level3 : level3
use entity work.level3(rtl_v2);

for rtl_v1
for inst_component_with_new_generics2: CUSTOMcomp2
use entity work.CUSTOMcomp2(rtl)
generic map (g_cus2 => '1')
port map ();
end for;
end for;
end for;
end for;
end for;

end for;
end for;

end for;

end for;

end top_highest_lev_cfg;
Constants defined in an entity visible in all deeper inner entities

Sample code for this trick:
http://stud4.tuwien.ac.at/~e0425408/vhdl/propagating_constants.zip
(will be removed sometime in the future...)




Comments welcome ...

Regards,
Albert Neumüller
 
A

albert.neu

The same arguments are also relevant to signals in a port!

entity top1 is
generic (g_abc : ...)
const_vis_lower (c_from_top1 : integer);
port (a_i : in std_logic);
port_vis_lower(
b_i : in std_logic;
b_o: out std_logic);
end top1;


(probably also possible with configurations...)

A solution other than configurations (like the port_vis_lower
suggestion) would be better though!



Regards,
Albert Neumüller
 
N

Nicolas Matringe

(e-mail address removed) a écrit :
Constants defined in an entity visible in all deeper inner entities [...]
Comments welcome ...


So, basically, you want to be able to plug different components in a
socket that fits only one of them. Seems a strange idea to me.

Nicolas
 
A

albert.neu

After going through the arguments again (and a lego analogy :) thanks
for listening, M. ), I now realize that a proper solution is in fact
possible with today's VHDL

For interested readers, here is the solution:
=============================================

The original argument made the assumption (an error by me! sorry!)
that the CUSTOM component is to be placed within level3.

However, there is no reason why it needs to be there!
So the solution to the problem, is to remove the CUSTOM components from
level3. level3 then passes it's inputs to the outside, where we can
plug in any desired CUSTOM component.

entity level3 is
generic (g_abc : ...);
port (in_i : ...;
out_i : ...);
end level3;

architecture rtl of level3 is
begin

out_i <= in_i;

end rtl;



Thus in essence we have a wrapper-component, that contains level1 (and
hence level2 and level3), and the CUSTOM component; and appropriate
connection-wires:



entity wrapper_level1_level2_level3_CUSTOMcomp1 is

generic (
g_abc: ...;
g_cus1 : integer);
port();

end wrapper_level1_level2_level3_CUSTOMcomp1;

architecture rtl of wrapper_level1_level2_level3_CUSTOMcomp1 is
begin

level1_level2_level3 : level1
generic map (g_abc => g_abc)
port map ();

inst_component_with_new_generics1: CUSTOMcomp1
generic map (g_cus1 => g_cus1);
port map (); -- inputs received from outputs of level1

end rtl;

______________________________________________________________________
|wrapper |
| _______ _______ _______ _______ |
| | | | | | | | | |
|---->----//|level1|//-->--//|level2|//-->--//|level3|-->--//| | |
| | | | | | | | | |
| ~~~~~~~~ ~~~~~~~~ ~~~~~~~~ | | |
| |CUSTOM| |
| | | |
|generic------------------------>----------------------------| | |
| | | |
| ~~~~~~~~ |
| |
| |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~




code:
http://stud4.tuwien.ac.at/~e0425408/vhdl/SOLUTIONpropagating_constants.zip


Regards,
Albert Neumüller
 
A

albert.neu

better sketch:

____________________________________________________________________
|wrapper ___________________________________ |
| |level1 _____________________ | ____________ |
| | |level2 _______ | | | | |
|---->--------|----->----|---->----|level3|---|--|---| | |
| | | ~~~~~~~~ | | | | |
| | ~~~~~~~~~~~~~~~~~~~~~~ | | | |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |CUSTOM comp| |
| | | |
|generic-------------------------->------------------| | |
| | | |
| ~~~~~~~~~~~~~ |
| |
| |
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-Albert
 
N

Nicolas Matringe

(e-mail address removed) a écrit :
After going through the arguments again (and a lego analogy :) thanks
for listening, M. ), I now realize that a proper solution is in fact
possible with today's VHDL

Glad I could help you see clearer :eek:)
My analogy was not meant to be Lego, just old electronics with DIP-14
74LSxx and sockets :eek:)

Nicolas
 
A

albert.neu

Since the pdf will not stay there for ever, here is the text:

We have a reusable component, consisting of level1, level2, lev2b,
level3 (including level3 processes).
To reuse it, we place our custom components into level3: This means
that we edit level3_custom_architecture.vhd to include out custom
components. (Via a configuration we can associate with the static
level3_entity.vhd, the correct custom architecture.)

Now we want to set custom generics in our custom components.
This is a problem: We want multiple instances of the whole design, and
hence have to set the generics from the outermost point. There are 3
possibilities:

Option 1. Use configurations (from the outside: for level1 for
level2 ...), specifying "generic map" for our custom components.
++Problem: This is not yet supported by synthesis tools (but works in
simulations tools)

Option 2. Edit all the sources, to be able to propagate the generics
into the inside (and finally to our custom components)
++Problem: One needs to edit the source code (which was meant to be
reusable)

Option 3. Create the reusable component in such a way, that the custom
components can be placed outside, form where generics can be assigned.
++Problem: Potentially large routing paths going all over the place.


Solution: Currently the only good solution is Option 2: to edit the
source in order to be able to propagate in the generics from the
outside. (Then level1-level2-... source code will be slightly different
for different designs in which the custom components have differing
generics)

Better solution: Get the synthesis tool people to support
configurations, and hence Option 1!

Regards,
Albert Neumüller
 

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,755
Messages
2,569,536
Members
45,009
Latest member
GidgetGamb

Latest Threads

Top