Systemverilog array: .sum(), but not sign-extension?

A

atass

Guest
I'm a lazy coder and want to use the intrinsic method ".sum()" to
tabulate the total of a 2D array.

logic signed [15:0] array [0:255]; // lots of widgets!

// the old fashioned way
logic signed [31:0] sum;
for ( int i = 0; i < $size(array); ++i )
sum = sum + array;

// the new and superior way
logic signed [31:0] sum;

sum = array.sum(); // INCORRECT RESULT!

----------------

Ok, after reading Chris Spear's "Systemverilog for Verification",
there was a warning against this gotcha. Basically, ".sum()"
performs the computation with fixed-precision (the width of the
parent array.) It does not 'sign-extend' the intermediate calculations
to the full-width of the LHS (lefthand side) variable.

Is this correct? If so, why was it done this way? It feels like
the ".sum()" method is not terribly useful :(
 
On Tue, 18 Nov 2008 23:23:22 -0800, "atass" <atass@lajta.com> wrote:

I'm a lazy coder and want to use the intrinsic method ".sum()" to
tabulate the total of a 2D array.
That's not lazy, that's "leverage" :)

; // lots of widgets!
logic signed [31:0] sum;

sum = array.sum(); // INCORRECT RESULT!

----------------

Ok, after reading Chris Spear's "Systemverilog for Verification",
there was a warning against this gotcha. Basically, ".sum()"
performs the computation with fixed-precision (the width of the
parent array.) It does not 'sign-extend' the intermediate calculations
to the full-width of the LHS (lefthand side) variable.

Is this correct? If so, why was it done this way? It feels like
the ".sum()" method is not terribly useful :(
There are various ways out. The 1800-2005 LRM is a bit vague
about it, but tool vendors have agreed on what should happen
and it is easy to get the "right" result.

You can use a "with()" expression on the reduction
method, and the self-determined type of that expression
sets the type of the calculation and the result. By using a size
cast you can easily set the result type to any width
you choose:

result = array.sum() with (64'(item));

Also, using a wider target for
the .sum() calculation should do the trick:

logic signed [63:0] long_result;
...
long_result = array.sum(); // Correctly widened

Of course, the usual SystemVerilog caveat applies:
not all tools correctly support this. In fact, I've
just run a few simple tests before writing this post
and they have given rise to <cough> some bug reports
to simulator vendors. Here's the tally:

simulator 1: all correct
simulator 2: syntax fully supported, but wrong results
(really, really badly wrong in many ways)
simulator 3: no support for .sum
simulator 4: no support for .sum, nor for
arrays as function args

My guess is that you're using simulator 2. I got the
same disastrously wrong answers in both the two most
recent releases; haven't tried the next-release beta yet.
Like I said, the bug report will be sent today :)
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
On Nov 19, 5:51 am, Jonathan Bromley <jonathan.brom...@MYCOMPANY.com>
wrote:
You can use a "with()" expression on the reduction
method, and the self-determined type of that expression
sets the type of the calculation and the result.  By using a size
cast you can easily set the result type to any width
you choose:

  result = array.sum() with (64'(item));
Yes, this is the appropriate way to do it.


Also, using a wider target for
the .sum() calculation should do the trick:

  logic signed [63:0] long_result;
  ...
  long_result = array.sum();  // Correctly widened
This is what he was already trying. His result variable was 32 bits,
while the elements he was summing were 16 bits.

This won't work. The result type of a function is not dependent on
the expression that it is used in. It is only dependent on the
definition of the function, even in this case where the function is
effectively being declared on the fly.

Verilog expressions with operators are very nice about doing this for
you, but a function is not an operator.
 
On Wed, 19 Nov 2008 18:54:05 -0800 (PST), sharp@cadence.com wrote:

  result = array.sum() with (64'(item));

Yes, this is the appropriate way to do it.

Also, using a wider target for
the .sum() calculation should do the trick:

  logic signed [63:0] long_result;
  ...
  long_result = array.sum();  // Correctly widened

This is what he was already trying. His result variable was 32 bits,
while the elements he was summing were 16 bits.

This won't work. The result type of a function is not dependent on
the expression that it is used in. It is only dependent on the
definition of the function, even in this case where the function is
effectively being declared on the fly.
Ah, never trust the empirical method over book-learning :)

Thanks for the correction. You are of course right, and
the improved description in the 2009 LRM draft makes this
unequivocally clear.

I couldn't remember the outcome of the IEEE discussions
on this, and the old 2005 LRM is not brilliantly clear
about it - after all, array reduction methods are
hardly ordinary functions, and indeed in the 'e'
language they are in fact macros rather than true
functions. So I resorted to trying it. Foolish me!
The only simulator I found that got .sum() even nearly
right was indeed widening the .sum() calculation to the
target width, at least for targets up to 256 bits wide
(I didn't have the stamina to try even wider targets).
Sounds like it's time for another bug report....
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 

Welcome to EDABoard.com

Sponsor

Back
Top