Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Alias of two std_logic_vector elements of an array

Reply
Thread Tools

Alias of two std_logic_vector elements of an array

 
 
hhanff
Guest
Posts: n/a
 
      08-20-2010
Hello!

I declared the following type and the corresponding signal:

type sd_card_data_a is array (natural range 527 downto 0) of
std_logic_vector(7 downto 0);
signal sd_card_data_as : sd_card_data_a;

What I can do now is create an alias for a single element of the
signal:

alias data_start_block_s : std_logic_vector(7 downto 0) is
sd_card_data_as(0);

What I can NOT do is defining an alias that spans several elements of
the array:

alias data_stuff_bytes_s : std_logic_vector(15 downto 0) is
sd_card_data_as(10 downto 9);

Even when I define a type for the alias:

type data_stuff_bytes_a is array (514 downto 513) of
std_logic_vector(7 downto 0);
alias data_stuff_bytes_s : data_stuff_bytes_a is sd_card_data_as(2
downto 1);

My questions are:
Did anybody understand my promblem?
Can anybody present a solution?

Greetings,

/h
 
Reply With Quote
 
 
 
 
Jonathan Bromley
Guest
Posts: n/a
 
      08-20-2010
On Fri, 20 Aug 2010 03:19:29 -0700 (PDT), hhanff wrote:

>type sd_card_data_a is array (natural range 527 downto 0) of
>std_logic_vector(7 downto 0);
>signal sd_card_data_as : sd_card_data_a;
>
>What I can do now is create an alias for a single element of the
>signal:
>
>alias data_start_block_s : std_logic_vector(7 downto 0) is
>sd_card_data_as(0);
>
>What I can NOT do is defining an alias that spans several elements of
>the array:
>
>alias data_stuff_bytes_s : std_logic_vector(15 downto 0) is
>sd_card_data_as(10 downto 9);


No, you can't - your alias must be an array of the same
element types as were in the original array.

>Even when I define a type for the alias:
>
>type data_stuff_bytes_a is array (514 downto 513) of
>std_logic_vector(7 downto 0);
>alias data_stuff_bytes_s : data_stuff_bytes_a is sd_card_data_as(2
>downto 1);


Different problem here. The alias must have the same
base type as the real object, I think. So you would
need something like this...

--- This one is just to reduce finger strain:
subtype byte is std_logic_vector(7 downto 0);

--- Generalised array type
type byte_array_t is array(natural) of byte;

--- Specialise it for your card_data array:
signal sd_card_data_as: byte_array_t(527 downto 0);

--- Now make your alias:
alias data_stuff: byte_array_t(514 downto 513)
is sd_card_data_as(2 downto 1);

I *think* that will work.... no time to check.

>Can anybody present a solution?


You will probably find it easier to write functions
and procedures to access groups of elements of the
array. For example, to read and write several
adjacent elements as if they were
a single wide vector:

function get_Nbytes(data: byte_array_t;
first_adrs: natural;
num_bytes: positive)
return std_logic_vector is
variable result:
std_logic_vector(8*num_bytes-1 downto 0);
begin
for i in 0 to num_bytes-1 loop
result(8*i+7 downto 8*i) := data(first_adrs+i);
--- puts first address into rightmost 8 bits
end loop;
return result;
end function;

The matching "put" procedure is left as an exercise...
--
Jonathan Bromley
 
Reply With Quote
 
 
 
 
hhanff
Guest
Posts: n/a
 
      08-23-2010
On Aug 20, 2:20*pm, Jonathan Bromley <(E-Mail Removed)>
wrote:
> On Fri, 20 Aug 2010 03:19:29 -0700 (PDT), hhanff wrote:
> >type sd_card_data_a is array (natural range 527 downto 0) of
> >std_logic_vector(7 downto 0);
> >signal sd_card_data_as : sd_card_data_a;

>
> >What I can do now is create an alias for a single element of the
> >signal:

>
> >alias data_start_block_s : std_logic_vector(7 downto 0) is
> >sd_card_data_as(0);

>
> >What I can NOT do is defining an alias that spans several elements of
> >the array:

>
> >alias data_stuff_bytes_s * *: std_logic_vector(15 downto 0) is
> >sd_card_data_as(10 downto 9);

>
> No, you can't - your alias must be an array of the same
> element types as were in the original array.
>
> >Even when I define a type for the alias:

>
> >type data_stuff_bytes_a is array (514 downto 513) of
> >std_logic_vector(7 downto 0);
> >alias data_stuff_bytes_s : data_stuff_bytes_a is sd_card_data_as(2
> >downto 1);

>
> Different problem here. *The alias must have the same
> base type as the real object, I think. *So you would
> need something like this...
>
> * --- This one is just to reduce finger strain:
> * subtype byte is std_logic_vector(7 downto 0);
>
> * --- Generalised array type
> * type byte_array_t is array(natural) of byte;
>
> * --- Specialise it for your card_data array:
> * signal sd_card_data_as: byte_array_t(527 downto 0);
>
> * --- Now make your alias:
> * alias data_stuff: byte_array_t(514 downto 513)
> * * * * * * * * * * is sd_card_data_as(2 downto 1);
>
> I *think* that will work.... no time to check.
>
> >Can anybody present a solution?

