1
votes

Let say I have these two classes:

class random_packet extends uvm_sequence_item;
    rand int cmd;
    ...
endclass

and its extension:

class good_packet extends random_packet;
    constraint good_constr {
    cmd inside {0,1,2};
    }
    ...
endclass

(Here I am not going to create good_packet object, but I just want to use its constraint as a reference) Then I instantiate random_packet object and randomize it:

random_packet pkt;
pkt = random_packet::type_id::create("pkt");
pkt.randomize();

My question: Is there a simpler way by utilizing its derived class good_packet's constraint to check whether the resultant pkt.cmd fall in category of good_packet constraint ? It would be better than writing redundant codes like:

if (pkt.cmd == 0 || pkt.cmd == 1 || pkt.cmd == 2) $display("good");
else $display("bad");
1

1 Answers

6
votes

You could copy the contents of pkt into a new packet of type good_packet and then check if the constraint holds.

First, you'll need a function that can update the fields of a good_packet based on the fields of a random_packet:

class random_packet extends uvm_sequence_item;
  // ...

  virtual function void update(random_packet source);
    this.cmd = source.cmd;
  endfunction
endclass

Using this function, you can update the fields of a good_packet that you've created earlier:

// ... randomization of 'pkt' happened earlier

good_packet g_pkt = new();
g_pkt.update(pkt);

Now that g_pkt contains the same values as pkt, you can use the inline constraint checker construct to check if the constraints defined in the good_packet class hold:

if (g_pkt.randomize(null))
  $display("good");
else
  $display("bad");

The call to randomize(null) won't actually randomize anything inside g_pkt (it's kind of like setting every field to rand_mode(0)).

You can find more info on this construct in section 18.11.1 In-line constraint checker of the IEEE 1800-2012 standard.