Constraints to generate random password in SV

Need help please.
Write constraints to generate random password in SV.
password length = 10
must contain 1 Capital Letter, 1 small letter and 1 special character.

In reply to Liiiiiz:


module top;
 
  class A;
    rand bit [6:0] pw[];
     
    constraint inside0_10 {
      pw.size() ==10;
    }
    constraint uniq { 
      foreach (pw[i]) {
        pw.sum() with (7'(item inside {[97:122]}))==1; //a-z
        pw.sum() with (7'(item inside {[65:90]}))==1;  //A-Z
        pw.sum() with (7'(item inside {[33:46]}))==1;  //special char
        pw.sum() with (7'(item inside {[48:57]}))==7;  //0-9
      }    
    }
    
  endclass
 
  A a=new;
  initial begin
    repeat(10) begin
      assert(a.randomize());
      foreach(a.pw[i]) $write("%s ",a.pw[i]);
     $display("");
    end
  end
 
endmodule

Output:
v89F7’5817
24348S2(w0
,5540bY806
8L98s018&5
86E2463c%1
6x9M2.7854
8710Ka2#20
$76598a4Q1
9&7z5812Q6
84080F8,w6

1 Like

In reply to Alokpati:

Note that the outer foreach iterative constraint is redundant, it can be removed

In reply to Alokpati:
thank you for your answer :)

could you please tell me why we are doing pw.sum here to get each value? I’m just trying to understand how you reached to this answer.

I read in LRM that “sum() returns the sum of all the array elements or, if a with clause is specified, returns the sum of the values yielded by evaluating the expression for each array element.”

    pw.sum() with (**7'**(item inside {[97:122]}))==1; //a-z
     - why are we doing 7' here?
            
    pw.sum() with (7'(item inside {[48:57]}))==7; 
     - this means that 7 numbers between [48-57] are randomly chosen. Say 40-46 are chosen, does it mean that all these 7 numbers are returned to the sum function?

In reply to Liiiiiz:

The result of the expression
item inside {[97:122]}
is true 1’b1 or false 1’b0, both 1-bit. The sum() of those expressions will also be a 1-bit result. You just need to cast that expression to a large enough width so the sum of 10 possible 1’b1 values does not overflow. Cast to 4-bits or int would work as well. I think Alokpati used 7 because that was the element size of pw array, but that size is no longer relevant.
Only 10 numbers can be chosen because that is the size of the array, and the sum of all the sum constraints is exactly 10. At most one value between 40-46 can be chosen because there is a constraint that only allows one value between 33-46.

You might want to read my DVCon paper: SystemVerilog constraints: Appreciating what you forgot in school to get better results

In reply to dave_59:

thank you Dave and Alokpati :)

In reply to dave_59:

In reply to Alokpati:
Note that the outer foreach iterative constraint is redundant, it can be removed

Thank you Dave for pointing the redundant code.