for language experts: RANGE TYPE

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
 
corrections:

On implementing the idea of a range-type with today's vhdl:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

concat_items(get_item_range(ref_item, 0)'range) -- item0

concat_items(get_item_range(ref_item, 1)'range) -- item1

concat_items(get_item_range(ref_item, 2)'range) -- item2
 
In the past, I've declared constant vectors with the ranges I needed,
and used them with the 'range attribute for this purpose. But (right
now) I can't put them in an array. On the other hand, with the upcoming
language additions to allow arrays of unconstrained arrays, that may be
possible.

subtype slv is std_logic_vector; -- abbreviation
constant item1_bits : slv(2 downto 0) := (others => '1');
constant item2_bits : slv(4 downto 3) := (others => '1');
constant item3_bits : slv(7 downto 5) := (others => '1');
....
item3 <= storage(item3_bits'range);

Or given the following deffinitions:

signal item1: slv(2 downto 0);
signal item2 : slv(4 downto 3);
signal item3 : slv(7 downto 5);

then the following is possible:

item1 <= storage(item1'range);

or

storage(item1'range) <= item1;

Or just use aliases...

If you really need the range information in an array, you might try a
record of left and right indices, and put that in an array, such that
you could:

for i in item'range loop
storage (item_range(i).left downto item_range(i).right) <= item(i);
-- or
item(i) <= storage(item_range(i).left downto item_range(i).right);
end loop;

Depending on how far they implement arrays of unconstrained arrays,
that may provide what you need, without an entirely new concept of a
range specification as a datatype.

Andy
 
Andy wrote:
In the past, I've declared constant vectors with the ranges I needed,
and used them with the 'range attribute for this purpose.
I like to use generic constants from the port
vector lengths in process subtypes and arrays of subtypes.

If you really need the range information in an array, you might try a
record of left and right indices, and put that in an array
Yes, or 'left to 'right of an enumeration type works also.

-- Mike Treseler
_____________________
subtype ALUSLV is std_logic_vector(7 downto 0);
type ALUTyp is (AD, ADC, SU, SUC, CM, CMC, AN, LOR, LXR, SR, SC, AER);

type ALUstyles is array (ALUTyp'left to ALUTyp'right) of ALUSLV;
constant init : ALUstyles := (AD => x"42", ADC => x"ff",
others => x"00");
 

Welcome to EDABoard.com

Sponsor

Back
Top