Guest
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
==================================================================
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