Array Method .sum() for multiple dimension array

Does this .sum() array method has limited to support multi-dimensional array?
I give a trial in my local : one work, one doesn’t

  1. under constraint block : supported

rand int box[][];

constarint c {
    box.sum() inside {[0:100]}; // works
}

  1. task / function body : NOT support

int box [3][3];
int val;

val = box.sum(); // compile fail

Error-[IAMC] Invalid array manipulation method call
my_tb.sv, 732
  Wrong usage of array manipulation method 'sum' as this method is not 
  supported on variable-size multidimensional arrays.


In reply to javatea:

The first should not have worked, unless the dimension sizes of the array were 0, then the resulting sum would be 0.

SystemVerilog has arrays of arrays where each array is a single unpacked dimension. To get the result you want, use

box.sum() with (item.sum());

In reply to dave_59:

Thank you, Dave.
I know LRM mentioned the answer you provide.
But it doesn’t work for Cadence or Synopsys compiler
I think they updated compiler to support following syntax, it works in my local and edaplayground website.
maybe you should update LRM, you are our Yoda.


class tmp;
    rand int box0[3][3];
    constraint c {
        foreach(box0[i,j]) {
            box0[i][j] inside {[0:10]};
        }
        box0.sum() inside {[1:10]};
    }
endclass

module automatic test;
  
  function void run;
    tmp tmp_h = new();
    tmp_h.randomize();
    $display("box0 = %p", tmp_h.box0);
  endfunction

  initial run();
  
endmodule

In reply to javatea:

Supporting different syntax for them same operator based on whether it’s used in a constraint or somewhere else does not make any sense to me.

In reply to dave_59:

Hi Dave,

Could you help me understand what is going wrong here?

module test();
 
class temp;
  rand int box[][];
 
  constraint c {
    box.sum() with (item.sum() with (item));
    box.size == 10;
    foreach(box[i,j]) {
      box[i][j] <= 5;
    }
  }
endclass
  
initial
	begin
      temp t = new();
      t.randomize();
      $display("var is %0d", t.box.size);
	end
 
endmodule
ncsim> run
    box.sum() with (item.sum() with (item));
          |
ncsim: *E,RNDCNSTE (./testbench.sv,7|10): Randomization constraint has this error, which will cause the randomize function to return 0 and no new rand values will be set:
Unsupported operator 'sum over upper dimension of multi-dimensional array' in this constraint expression.

In reply to kernalmode1:

Your simulator is what’s wrong. “Unsupported” messages mean the tool recognized the syntax, but has yet to implement it.

In reply to dave_59:

Ah, I see. Well, one can only get so much on edaplayground.

Thanks.

In reply to dave_59:

Hi Dave ,

It seems even on Latest Simulators :: 2D_Unpackd_Array.sum() with (item.sum() with (item));

as a Constraint Doesn’t work , but when used in a Procedural Context it runs properly

I have the following Code ::



class A;

rand bit [1:0]  A[][]; 

`ifdef M1

constraint SIZE_CONSTRAINT_1D { A.size()  == 9 ; }


constraint sum_constraint_2d {   foreach(A[i])
                                  {
			             A[i].sum() with ( int'(item) ) == 27 ;	  
				  }
			     }

				  
`endif

`ifdef S2 // Size for 2nd Dimension

constraint SIZE_CONSTRAINT_1D { A.size()  == 9 ; }

constraint S2_2d {       foreach(A[i])
                      {
		         A[i].size() == 2 ;	  
		      }
	         }

constraint sum_constraint_2d {   foreach(A[i,j])
                                  {
			             
                      A.sum() with ( item.sum() with ( int'(item) ) ) == 27 ; 
		     
				  }
			     }

`endif

// Either M1 or S2 Would be Active at a time 

endclass

A a1;


initial begin

a1 = new();


repeat(5)
begin

if ( a1.randomize() )
  $display("Success with %p",a1);
else
  $display("Fails with %p",a1);

end

end





Here is the Output ::

For +define+M1

Simulator1 :: 

Fails with '{A:'{}}
Fails with '{A:'{}}
Fails with '{A:'{}}
Fails with '{A:'{}}
Fails with '{A:'{}}


Simulator2 ::

Success with '{A:'{'{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}}}
Success with '{A:'{'{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}}}
Success with '{A:'{'{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}}}
Success with '{A:'{'{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}}}
Success with '{A:'{'{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}, '{}}}


[Q1] Is there anything wrong with the Code ?

Constraint A.size() == 9 would Make the 1st Dimension as 9 but the 2nd Dimension is not Sized

[Q2] How would constraint A[i].sum() with ( int’(item) ) == 27 be Calculated in this Case since 2nd Dimension isn’t Sized ?

[Q2.1] Also is it compulsory to write “item” , can’t I write anything else ?



Output For +define+S2 

With (a) 

Simulator1 : Works 

Simulator 2 and 3  :: Failure


[Q3] Is there any neat alternative for the 2 sizing Constraints :: SIZE_CONSTRAINT_1D and S2_2d ?

[Q3.1] I noticed A.size() with ( item.size() ) Doesn’t work .
Can with() Work with size() ?

[Q4] Any other way for Constraint :: sum_constraint_2d ? So that the Total sum is 27



Example :: constraint Functn_Call_in_Sum { A.sum() with (int'(item)) == SUMWA() ; } 

function int unsigned SUMWA ();
int unsigned sum1;

foreach(A[i,j])
sum1 = sum1+ A[j].sum with ( int'(item) ) ;

SUMWA = sum1;

endfunction


Regards,

AGIS

In reply to Etrx91:

  1. The correct result is randomize should fail. There are no elements to sum, so how could it ever equal 27?
  2. You are bitstream casting the 2nd dimension to an int. So if there were any elements in that dimension, they get concatenated to a single int
  3. The ()'s after sum is where you can change item. You can write
box.sum(item1d) with (item1d.sum(item2d) with (item2d));
  1. SystemVerilog does not really have multidimensional array, it has arrays of arrays. So there is no simpler way to size the dimensions.
  2. No.
  3. You can flatten your array to a single dimension.

In reply to kernalmode1:

I am trying to do something like this

    
constraint sum_c {
        m.sum() with (int'(item.sum() with (int'(item)))) == 30;
    }

but I get the following error message –
Unsupported operator ‘sum over upper dimension of multi-dimensional array’ in this constraint expression.

Looks like even the industry wide simualtors dont have this supported :(

In reply to Jako:

Works with Questa on EDAPlayground. This example has been in the LRM since 1800-2009.

In reply to dave_59:

But same code will not work in VCS: 2D sum constraint(1) - EDA Playground
The working version for VCS is: 2D sum constraint(2) - EDA Playground

.sum() for multi dimension array is a very useful feature. Hope different simulator can consolidate the syntax.

In reply to wyc123:

That is a tool bug. See 2D array constraint randomization | Verification Academy