Guest
Is there a range datatype in vhdl?
It's definately needed! (so revision... let's go!)
Why, for what would we need this?
->>
Consider an array that is a linear concatenation of items of different
lengths.
e.g.
--------------------------------------
signal item0 : std_logic_vector(1 downto 0);
-- item0'length = 2
signal item1 : std_logic_vector(2 downto 0);
-- item1'length = 3
signal item2 : std_logic_vector(10 downto 0);
-- item2'length = 11
--------------------------------------
Now suppose that we do not know before-hand who many items we're
dealing with, since this is set with a generic.
Then it is natural to store these items linearly in a vector (in
concatenated fashion):
--------------------------------------
signal concat_items : std_logic_vector(0 to 15);
-- concat_items <= item0 & item1 & item2;
--------------------------------------
If we want to refer to the items, the following definition would be
great (but it's not yet part of vhdl):
--------------------------------------
type ref_item_arr is array(natural range<> of RANGE_TYPE;
constant ref_item : ref_item_arr(0 to 2) : (RANGE_TYPE'(0 to 1),
RANGE_TYPE'(2 to 4),
RANGE_TYPE'(5 to 15),)
--------------------------------------
Now if we want to refer to one of our items in concat_items, we could
just use:
--------------------------------------
concat_items(ref_item(0)) -- item0
-- or
concat_items(ref_item(1)) -- item1
-- or
concat_items(ref_item(2)) -- item2
--------------------------------------
BUT FOR THIS A RANGE TYPE IS NEEDED!
{{{{ (ignore this)
An alternative would be an array of aliases:
alias_array item(0 to 2) : std_logic_vector concat_items(0 to 1), concat_items(2 to 4), concat_items(5 to 15))
is is also not yet supported, and probably never will; though the idea
might be stimulating.
}}}}
Implementing range type using today's VHDL and bursts of VHDL-code
trickery!
----------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
package range_pack is
subtype t_dummy is std_logic_vector;
type t_ref_item is record
start : integer;
stop : integer;
end record;
type t_ref_item_arr is array (natural range<> of t_ref_item;
function get_item_range (conc : t_ref_item_arr; item_num : integer)
return t_dummy;
end range_pack;
package body range_pack is
function set_to(i_left : integer; i_right : integer) return t_dummy
is
variable result : t_dummy(i_left to i_right);
begin
return result;
end set_to;
function set_downto(i_left : integer; i_right : integer) return
t_dummy is
variable result : t_dummy(i_left downto i_right);
begin
return result;
end set_downto;
function get_item_range (conc : t_ref_item_arr; item_num : integer)
return t_dummy is
begin
if conc(item_num).start <= conc(item_num).stop then
return set_to(conc(item_num).start, conc(item_num).stop);
else
return set_downto(conc(item_num).start, conc(item_num).stop);
end if;
end get_item_range;
end range_pack;
----------------------------------------------------
constant ref_item : t_ref_item_arr := ((0, 1), (2, 4), (5, 15));
signal concat_items : std_logic_vector(0 to 15);
Now if we want to refer to the items, just use:
concat_items(get_item_range(ref_item, 0)'range) -- item0
concat_items(get_item_range(ref_item, 1)'range) -- item0
concat_items(get_item_range(ref_item, 2)'range) -- item0
(This works fine in Modelsim, but last time I tried a similar idea
func_returns_array(...)'range
in synplify, it wasn't accepted)
Comments welcome...
Regards,
Albert Neumüller
It's definately needed! (so revision... let's go!)
Why, for what would we need this?
->>
Consider an array that is a linear concatenation of items of different
lengths.
e.g.
--------------------------------------
signal item0 : std_logic_vector(1 downto 0);
-- item0'length = 2
signal item1 : std_logic_vector(2 downto 0);
-- item1'length = 3
signal item2 : std_logic_vector(10 downto 0);
-- item2'length = 11
--------------------------------------
Now suppose that we do not know before-hand who many items we're
dealing with, since this is set with a generic.
Then it is natural to store these items linearly in a vector (in
concatenated fashion):
--------------------------------------
signal concat_items : std_logic_vector(0 to 15);
-- concat_items <= item0 & item1 & item2;
--------------------------------------
If we want to refer to the items, the following definition would be
great (but it's not yet part of vhdl):
--------------------------------------
type ref_item_arr is array(natural range<> of RANGE_TYPE;
constant ref_item : ref_item_arr(0 to 2) : (RANGE_TYPE'(0 to 1),
RANGE_TYPE'(2 to 4),
RANGE_TYPE'(5 to 15),)
--------------------------------------
Now if we want to refer to one of our items in concat_items, we could
just use:
--------------------------------------
concat_items(ref_item(0)) -- item0
-- or
concat_items(ref_item(1)) -- item1
-- or
concat_items(ref_item(2)) -- item2
--------------------------------------
BUT FOR THIS A RANGE TYPE IS NEEDED!
{{{{ (ignore this)
An alternative would be an array of aliases:
alias_array item(0 to 2) : std_logic_vector concat_items(0 to 1), concat_items(2 to 4), concat_items(5 to 15))
is is also not yet supported, and probably never will; though the idea
might be stimulating.
}}}}
Implementing range type using today's VHDL and bursts of VHDL-code
trickery!
----------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
package range_pack is
subtype t_dummy is std_logic_vector;
type t_ref_item is record
start : integer;
stop : integer;
end record;
type t_ref_item_arr is array (natural range<> of t_ref_item;
function get_item_range (conc : t_ref_item_arr; item_num : integer)
return t_dummy;
end range_pack;
package body range_pack is
function set_to(i_left : integer; i_right : integer) return t_dummy
is
variable result : t_dummy(i_left to i_right);
begin
return result;
end set_to;
function set_downto(i_left : integer; i_right : integer) return
t_dummy is
variable result : t_dummy(i_left downto i_right);
begin
return result;
end set_downto;
function get_item_range (conc : t_ref_item_arr; item_num : integer)
return t_dummy is
begin
if conc(item_num).start <= conc(item_num).stop then
return set_to(conc(item_num).start, conc(item_num).stop);
else
return set_downto(conc(item_num).start, conc(item_num).stop);
end if;
end get_item_range;
end range_pack;
----------------------------------------------------
constant ref_item : t_ref_item_arr := ((0, 1), (2, 4), (5, 15));
signal concat_items : std_logic_vector(0 to 15);
Now if we want to refer to the items, just use:
concat_items(get_item_range(ref_item, 0)'range) -- item0
concat_items(get_item_range(ref_item, 1)'range) -- item0
concat_items(get_item_range(ref_item, 2)'range) -- item0
(This works fine in Modelsim, but last time I tried a similar idea
func_returns_array(...)'range
in synplify, it wasn't accepted)
Comments welcome...
Regards,
Albert Neumüller