Constraint AND randomize with - whole queue value

Hi Dave,
Can you please help on this?

class bus_seq;
  rand bit queue_m[$]; 
  rand bit [3:0] lsize;
  
  constraint size_constriant {
    lsize == 6;
    queue_m.size() == lsize;
  }

endclass : bus_seq

module randm();

  bus_seq bs = new();

  initial begin
    $display(" --> initial queue_m = %p",bs.queue_m);
    //option 1. this obviously works
    //bs.randomize();             

    //option 2. this works , but I don't want for individual elements
    //as elements are interdependent for later use
    if (!bs.randomize() with {queue_m[0] == 1;
                              queue_m[1] dist {0 := 50, 1 := 50}; 
                              queue_m[2] dist {0 := 50, 1 := 50}; 
                              queue_m[3] dist {0 := 50, 1 := 50}; 
                              queue_m[4] dist {0 := 50, 1 := 50}; 
                              queue_m[queue_m.size()-1] == 0;})  
    $display("Randomize", "bs randomize() failed!!");

    //option 3. I need help here, this is not working ! assigning whole queue elements ?
    //I want to assigne whole queue as I want specific patterns - {1,0,1,0,1,0} or {1,1,0,0,1,0} or {1,0,1,1,0,0} or {1,1,1,0,0,0}
    //bs.randomize() with {queue_m == {{1,0,1,0,1,0};}                      //this dont work
    //bs.randomize() with {queue_m == {{1,0,1,0,1,0} or {1,1,0,0,1,0};}     //this dont work, I actually want this kind of values with or condition?!
    
    $display(" --> randomized queue_m = %p",bs.queue_m);
  end

endmodule : randm

Thank you.

In reply to megamind:

Below syntax also did not work!

bs.randomize() with {queue_m dist {'{1,0,1,0,1,0} := 50, '{1,1,0,0,1,0} := 50};}   //this dont work, I actually want this kind of whole queue assignment?!
bs.randomize() with {queue_m dist {{1,0,1,0,1,0} := 50, {1,1,0,0,1,0} := 50};}     //this dont work, I actually want this kind of whole queue assignment?!

In reply to megamind:

Below code also dont work, it seems that the simulator is not supporting this feature, as I am getting error for below simple assignment – This feature is currently not supported for queues, dynamic arrays, strings and associative arrays.

bs.randomize() with {queue_m == {1,0,1,0,1,0};};

Can I ask if this is supported as per LRM? i.e. constraining the whole queue values in one go?

In reply to megamind:

SystemVerilog constraints are restricted to integral expressions. If you just want to initialize a queue to a constant set of values, you can use randcase

randcase 
  50: queue_m = {1,0,1,0,1,0};
  50: queue_m = {1,1,0,0,1,0};
endcase

You can put this code inside pre/post_randomize() if needed.

In reply to dave_59:

Thank you very much Dave, you always have a solution :) I tried the suggested code in the post randomize and it works well.

Below is the code I tried,

  function void post_randomize();
    randcase
      25: begin
            queue_m = {1,1,0,0,1,0};
          end
      25: begin
            queue_m = {1,1,1,0,0,0};
          end
      25: begin
            queue_m = {1,0,1,0,1,0};
          end
      25: begin
            queue_m = {1,0,1,1,0,0};
          end
    endcase 
  endfunction : post_randomize

I have two follow up questions as below,

  1. minimum iterations required for randcase, to deliver appropriate results? or it is dependent on just the probability branches or weights and number of cases calculation.
  2. Also can you please point to relevant the LRM reference section for statement “SystemVerilog constraints are restricted to integral expressions.”

Thank you.

In reply to megamind:

See Randomisation_dist - SystemVerilog - Verification Academy and Distributed weightage constraint - SystemVerilog - Verification Academy

Constraints can be any SystemVerilog expression with variables and constants of integral type (e.g., bit, reg, logic, integer, enum, packed struct).

In reply to dave_59:

Thank you Dave. Wishing you a very Merry Christmas. Happy Holidays!

Hi,

If I am writing inside the pre_randomize, it is not woorking
function void pre_randomize();

randcase
50 : queue_m = {1,1,0,0,1,0};
50 : queue_m = {1,0,1,0,1,0};
endcase

endfunction

if I am keeping inside the post randomize, it is working
function void post_randomize();

randcase
50 : queue_m = {1,1,0,0,1,0};
50 : queue_m = {1,0,1,0,1,0};
endcase

endfunction

why it is not working in pre_randomize, what I understood is it is randomizing different value and in post_randomize it is overriding ?

In reply to Lakshman4178:

When you randomize any object then randomize related methods are called in following order.

pre_randomize
randomize
post_randomize

so output generated by the pre_randomize is overridden by randomize method.

More detail : what is the difference between pre randomization and post randomization methods??? | Verification Academy

In reply to Rahulkumar Patel:
Thanku for answering

how it is generating particular sequence when it is randomizing. I have declared in post randomize, at the time of randmozing how it is generating particular sequence.

In reply to Lakshman4178:

In reply to Rahulkumar Patel:
Thanku for answering
how it is generating particular sequence when it is randomizing. I have declared in post randomize, at the time of randmozing how it is generating particular sequence.

Using the random constraint is one of the options. However, sometimes your constraint becomes more complicated to be solved, then you need to use pre/post_randomize.

In reply to Lakshman4178:

In reply to Rahulkumar Patel:
Thanku for answering
how it is generating particular sequence when it is randomizing. I have declared in post randomize, at the time of randmozing how it is generating particular sequence.

output generated during randomization is overridden by the post_randomization. Let take example :

class rndm;
  rand bit [3:0]  data;
  rand bit dummy_bit;
 
  constraint c_data { data == 4; dummy_bit == display(data);  }
 
 
  function void pre_randomize ();
    data = 3;
    $display ("pre_randomize data = %d", data);
  endfunction
 
  function bit display(int dt);
    $display("during randomization data =  %0d", dt);
    return 1;
  endfunction
 
  function void post_randomize ();
    data = 5;
    $display ("post_randomize data =  %d", data);
  endfunction
endclass
 
program my_prg;
 
  initial begin
    rndm a1;
    a1 = new();
    a1.randomize();

    $display("\n\n Final Data value = %d ", a1.data);
  end
endprogram : my_prg


//output:
# pre_randomize data =  3
# during randomization data =  4
# post_randomize data =   5
#  
#  
# Final Data value =  5 

/*
Here when you randomize the object a1.randomize();
    First pre_randomize method is called so data=3 
    then Randomization based on your constraint happen data=4, 
    at the end post randomization happen so data=5

After a1.randomize(), 
check the final value of data which is 5 set during the post randomize because value set during the randomization is overridden. 
    $display("\n\n Final Data value = %d ", a1.data);
*/