What all can be Constrained?

Recently I asked myself apart from random / non-random class properties of a class what all can be constrained

(a) Can the value parameter of a Parameterized class be constrained ?
(b) Can the variables declared outside the class be constrained ?

So I made the following code ::


module What_Can_b_Constrained ;
   
   int Q = 20 , W = 30 ; // Variables outside class Scope 

   class Main #( int N = 10 , int M = 90 , parameter int A = 50 , parameter int B = 50 ) ; // Value Parameters
  
  
      constraint M_N { M + N == 100 ; } 
      
      constraint A_B { A + B == 100 ; } 
  
      constraint Q_W { Q + W == 50 ; } 


   endclass
  
    Main m ;

     initial begin

      m = new() ;

      if ( m.randomize() )
      begin
         $display("Success");
      end
     else
	   begin
         $display("Fails");
	   end

	end  
  endmodule


I see all 3 constraints work .
I went through SV LRM 18.5 :: " The constraint_block is a list of expression statements that restrict the range of a variable or define relations
between variables " .

    I have a few basic questions 

[1a] Are the value parameters also considered variables ?
[1b] Similar to a module parameter wouldn’t they be resolved at elaboration time and
hence be considered a non-variable ?
[2] Is there any difference between the following ::

 parameter int A = 50 / int A = 50 / parameter A = 50 
during declaration of a parameterized class ?

Would parameter A = 50 imply A to be signed integer ( 4-state data type ) ?

Thanks

In reply to ABD_91:

From annex P of the LRM “…constant: Either of two types of constants in SystemVerilog: elaboration constant or run-time constant.
Parameters and local parameters are elaboration constants. Their values are calculated before elaboration is
complete. Elaboration constants can be used to set the range of array types. Run-time constants are variables
that can only be set in an initialization expression using the const qualifier…”

In your example basically your stating 100==100, which holds true as they expression A+B is resolved in elaboration time to 100

HTH,

-R

In reply to rgarcia07:

Thanks , that answers 1(b) .

Any idea on 1(a) and 2 ?

In reply to ABD_91:

[i][1a] Are the value parameters also considered variables ?

I think what I showed from the LRM explains it, they are constants not variables, and they are resolved at elaboration time, in case of them depending on other parameters or functions like this:

 
                parameter int X = $clog2(Y);
                parameter bit [31:0] Z = X + Y;
                parameter int Y =  1024;

parameter int A = 50; // Creates a constant of type int with a value of 50
 int A = 50; //creates a variable of type int (signed) 
 parameter A = 50; // creates a parameter of type integer (four state variable 0-1-X-Z)I believe as SV has to have Verilog compatibility and int which is a two state value (0-1) is not supported in Verilog 

Regarding to the last one I think I read somewhere that in Verilog (not sure about SV) the type of the parameter is resolved from the value assigned if it was omitted. A Verilog parameter infers its type from its value — the myth that there is a default signed integer parameter type in Verilog – Brad Pierce's Blog

Not sure if this is correct or not as normally I specify the type of the parameter to avoid ambiguity

HTH,

-R

In reply to rgarcia07:
After doing an experiment with this code I get the following from one simulator

module test();
  parameter X = 50;
  parameter int Y = $clog2(X);
  parameter bit [31:0] Z =  X +Y;
  
  initial begin
    $display("X = %0d type = %s", X, $typename(X));
    $display("Y = %0d type = %s", Y, $typename(Y));
    $display("Z = %0d type = %s", Z, $typename(Z));
  end
endmodule

*# KERNEL: X = 50 type = reg[31:0]

KERNEL: Y = 6 type = int

KERNEL: Z = 56 type = bit[31:0]*