5

I noticed this interesting thing about the max() and min() functions in SV LRM (1800-2012) 7.12 (Array manipulation methods). I tried out the max() and min() functions in a dummy SV file

int a[3] = {0,5,5};
int q[$];
int b;
q = a.max(); // legal
b = a.max(); // illegal

The illegal statement error was

Incompatible complex type assignment
Type of source expression is incompatible with type of target expression.
Mismatching types cannot be used in assignments, initializations and
instantiations. The type of the target is 'int', while the type of the
source is 'int$[$]'.

So I commented out the illegal statement and tested it. It compiled and ran fine but I was hoping to get some more insight as to why the function returns a queue and not a single element - I printed out the contents of q and the size, but the size is still 1 and 5 is being printed just once. Kind of redundant then to make the max() and min() functions return a queue ?

Prashanth R
  • 95
  • 1
  • 2
  • 8

3 Answers3

6

The "SystemVerilog for Verification" book by Chris Spear and Greg Tumbush has a good explanation on this topic in Chapter 2.6.2, which I am quoting below:

"The array locator methods find data in an unpacked array. At first you may wonder why these return a queue of values. After all, there is only one maximum value in an array. However, SystemVerilog needs a queue for the case when you ask for a value from an empty queue or dynamic array."

AndresM
  • 1,293
  • 10
  • 19
2

It returns a queue to deal with empty queues and when the with () conditions have no matches. The the empty queue return is a a way to differentiate a true match from no matches.

Consider the below code. to find the minimum value of a that is greater than 5. a has data but none of its entries have above 5. b is empty, so it will return an empty. c will return 7.

int a[3] = '{0,5,5};
int b[$] = '{};
int c[4] = '{0,15,5,7};
int q[$];
q = a.min() with (item > 5); // no items >5, will return an empty queue
q = b.min();                 // queue is empty, will return an empty queue
q = c.min() with (item > 5); // will return a queue of size 1 with value 7
Greg
  • 18,111
  • 5
  • 46
  • 68
  • I tried running your example. Interestingly, q is not empty and contains 0, and the size is 1. Similarly, I tried the max() and q contained 0. I think if the 'with' condition fails, it just returns the minimum value present in the array. I am using VCS 2014 as my simulator. Similar with using a dynamic array, failing 'with' condition returns the minimum value and not empty queue. – Prashanth R Nov 16 '17 at 23:26
  • Performing a max() or a min() on an empty queue or empty unpacked array yielded a empty queue, so the return type of queue makes sense to me now. Thanks ! – Prashanth R Nov 16 '17 at 23:30
  • @PrashanthR same for `VCS R-2020.12-SP2-4_Full64` – BugKiller Jan 03 '22 at 06:27
0

I believe the example results as per Greg's answer is not correct.

As per System Verilog Language:

  • min() returns the element with the minimum value or whose expression evaluates to a minimum.

  • max() returns the element with the maximum value or whose expression evaluates to a maximum.

So, when with expression is evaluated, the resultant value will be:

a.min() with (item > 5); {0,0,0} -> Minimum is 0 and corresponding item is 5.
c.min() with (item > 5); {0,1,0,1}-> Minimum is 0 and corresponding item is 5.

Since, example demonstrates the usage of min, the result will be:

q = a.min() with (item > 5); // A queue of size 1 with value 5. 
q = c.min() with (item > 5); //A queue of size 1 with value 5.
Tomerikoo
  • 18,379
  • 16
  • 47
  • 61
  • No, both your and Gre's answer are NOT correct. As [Prashanth R](https://stackoverflow.com/questions/47338777/why-does-system-verilog-max-and-min-functions-return-a-queue-and-not-a-singl#comment81633964_47339711)'s comment, `q = a.min() with (item > 5);` return {0}, which is same with `q = c.min() with (item > 5);` This is due to `with` clause determine the index, i.e. **index 0** is selected – BugKiller Jan 03 '22 at 06:37