-
[SystemVerilog] 랜덤변수 1개발/SystemVerilog 2022. 1. 25. 22:16
시스템베릴로그의 강력한 기능인 constriant randomize 를 알아본다.
베릴로그에는 랜덤값을 생성하는 시스템태스크가 있다.
하지만 어떤 제약조건에 맞는 범위의 랜덤변수를 생성하려면 번거롭게 코딩을 해야한다.
시스템베릴로그는 랜덤변수에 제약조건과 확률분포, 조건부 확률을 지원하여 사용자의 입맛대로 자유롭게 랜덤변수를 생성 할 수 있다.
시뮬레이터는 트루랜덤이 아니라 pseudo 랜덤값을 생성하는데 이는 테스트의 일관성과 반복적 디버깅을 위해서 그런것이다. 시드가 같으면 랜덤값의 시퀀스도 같다.
랜덤변수를 선언할 때 rand / randc 키워드를 붙이면 된다.
rand 는 균일한 확률분포를 갖는 랜덤변수를 정의한다.
randc는 랜덤값이 순환하는 하도록 정의한다.
랜덤값을 주려면 randomize() 메서드를 쓰면 된다.
module tb; class packet; rand bit [2:0] data; randc bit [2:0] addr; endclass initial begin packet pkt = new(); repeat (16) begin pkt.randomize(); $display("data = %d, addr = %d", pkt.data, pkt.addr); end end endmodule
테스트 결과를 보면 차이를 바로 알 수 있다.
rand로 선언한 변수는 무작위로 값이 나온다.
randc 는 무작위이긴 하지만 값을 갖을수 있는 범위(0~7) 안에 있는 값들이 한번씩 나온다.
randomize() 메서드를 이용하여 랜덤값을 부여한다.
rand / randc 키워드는 기본적인 데이터 타입에는 모두 사용할 수 있다. (int, bit, array, queue 등등)
이제 랜덤값을 만드는건 알았지만 그렇다고 아무값이나 막 줄수는 없다.
따라서 랜덤값에도 일정한 범위를 한정해야한다.
constraint 구문을 사용하여 랜덤값 생성에 범위와 조건을 지정할 수 있다.
constraint valid_addr {addr [1:0] == 2'b00; addr <= 32'h1111_ffff; addr >= 32'h0000_1111}; constraint fast_burst {burst >= 3; len >= 64; size >= 128}; constraint empty {}; constraint error {0 < min < typ < max < 128}; // invalid // valid expression constraint valid {0 < min; min < typ; typ < max; max < 128};
contraint name {condition1; condition2; ...}; 형식으로 제약조건을 지정한다.
만약 서로 상충되는 조건이 있을 경우엔 런타임에러가 발생한다.
한 문장에 하나의 조건씩 기술해야한다.
module tb; class packet; rand bit [3:0] mode;; constraint c1 {mode > 2; mode < 6;}; endclass initial begin packet pkt = new(); repeat (10) begin pkt.randomize(); $display("mode = %d", pkt.mode); end end endmodule
constraint 를 추가하고 랜덤값을 준 결과. 3 ~ 5 값이 생성된다.
extern 키워드를 사용하면 constraint 구문을 클래스 밖에서 기술할 수 있다.
extern task / function 정의하는것과 똑같다.
module tb; class packet; rand bit [3:0] mode; exturn constraint c1; endclass contraint c1 {mode >2 ; mode < 6};
constraint 구문을 작성할 때 inside operator가 유용하다.
대괄호 안에 정수 범위를 지정할 수 있다.
inside는 파이썬에서 in 연산자와 동일한 기능을 한다.
constraint range {typ >= 32; typ <= 256;}; // 32 to 256 constraint range {typ inside {[32:256]};}; // 32, 64, 128 중에 하나 constraint range {typ inside {32, 64, 128};}; // 32, 64, 128 제외한 나머지 constraint range {!(typ inside {32, 64, 128});};
'개발 > SystemVerilog' 카테고리의 다른 글
[SystemVerilog] 랜덤변수 3 (0) 2022.01.27 [SystemVerilog] 랜덤변수 2 (0) 2022.01.26 [SystemVerilog] 클래스 4 데이터 은닉 (0) 2022.01.24 [SystemVerilog] 클래스 3 다형성2 (0) 2022.01.24 [SystemVerilog] 클래스 3 다형성 (0) 2022.01.24