Working with multi-dimensional associative arrays

Hello,

I read a post about initializing multi-dimensional associative arrays in this forum.

It said we can do something like this,

string ARY[string][string] = ‘{“A”:’{“0”:“abc”, “1”:“def”}, “B”:'{“0”:“ghi”}};

I’m trying to do the following but it’s not getting compiled.

string ARY[string][string] = ‘{“A”:’{“0”:‘{“a”, “b”, “c”}, “1”:’{“d”, “e”, “f”}}, “B”:‘{“2”:’{“a”, “b”, “c”}, “3”:'{“d”, “e”, “f”}}};

Could anyone please suggest a right way to do this?

Thank you

These are assignment patterns that are explained in section 10.9 of the 1800-2012 LRM. The syntax you showed worked for me in Questa. Can you show us your compiler error?

Note that the inner most pair of '{}'s could be replaced with a simple concatenation.

string ARY[string][string] = '{"A":'{"0":{"a", "b", "c"}, "1":{"d", "e", "f"}}, "B":{"2":'{"a", "b", "c"}, "3":{"d", "e", "f"}}};

In this case, a concatenation has similar syntax to an assigment pattern without the keys.

In reply to dave_59:

Hi Dave,

This is the error I got from my compiler,
Assignment pattern - LHS must be an array or structure [SystemVerilog]. (Probably because it might not support latest SV constructs)

Also, I was trying something on www.edaplayground.com/

module integer_associative_array ();

  int  ARY[*][*] = 
'{
  "A19" : '{0:'{0,1,2,3} , 1:'{4,5,6,7}},
  "A33" : '{30:'{1,6,5,7} , 31:'{8,9,10,11}}
};
  
  initial begin
    
    $display ("value stored is %p", ARY["A19"][0]);
    
  end
  
endmodule

This gives me the following error, Error: testbench.sv(8): Illegal assignment pattern. The number of elements (4) doesn’t match with the type’s width (32).

Shouldn’t ARY[“A19”][0] return this array - {0,1,2,3} ?
Am I missing something?
Thank you

In reply to shailesh2490:

No, ARY[“A19”][0] should return a value of type int. Actually, int is equivalent to bit signed [31:0], which is packed array of 32 bits. An assignment pattern for this would have to be a list of 32 bits. You probably want to be using a concatenation the results in being 32-bits wide instead.

  int  ARY[string][int] = 
'{
  "A19" : '{0:{8'd0,8'd1,8'd2,8'd3} , 1:{8'd4,8'd5,8'd6,8'd7}},
  "A33" : '{30:{8'd1,8'd6,8'd5,8'd7} , 31:{8'd8,8'd9,8'd10,8'd11}}
};

You should never use the wildcard [*] index for an associative array. It is not type-safe and it limits you in terms of other SV constructs it can be used with (foreach loops, find methods).

1 Like

In reply to dave_59:

Some tools are treating array literal(one which is defined with '{}), concatenation( {}) in the same way.(I feel that mostly all tools does this)

First of all the array is two dimensional and the value stored is of type int. So VCS is printing concatenation equivalent value of {0,1,2,3} == 3 (because all 4 are int type and result should go to int type.)

Your tool is somewhat intelligent so it throwing an error. But that error is because of width mismatch. If you have following declaration in the inner brackets then i think you don’t even see the error.


{8'h01,8'h30,8'h10,8'h3};

So care must be taken while declaring array dimension.

In reply to Naven8:

{0,1,2,3} is illegal as a concatenation because the literals do not have an explicit size.

Yes, there cases where the functionality of an assignment pattern looks exactly like an array literal/concat. See Section 10.10.1 Unpacked array concatenations compared with array assignment patterns of the 1800-2012 LRM.

1 Like

In reply to dave_59:

Thank you Dave. Your suggestions were helpful.

In reply to shailesh2490:

Dave, Can you explain the difference between when to use array literal and how to use it.
The following snippet is returning same result with both array literal and concatenation


string A[3] = {"a","b","c"};
$display("Print A[0] = %s",A[0]);

or 
string A[3] = '{"a","b","c"};
$display("Print A[0] = %s",A[0]);

Result is: Print A[0] = a

In reply to Naven8:

Have you looked at section 10.10.1 of the LRM yet?

In reply to dave_59:

Thanks for the info Dave. I got the clear picture now.

In reply to Naven8:

Hello Dave,
The following code returns “0123” for ARY[“A19”][0]
and it gives the ASCII value of “0” for ARY[“A19”][0][0].

string  ARY[string][int] = 
'{
  "A19" : '{0:{"0","1","2","3"} , 1:{"4","1","7","3"}}
};

It doesn’t work the same way when I change the data type of the array elements to int, for example

int  ARY[string][int] = 
'{
  "A19" : '{0:{8'd0,8'd1,8'd2,8'd3} , 1:{8'd4,8'd5,8'd6,8'd7}}
};

ARY[“A19”][0] returns the concatenated value whereas ARY[“A19”][0][0] returns a wrong value.

Basically I want ARY[“A19”][0][0] to return integer 0 and ARY[“A19”][0][1] should return integer 1 and so on. Is there any way to access these innermost elements as an array?

In reply to shailesh2490:

Then you want an array with three dimensions, not two.

int  ARY[string][int][4] = 
'{
  "A19" : '{0:{8'd0,8'd1,8'd2,8'd3} , 1:{8'd4,8'd5,8'd6,8'd7}}
};
1 Like