SystemVerilog: solve...before Constraint - IKSciting
2185
post-template-default,single,single-post,postid-2185,single-format-standard,bridge-core-2.8.7,qodef-qi--no-touch,qi-addons-for-elementor-1.7.1,qode-page-transition-enabled,ajax_fade,page_not_loaded,,qode-title-hidden,qode_grid_1300,footer_responsive_adv,qode-content-sidebar-responsive,qode-theme-ver-27.1,qode-theme-bridge,qode_header_in_grid,wpb-js-composer js-comp-ver-6.6.0,vc_responsive,elementor-default,elementor-kit-838

solve…before Constraint

먼저 아래의 random constraint 코드에서 어색하게 느껴지는 부분이 없는지 살펴보자. 만약 발견하지 못했다면 이번 포스트를 한 번 끝까지 읽어보도록 하자.

class my_class;

  rand int a;
  rand int b;

  constraint c_a { a inside { [1:10] }; }

  constraint c_b {
    solve a before b;
    b == (a ** 2);
  }

endclass: my_class

효과적인 검증을 위해 constraint 기반의 random verification을 수행하다 보면, random 변수 간의 관계로 인해 SystemVerilog의 solvebefore를 사용하기도 한다. 하지만 정확한 동작을 이해하지 못하고 잘못 사용하는 경우를 종종 보게 되는데, 위 코드도 이에 해당한다. a의 값이 결정되어야 b가 결정되므로 solvebefore constraint를 사용하여 순서를 지정해주어야 한다고 오해하기 때문이다.

하지만 solvebefore constraint는 solution set에는 전혀 영향을 미치지 않으며, 가능한 solution set 범위 내에서의 distribution을 조정하는 역할만 할 뿐이다. 위 코드에서 ba의 값에 따라 분포를 달리 하는 것이 아니라 확정적으로 a의 제곱값을 갖게 된다. 따라서 이 경우 solvebefore constraint는 불필요한 코드가 된다.

Solution set 내에서의 distribution을 조정한다는 의미를 조금 더 쉽게 이해하기 위하여 다음 코드를 살펴보자. cmd가 write 또는 read의 값을 가질 수 있으며, read인 경우 data가 0, write인 경우 data가 0에서 3의 값을 가질 수 있다고 가정하자.

typedef enum bit { RD = 0, WR = 1 } cmd_e;

class my_class;

  rand cmd_e cmd;
  rand bit [1:0] data;

  constraint c { (cmd == RD) -> (data == 0); }

endclass: my_class

위 코드에서 cmddata의 가능한 solution set은 (RD, 0), (WR, 0), (WR, 1), (WR, 2), (WR, 3)이다. SystemVerilog의 constraint solver는 solution set 내에서 모든 solution이 uniform distribution을 갖도록 한다. 즉, 각 solution은 동일하게 20 %의 확률을 갖는다. 만약 write와 read의 확률을 동일하게 test 하고자 했다면 의도한 바와 다른 동작을 하는 것이다. 뿐만 아니라 만약 data가 8-bit 또는 32-bit와 같은 data type으로 선언되어 훨씬 다양한 값을 가질 수 있게 된다면, test 도중 read가 선택될 확률은 극도로 작아진다.

이번에는 동일한 코드에 solvebefore constraint를 추가해보자.

typedef enum bit { RD = 0, WR = 1 } cmd_e;

class my_class;

  rand cmd_e cmd;
  rand bit [1:0] data;

  constraint c {
    solve cmd before data;
    (cmd == RD) -> (data == 0);
  }

endclass: my_class

위에서 설명한 바와 같이 solvebefore constraint를 사용하더라도 solution set은 변함 없이 (RD, 0), (WR, 0), (WR, 1), (WR, 2), (WR, 3)이다. 하지만 이 경우 constraint solver가 cmd를 먼저 solve 함으로써 cmd가 uniform distribution을 갖게 되어 write와 read가 각각 50 %의 확률을 가진다. Read의 경우 data가 항상 0의 값을 갖게 되며, write의 경우 data가 0부터 3까지 각각 25 %의 확률로 분포하게 된다. 결과적으로 전체 solution set에서 (RD, 0)은 50 %, (WR, 0), (WR, 1), (WR, 2), (WR, 3)은 각각 12.5 %의 확률을 갖게 됨으로써 write와 read의 확률은 동일하게 유지하면서 test 할 수 있게 된다.

Summary

이처럼 SystemVerilog의 solvebefore constraint는 (이미 결정되어 있는) solution set의 distribution을 조정하기 위하여 사용된다. Test intent에 따라 필요한 경우 적절히 사용할 수 있어야 하며, distribution 조정의 의미가 없는 경우는 사용하지 않도록 해야 한다.

References

6 Comments

Post A Comment