>
> You will probably find it easier to write functions
> and procedures to access groups of elements of the
> array. *For example, to read and write several
> adjacent elements as if they were
> a single wide vector:
>
> * function get_Nbytes(data: byte_array_t;
> * * * * * * * * * * * first_adrs: natural;
> * * * * * * * * * * * num_bytes: positive)
> * * * * * * * *return std_logic_vector is
> * * variable result:
> * * * * *std_logic_vector(8*num_bytes-1 downto 0);
> * begin
> * * for i in 0 to num_bytes-1 loop
> * * * result(8*i+7 downto 8*i) := data(first_adrs+i);
> * * * --- puts first address into rightmost 8 bits
> * * end loop;
> * * return result;
> * end function;
>
> The matching "put" procedure is left as an exercise...
> --
> Jonathan Bromley


Dear Jonathan!

Thanks for your quick reply. You were right in all points. I
implemented your advises today and exerything is fine now.
The solution to your exercise ahould be:

function put_Nbytes_f(data : std_logic_vector;
first_adrs : natural;
num_bytes : positive)
return byte_array_t is
variable result : byte_array_t(512 -1 downto 0);
begin
for i in 0 to num_bytes-1 loop
result(first_adrs+i) := data(8*i+7 downto 8*i);
--- puts 8 bit into rightmost rightmos byte
end loop;
return result(num_bytes-1 downto 0);
end function;

end package body sd_card_spi_wrapper_pack;


Yours,

/h
 
Reply With Quote
 
Jonathan Bromley
Guest
Posts: n/a
 
      08-23-2010
On Mon, 23 Aug 2010 05:00:00 -0700 (PDT), hhanff wrote:

>The solution to your exercise ahould be:
>
> function put_Nbytes_f(data : std_logic_vector;
> first_adrs : natural;
> num_bytes : positive)
> return byte_array_t is
> variable result : byte_array_t(512 -1 downto 0);
> begin
> for i in 0 to num_bytes-1 loop
> result(first_adrs+i) := data(8*i+7 downto 8*i);
> --- puts 8 bit into rightmost rightmos byte
> end loop;
> return result(num_bytes-1 downto 0);
> end function;


Yes, but that's probably a little inefficient - it
constructs the whole of "result" even if you use
only a tiny part of it. More important, though,
it has unnecessary arguments.

As an example, consider

mySig: byte_array_t(511 downto 0);
...
--- now we update just 2 words of it
mySig(5 downto 4) <= put_Nbytes(some_data, 4, 2);

Note how you are tempted to repeat the "start address"
on both sides. Indeed, the '4' argument to put_Nbytes
doesn't really do anything useful at all, and the '2'
length argument is unnecessary too. You could
mightily simplify it...

function to_bytes(data:std_logic_vector)
return byte_array_t is
constant nBytes: integer := data'length/8;
variable result: byte_array_t(nBytes-1 downto 0);
constant normalised:
std_logic_vector(data'length-1 downto 0)
:= data;
begin
assert (data'length mod = 0
report "Data should be a multiple of 8 bits"
severity error;
for i in 0 to nBytes-1 loop
result(i) := data(8*i+7 downto 8*i);
end loop;
return result;
end;

Now you could do
mySig(5 downto 4) <= to_bytes(X"CAFE");
mySig(13 downto 10) <= to_bytes(X"BAD4F00D");

Originally I was thinking, rather, of passing
the target array as an out or inout argument to
a procedure, so that it is passed by reference,
and then having the procedure update just the
necessary elements. However, this is less
convenient than the function because you need
two versions of the procedure - one to update
a signal result, and one to update a variable[*].
And you can't call any procedure from within
a function [**]. So, on balance, I like the function
version better.
[*] VHDL wishlist item: Some way of overloading
subprograms based on the class (signal vs other things)
of their arguments, so that you can write identical
procedures to update signals and variables. Today
you must create two procedures with different names.

[**] Another VHDL wishlist item: void functions to
encapsulate non-time-consuming activity whilst
permitting input, output and inout arguments.
Did that make it into VHDL-2008? I don't think so.
--
Jonathan Bromley
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Alias array / array of aliases Colin Beighley VHDL 12 10-14-2011 02:52 PM
Array of std_logic_vector Willem Oosthuizen VHDL 3 02-26-2010 12:27 AM
reference/alias in perl vs reference/alias in C++ grocery_stocker C++ 9 05-24-2008 04:32 AM
XP X64 Pro, IE7, Delphi 2007, IntraWeb, MS Access, ODBC Alias problem: Insufficient memory for this operation. Alias: SomeDatabase. Skybuck Flying Windows 64bit 13 01-09-2008 07:34 PM
inout std_logic_vector to array of std_logic_vector of generic length conversion... Thomas Rouam VHDL 6 11-09-2007 11:49 AM



Advertisments