ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [SystemVerilog] 랜덤변수 2
    개발/SystemVerilog 2022. 1. 26. 23:30

    dist 키워드로 constraint 내부에서 확률 가중치를 부여할 수 있다.

    가중치는 := 또는 :/ 으로 부여한다.

    class myclass;
        rand bit [2:0] typ;
        constraint c1 {typ dist {0:=20, [1:5]:=50, 6:=40, 7:=10};};
    endclass
    
    
    class myclass;
        rand bit [2:0] typ;
        constraint c2 {typ dist {0:=20, [1:5]:/50, 6:=40, 7:=10};};
    endclass

    :=은 범위에 속하는 수들이 동일한 가중치를 부여한다. 위 예에서 [1:5]:=50 에서 5개의 수는 각각 50의 가중치를 갖는다.

    :/ 는 지정한 가중치를 범위에 속하는 수들이 균등하게 나눠갖는다. [1:5]:/50 에서 5개의 수는 50을 나눠서 각각 10의 가중치를 갖는다.

     

     

     

     

    조건에 따라서 랜덤변수를 부여할 수 있다.

    class myclass;
        rand bit [2:0] mode;
        rand bit [3:0] len;
        
        constraint c1 {mode >= 4 -> len == 4;};
    
    endclass

    -> 연산자를 사용하여 조건부 경우의 수를 지정할 수 있다.

    위의 constraint 구문은  if (mode >= 4) len = 4; 문장과 같은 의미다.

     

     

     

     

     

     

    class myclass;
        rand bit a;
        rand bit [1:0] b;
        
        constraint c1 {a -> b == 3;};
    endclass

    constraint 구문이 위와 같을 경우 확률분포는 어떻게 되는가.

    a b P
    0 0 1/5
    0 1 1/5
    0 2 1/5
    0 3 1/5
    1 3 1/5

    위의 변수들이 갖을 수 있는 모든 경우의 수들이 균등한 확률분포를 갖는다.

     

    하지만 constraint 구문 안에 solve ... before 를 쓰면 분포가 변한다.

    class myclass;
        rand bit a;
        rand bit [1:0] b;
        
        constraint c1 {a -> b == 3; solve a before b};
    endclass

    constraint 구문이 위와 같을 경우 확률분포는 어떻게 되는가.

    a b P
    0 0 1/8
    0 1 1/8
    0 2 1/8
    0 3 1/8
    1 3 1/2

    즉 a의 분포 확률을 먼저 구하고 다음으로 b의 경우의 수 만큼 확률을 나눈다.

     

     

     

     

    constraint 내부에 loop 구문을 사용하여 배열 원소들의 값을 부여할 수 있다.

    class myclass;
        // dynamic array
        rand int A[];
        constraint c1 {foreach (A[i]) (i <= A.size()/2) -> (A[i] <= i);};
        constraint c2 {foreach (A[i]) (i > A.size()/2) -> (A[i] >= i);};
    endclass

     

     

     

    static을 선언하면 같은 클래스끼리 변수나 메서드를 공유할 수 있다.

    마찬가지로 static constraint 선언하면 해당 constraint는 같은 클래스 끼리 공유된다.

    constraint 구문은 constraint_mode() 메서드로 on / off 할 수 있다.

    class myclass;
        rand bit [3:0] a;
        
        constraint c1 {a > 5};
        static constraint c2 {a < 12};
    endclass
    
    
    module tb;
        initial begin
        	myclass class1 = new;
            myclass class2 = new;
            
            // off the static constraint
            class1.c2.constraint_mode(0);
            
            for (int i = 0; i < 10; i++) begin
            	class1.randomize();
                class2.randomize();
                $display("class1 = %d,  class2 = %d", class1.a, class2.a);
            end
        end
    endmodule

    class1 의 c2를 off 했지만, class2또한 적용받는다.

     

     

     

     

    inline constraint 구문을 이용하면 randomize() 할 때 추가적으로 constraint를 간단하게 적용할 수 있다.

    inline constraint를 적용하려면 with {condition1; condition2; ... } 형식으로 쓰면 된다.

    class myclass;
        rand bit [7:0] id;
        constraint c1 {id < 24;};
    endclass
    
    module tb;
        initial begin
        	myclass class1 = new();
            repeat(10) begin
            	class1.randomize() with {id < 5;};
                $display("id = %d", class1.id);
            end
        end
    endmodule

    inline constraint 적용한 결과다.

    만약 randomize() with {id > 25;}; 으로 적용하면 어떻게 될까?

    클래스안에서 선언한 constraint 블럭과 상충되는 조건으로 inline constraint 를 주면 에러가 발생한다.

     

    하지만 soft 키워드를 사용하면 상충되는 조건으로 inline constraint 를 적용할 수 있다.

    constraint의 조건문 중에 soft를 적용하고 싶은 문장 앞에 soft 키워드를 넣으면 된다.

    {<soft> condition1; <soft> condtion2; }; 형식

    class myclass;
        rand bit [7:0] id;
        constraint c1 {soft id < 24;};
    endclass
    
    module tb;
        initial begin
        	myclass class1 = new();
            repeat(10) begin
            	class1.randomize() with {id > 30;};
                $display("id = %d", class1.id);
            end
        end
    endmodule

    클래스 내부에서 soft constraint 를 선언하여 유연하게 제약조건을 적용할 수 있다.

     

Designed by Tistory.