SystemVerilog queue initialization using ncverilog +sv?

S

Steven Wilson

Guest
I have a question for the assembled masses.

I have a declaration similar to the following:

integer my_q[$] = {1,2,3,4,5,6};

This is accepted by Modelsim using the -sv switch.

If I compile this with ncverilog +sv I get the following gripes:

ncvlog: *E,TYCMPAT (queue.sv,5|18): assignment operator type check
failed (expecting datatype compatible with 'queue of integer' but
found 'packed array' instead).
integer my_q[$] = {1,2,3,4,5,6};
|
ncvlog: *E,NONOWD (queue.sv,5|19): Illegal use of a constant without
an explicit width specification [4.1.14(IEEE)].
integer my_q[$] = {1,2,3,4,5,6};
etc...

Any suggestions as to what I'm doing wrong here?

Thanks!

Steve Wilson

--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
 
On Mon, 08 Mar 2010 13:29 -0800, Steven Wilson wrote:

I have a question for the assembled masses.
heh. That's one of those "I'm glad you asked
that" questions.... apologies for the ensuing
prolix outpourings.

I have a declaration similar to the following:

integer my_q[$] = {1,2,3,4,5,6};

This is accepted by Modelsim using the -sv switch.
Sure it's SystemVerilog, so you would expect to
need either -sv or a .sv file extension - and
similarly with NC.

If I compile this with ncverilog +sv I get the following gripes:

ncvlog: *E,TYCMPAT (queue.sv,5|18): assignment operator type check
failed (expecting datatype compatible with 'queue of integer' but
found 'packed array' instead).
integer my_q[$] = {1,2,3,4,5,6};
|
ncvlog: *E,NONOWD (queue.sv,5|19): Illegal use of a constant without
an explicit width specification [4.1.14(IEEE)].
integer my_q[$] = {1,2,3,4,5,6};
etc...

Any suggestions as to what I'm doing wrong here?
Your first mistake was to assume that the IEEE 1800-2005
definition of queue syntax makes sense :)

It's a long and messy story.

As you probably know, plain undecorated {} is used
for bit-vector concatenation in Verilog. When queues
and other exotic species of array were introduced
in early versions of SV, there was obviously a need
to write literal array values; the {a,b,c,d} syntax
was dragooned into service to do this in the same way
that C does it. However, it very soon became clear
that this was a sure and rapid path to ruin, and a
new syntactic form was needed to write literal array
values. Consequently, the "assignment pattern" syntax
was invented:

int my_int_array[5] = '{1,2,3,4,5};

Note carefully the apostrophe before the opening
curly bracket. That turns the concatenation into an
"assignment pattern", which cunningly learns its
data type by looking across to the left-hand side
of the assignment = operator. So the assignment
pattern says "hey, I'm being assigned to an array
of 5 ints, so I'd better contain a comma-separated
list of five int-like things", and all is well.

UNFORTUNATELY... the 1800-2005 LRM left in place the
use of simple {} to write values of queue type. There
are many examples of this in the LRM; it's syntax stolen
directly from SV's predecessor Superlog. But the
1800-2005 language standard dismally fails to explain
what the blazes it's all about.

So there was a bit of a hoo-hah about this when SV was
up for revision (the 2009 standard is now out).
At least one vendor flatly, and not unreasonably, refused
to implement this weird unexplained syntax, as you have
discovered. Various weasels were employed to craft
appropriate words, and we invented a new syntax called
"unpacked array concatenation" to legitimize the syntax
that you're trying to use. Unpacked array concatenation
is now properly defined in 1800-2009, and it is quite
reasonable for you to start beating on vendors to support
it (you've already found one vendor that does so, at
least in simple cases).

Meanwhile you are slightly stuck if you want to use a
tool that doesn't support it. You can construct the
queue dynamically:

integer my_q[$];
my_q.push_back(1);
my_q.push_back(2);
my_q.push_back(3);
my_q.push_back(4);
my_q.push_back(5);

or reconstruct it from a fixed-size array:

integer my_q[$];
integer my_init_array[5] = '{1,2,3,4,5};
foreach (my_init_array) my_q.push_back(my_init_array);

or various other solutions. 1800-2009 makes all this a lot
tidier, but you may have to wait a while for full support.

I will try to write up an appnote-style description of
unpacked array concatenation somewhere, soon; it's a very
useful construct, and deserves to be widely known so that
people start demanding it from their vendors.
--
Jonathan Bromley
 

Welcome to EDABoard.com

Sponsor

Back
Top