Constraints

why we cant use X (unknown) and Z (high-impedance) values in system verilog constraints?

Thanks Dave.

I have one more question: Why we are not used X(don’t care) and Z(impedance) value in constraints?

There is a built-in constraint solver in every simulator. IEEE 1800-2012 states that the constraint solve can only handle 2-value logic. In randomize function, the solver can’t solve if X or Z is used.

Let’s say we have following example:

rand logic a;
constraint c1 {a==0;}
constraint c2 {a==1;}

The constraint solver parses both the constraints concurrently. It uses an integer (seed value) to solve the constraint but sees a conflict while assigning values. Thereby resulting in solver error.

Since X is just an overlapping of 0 and 1, the constraint solver cannot generate both values at a time. Hence, X can not be generated.

But, you may use a following workaround in post_randomize function to get an X or Z value. Again, this is based on random generation of 0 or 1.

rand logic a;

function post_randomize();
  a = ($urandom_range(0,1)) ? ('x) : ('z); // Based on 0 or 1 generation
endfunction

In reply to sharvil111:

Hi sharvil111,

I was playing around with the above code and I was wondering why we need the additional system call ‘$urandom_range’ in the above code? Since that code is in the post_randomize function, the value of a would have already be randomized right? I quickly made the following code snippet.


module top();
  class A;
    rand logic a;

    function void post_randomize();
      a = a?'x:'z;
    endfunction : post_randomize
  endclass

  initial begin
    A a_h = new;
    a_h.randomize();
    $display(a_h.a); // This should give either x or z randomly.
  end

Also, to extend from the above problem, I thought I’ll randomize the variable ‘a’ in such a way that it gives out all combinations like 0,1,x,z. I was able to do this using a system call and an additional variable like so :


module top();
  class A;
    rand logic a;
    rand bit   ctrl;

    function void post_randomize();
      ctrl = $urandom_range(0,1);
      if(ctrl)
        a = a?'x:'z;
    endfunction : post_randomize
  endclass

  initial begin
    A a_h = new;
    a_h.randomize();
    $display(a_h.a); // This should give  x,z,0,1 randomly.
  end

But however, I tried to avoid system calls and use .randomize instead like so :


function void post_randomize();
  this.randomize(ctrl);  //This line gives an error
  if(ctrl)
    a = a?'x:'z;
endfunction : post_randomize

So when I try the above code, I get an error which says “Too many nested randomize calls will cause stack overflow”.

Can someone tell me how to get around this problem without using system calls or a more efficient way?

Thanks

In reply to szy0014:
There is no need to have any randomization in post_randomize(). Just use an enumeration to represent the additional X and Z states and use post_randomize() to convert the enum to the actual X and Z states.

typedef enum {S0, S1, SX, SZ} mvl4_t; // Multi-Value Logic 4 -states

class A
  rand mvl4_t Sa;
  logic a;
  rand bit ctrl;
  constraint a_unknown { if (ctrl) Sa inside {SX, SZ};
                            else   Sa inside {S0, S1}; }
  function void post_randomize;
    case (Sa)
    S0: a = '0;
    S1: a = '1;
    SX: a = 'X;
    SZ: a = 'Z;
    endcase
  endfunction
endclass



In reply to dave_59:

Yes. That works. Thanks Dave.

And I guess we don’t even need that extra variable anymore or that constraint (unless we want to particularly control the x and z generation). I modified the above code as follows:


typedef enum{s0, s1, sx, sz} mvl4_t;
class A
  rand mvl4_t sa;
       logic  a;

  function void post_randomize;
    case(sa)
      s0 : a = '0;
      s1 : a = '1;
      s2 : a = 'x;
      s3 : a = 'z;
    endcase
  endfunction
endclass

In reply to szy0014:

Yes you are correct. There’s no need of an extra system function call. Also Dave’s solution using an enum seems to be user friendly. The CTRL bit can itself be randomized in the main randomization hence it need not be re-randomized in post-randomization. Doing so will cause recursive call to randomize-post_randomize-randomize-post_randomize… functions. Henceforth the error.