Welcome ! This website will help YOU (recent graduates/professionals) learn verification languages like SystemVerilog and UVM. Register for free and access more content !
2 minutes reading time (404 words)

Power of SystemVerilog Constraints

sv_power_of_constraints Use constraints to generate two queues with unique numbers and random size

SystemVerilog constraints are pretty amazing ! Lets see one use case where constraints are used to generate two queues of random sizes with unique values. Let us assume total number of elements in each queue should be less than or equal to 10.

Using a loooong way

Consider that both queues are part of a class called ABC. The first logical thing would be to decide the size of each queue which can be maintained in two separate variables that can be randomized. The constraints on these variables ensure that the total number of elements in each queue meets the requirement.

class ABC;
  int l_q[$];
  int l_q2[$]; 
 
  rand int l_q_size;
  rand int l_q2_size;
 
  constraint c_size { l_q_size inside {[1:9]};
                     l_q2_size inside {[1:10]};
                     (l_q_size + l_q2_size) <= 10;
                      l_q2_size >= 1;
                      solve l_q_size before l_q2_size;
                    }
endclass
 
module tb;
  initial begin
    ABC abc = new;
    abc.randomize();
    $display ("l_q_size=%0d l_q2_size=%0d", abc.l_q_size, abc.l_q2_size);
 
    for (int i = 0; i < abc.l_q_size; i++) begin
      int l_num;
      std::randomize(l_num) with { l_num inside {[1:10]};
                                  !(l_num inside {abc.l_q});
                                  };
      abc.l_q.push_back(l_num);
    end
 
    for (int i = 0; i < abc.l_q2_size; i++) begin
      int l_num;
      std::randomize(l_num) with { l_num inside {[1:10]};
                                  !(l_num inside {abc.l_q2, abc.l_q});
                                  };
      abc.l_q2.push_back(l_num);
    end
 
    $display("l_q=%p", abc.l_q);
    $display("l_q2=%p", abc.l_q2);
  end
endmodule
 

The class instance abc is randomized to decide on the size for each queue. That many number of elements can be randomized and pushed into the queue using a simple for loop. For each iteration, a local variable is randomized using the scope randomizer with inline constraints. These constraints ensure that unique elements are pushed into the queue and each element falls within the valid range.

In a similar way, the second for loop pushes a new set of elements into the second queue. Note that the inline constraint has also considered l_q or the first queue to keep elements unique between the two queues.

Using only constraint solver

This is the fastest way to generate two queues with unique data.

class ABC;
  rand int l_q[$];
  rand int l_q2[$];
 
  constraint c_q {   l_q.size() inside {[1:10]}; 
          foreach (l_q[i]) {
            l_q[i] inside {[1:10]};
            unique {l_q};
          }
        }
 
 constraint c_q2 {   l_q.size() + l_q2.size() inside {[1:10]};
          foreach (l_q2[i]) {
            l_q2[i] inside {[1:10]};
            unique {l_q, l_q2};
          }
        }
endclass
 
module tb;
  initial begin
    ABC abc = new;
    abc.randomize();
    $display("l_q=%p", abc.l_q);
    $display("l_q2=%p", abc.l_q2);
  end
endmodule
 

This could be your next interview question !

SystemVerilog Loops - when and where to use
The Art of Logging

Related Posts

 

Comments

No comments made yet. Be the first to submit a comment
Already Registered? Login Here
Guest
Tuesday, 23 April 2019

You consent to our cookies if you continue to use our website. To know more about cookies, see our privacy policy. I accept cookies from this site.

Agree