Alias of two std_logic_vector elements of an array

Discussion in 'VHDL' started by hhanff, Aug 20, 2010.

  1. hhanff

    hhanff Guest

    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
    hhanff, Aug 20, 2010
    #1
    1. Advertising

  2. 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
    Jonathan Bromley, Aug 20, 2010
    #2
    1. Advertising

  3. hhanff

    hhanff Guest

    On Aug 20, 2:20 pm, Jonathan Bromley <>
    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
    hhanff, Aug 23, 2010
    #3
  4. 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 8) = 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
    Jonathan Bromley, Aug 23, 2010
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Khashishi
    Replies:
    3
    Views:
    5,610
    Weng Tianxiang
    Sep 22, 2004
  2. Tom
    Replies:
    1
    Views:
    402
    Michiel Salters
    Jul 4, 2003
  3. Thomas Rouam
    Replies:
    6
    Views:
    1,116
  4. grocery_stocker
    Replies:
    9
    Views:
    735
    grocery_stocker
    May 24, 2008
  5. Colin Beighley

    Alias array / array of aliases

    Colin Beighley, Oct 5, 2011, in forum: VHDL
    Replies:
    12
    Views:
    1,604
    Tricky
    Oct 14, 2011
Loading...

Share This Page