Array sum() method issue

Why am I getting a value of 1 for the final sum statement?

int numbers[] = '{1,4,7,3,10,55,36,10,3};
  int y;

  y=numbers.sum();
  $display("sum()=%0d",y);
    
  y=numbers.sum with (item>5);
  $display("sum with (item>5)=%0d",y);

KERNEL: sum()=129

KERNEL: sum with (item>5)=1 <------ 1?

In reply to bmorris:
It would help if you stated what output value you were expecting.

If you want a count of then number of elements greater than 5, then you need to write

y=numbers.sum with (int'(item>5));

That’s because the type of item>5 is a 1-bit expression, and sum of 1-bit expressions is a 1-bit result.

If you want the sum of elements whose values are greater than 5, then you need to write

y=numbers.sum with (item>5?item:0);

In reply to bmorris:

(item > 5) is returning a 1-bit number that is continually added as a 1-bit number. If you want the number of elements greater than 5, use:

y = numbers.sum with (int'(item > 5));

In reply to dave_59:

My fault.

My intention was to add up all the numbers, but only including those which were greater than 5. The result I was looking for was 118.

edit: just saw your solution. Ill do that.
y=numbers.sum with (item>5?item:0)

thanks for the help

In reply to dave_59:

If you want a count of then number of elements greater than 5, then you need to write

y=numbers.sum with (int'(item>5));

That’s because the type of item>5 is a 1-bit expression, and sum of 1-bit expressions is a 1-bit result.

This whole casting thing is ridiculous, since this is what users usually want and forget, leading to these kinds of questions on forums. I’d like to hear a compelling reason why the language designers specified things this way.

In reply to Tudor Timi:
Because the language is designed to execute what you wrote, not what you wanted to write. SystemVerilog may not be the strongest typed language out there, but it does have fixed set of rules for determining bit lengths. If we start changing the rules for every situation we think the user wants, the LRM would become exponentially bigger than it already is. And just look how sbellock misinterpreted what they thought bmorris wanted.

In reply to dave_59:

In reply to Tudor Timi:
Because the language is designed to execute what you wrote, not what you wanted to write. SystemVerilog may not be the strongest typed language out there, but it does have fixed set of rules for determining bit lengths. If we start changing the rules for every situation we think the user wants, the LRM would become exponentially bigger than it already is. And just look how sbellock misinterpreted what they thought bmorris wanted.

I’m not debating “executing what you wrote”. I’m debating the way sum() is defined:

sum() returns the sum of all the array elements or, if a with clause is specified, returns he sum of the values yielded by evaluating the expression for each array element.

The way people interpret a with syntax on first glance (without looking into the LRM) is that it sums all elements of the array for which the condition is true. I did this experiment with more of my colleagues who aren’t intimately acquainted with all LRM details and this was the exact answer I got. Forcing the current definition is the very reason such pitfalls exist, because it breaks the principle of least surprise.

Summing is one thing, applying a function on the values of an array is another thing. Summing the values resulted after applying a function on the values of an array is a cascade of the previous operations, which should be visible in the code. In e this would look like:


array.apply(<expression>).sum();

In reply to dave_59:

Also, I rushed my post yesterday and looked at the wrong thing. I didn’t mean to talk about the cast variant, which, as you correctly pointed, only counts the number of items that satisfy the expression. I meant to talk about the version with the ternary operator:


y=numbers.sum with (item>5?item:0);

which is what users usually want.

In reply to Tudor Timi:

My coworker also interpreted
y=numbers.sum with (item>5);
as what actually happens with:
y=numbers.sum with (item>5?item:0);

The LRM does spell it out, of course. I think part of my problem was I was just done executing a bunch of find() operators, which returns a queue populated with items, so I presumed incorrectly that sum worked the same way.

“find() returns all the elements satisfying the given expression.”

“(sum) returns the sum of the values yielded by evaluating the expression for each array element”

Whatever; it is what it is.

In reply to bmorris:

That’s true, it’s much too late to change, but at some point we’ll move on from SystemVerilog to some other (probably totally new) language and I’d like it if we learned from the pain we had with this one.

In reply to dave_59:

i need to know why "int’ " is used there? Can I get reference from LRM?

In reply to sundarji:
Read the last paragraph of section 7.12.3 Array reduction methods.