Problem populating a SLV using aggregates

A

alivingstone

I'm trying to populate a sparse SLV using aggregate notation, but it's
apparently not legal VHDL. Anyone have any ideas on how I could
implement the following snippet...

constant M1 : integer := 7; --marker1
constant M2 : integer := 80;

subtype DATA is std_logic_vector(31 downto 0);
constant D1 : DATA := x"00112233"; --data1
constant D2 : DATA := x"44556677";

subtype FRAME is std_logic_vector(0 to 1023);
constant F : FRAME := (
M1 to M1 + DATA'length => D1,
M2 to M2 + DATA'length => D2,
others => '0'
);

My intent is to populate only select portions of the large
std_logic_vector F and set the rest to '0'.

Much appreciated.
 
M

Mike Treseler

alivingstone said:
I'm trying to populate a sparse SLV using aggregate notation, but it's
apparently not legal VHDL. Anyone have any ideas on how I could
implement the following snippet...

constant M1 : integer := 7; --marker1
constant M2 : integer := 80;

subtype DATA is std_logic_vector(31 downto 0);
constant D1 : DATA := x"00112233"; --data1
constant D2 : DATA := x"44556677";

subtype FRAME is std_logic_vector(0 to 1023);
constant F : FRAME := (
M1 to M1 + DATA'length => D1,
M2 to M2 + DATA'length => D2,
others => '0'
);

My intent is to populate only select portions of the large
std_logic_vector F and set the rest to '0'.

Much appreciated.
library ieee;
use ieee.std_logic_1164.all;

package vec_array is
constant M1 : integer := 7; --marker1
constant M2 : integer := 80;

subtype data_t is std_logic_vector(31 downto 0);
constant D1 : data_t := x"00112233"; --data1
constant D2 : data_t := x"44556677";

type FRAME is array (0 to 1023) of data_t;
constant F : FRAME := (
M1 to M1 + data_t'length => D1,
M2 to M2 + data_t'length => D2,
others => (others => '0'));
end package vec_array;

-- Mike Treseler
 
A

alivingstone

Thanks Mike. What you posted would definitely work if I only equally
sized slices to insert into the FRAME array. Is there a way of
manipulating what you posted so that it could work for this too?

constant M1 : integer := 7; --marker1
constant M2 : integer := 80;
constant M3 : integer := 388;

subtype DATA is std_logic_vector(31 downto 0);
constant D1 : DATA := x"00112233"; --data1
constant D2 : DATA := x"44556677";

subtype DATA2 is std_logic_vector(1 to 24);
constant D3 : DATA2 := x"123456";

subtype FRAME is std_logic_vector(0 to 1023);
constant F : FRAME := (
M1 to M1 + DATA'length => D1,
M2 to M2 + DATA'length => D2,
M3 to M3 + DATA2'length => D3,
others => '0'
);
 
M

Mike Treseler

alivingstone said:
Thanks Mike. What you posted would definitely work if I only equally
sized slices to insert into the FRAME array. Is there a way of
manipulating what you posted so that it could work for this too?

Yes, but it's more trouble than it's worth.
Array elements have to be equal width.
How about zero filling:
constant D3 : data_t := x"00123456";

Or, if I used numeric_std.unsigned vectors,
I could use your 24 bit type and say

constant F : FRAME := (
M1 to M1 + len => D1,
M2 to M2 + len => D2,
M3 to M3 + len => resize(D3,len),
others => (others => '0'));

-- Mike Treseler
 
A

alivingstone

Yeah, I guess the other wrinkle is that I'm looking to place the data
markers throughout the frame at arbitrary locations. i.e. They won't
always fall on 32b boundaries. I guess I need to setup up some fancy
looping scheme to do this.

Thanks for the help.
 
K

Kenn Heinrich

alivingstone said:
Yeah, I guess the other wrinkle is that I'm looking to place the data
markers throughout the frame at arbitrary locations. i.e. They won't
always fall on 32b boundaries. I guess I need to setup up some fancy
looping scheme to do this.

Another option might be to use a function to compute an image of the
vector with just a single field filled in. The function would take a bit
index, and a std_logic_vector of your intended filler data, and return a
new frame type vector. Then just OR all these intitialized frame
vectors together. You can make your "make" initializaer function as
fancy as you want, to handle arbitrary bit offsets, add an argument to
repeat data, etc.

A rough sketch (treat as pseudocode only)

function make( offset_location : integer;
field_data : std_logic_vector)
return long_vector;

type lotta_vectors: array (1 to NUM_INITIALIZERS) of long_vector;

function long_or( x : lotta_vectors)
return long_vector;

constant frame :=
long_or (
( 1=> make (offset_1, filler_vector_1),
2=> make (offset_2, filler_vector_2),
NUM_INITIALIZERS=> make (offset_N, filler_vector_N));


Hope this helps,

- Kenn
 
J

JimLewis

Note that what you wrote will become legal in VHDL-2008. :)
So ask your vendors to support it.

I do something very similar to what Kenn did for this,
however, I would add a size field to the shift and fill function
(Kenn's make) and have the return value be std_logic_vector.
This way it does not need to know about frameType and can be
used for other frame sizes without modification.

function make( offset_location : integer;
field_data : std_logic_vector ;
size : natural
) return std_logic_vector ;


If you are working with the three objects that you proposed in your
2nd post,
constant M1 : integer := 7; --marker1
constant M2 : integer := 80;
constant M3 : integer := 388;


constant D1 : std_logic_vector := x"00112233";
constant D2 : std_logic_vector := x"44556677";
constant D3 : std_logic_vector := x"123456";

You don't need the "long_or" function. With std_logic_vector
(and its subtypes) use the "or" defined for std_logic_vector:

constant F : FrameType :=
make(M1, D1, FrameType'length) or
make(M2, D2, FrameType'length) or
make(M3, D3, FrameType'length) ;


If I needed to use the D1, D2, D3 in my testbench in different
places, I would not necessarily want to remember the corresponding
offset, and instead would define the constant to match the frame
size:

constant D1 : FrameType := make(7, x"00112233",
FrameType'length) ;


Cheers,
Jim
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top