implication(->)
「->」は expressionが真であれば、constraint_setを満たす。偽ならdont careの場合に使用します。
expressionが真であればconstraint_setを行う。(constraint_setを満たす)
expression -> constraint_set
記述例
「a00が5より大きな数値であれば、b00はa00より小さい値にする」制約です。
class c_imp ;
rand bit [3:0] a00,b00 ;
constraint C01 {a00>5 -> b00<a00 ; }
endclass
module test () ;
c_imp class00 ;
initial begin
class00 = new() ;
for (int iiii=0;iii<10;iii++) begin
class00.randomize() ;
$display("a00=%3d b00=%3d",class00.a00,class00.b00) ;
end
end
endmodule
実行結果
10回志向した結果です。a00が12、14、6、14のときにb00の値がそれぞれ1、8、3、12となっていることが確認できました。
a00= 4 b00= 13
a00= 3 b00= 3
a00= 1 b00= 13
a00= 2 b00= 5
a00= 4 b00= 0
a00= 12 b00= 1
a00= 14 b00= 8
a00= 6 b00= 3
a00= 5 b00= 12
a00= 14 b00= 12
if-else
“->”にさらにそうでなければ別のことを設定したい場合には”if-else”を使用します。
expressionが真であれば、constraint1_setを実行、expressionが偽であればconstraint2_setを実行
if (expression) constraint1_set
else constraint2_set
実行例
a00とb00は4ビット信号、a00が10より大きな値のときはb00は10、それ以外はb00は1にする制約を行う例です。
class_if ;
rand bit [3:0] a00,b00 ;
constraint C1 {
if(a00>10)
b00==10 ;
else
b00==1 ;
}
endclass
module test () ;
c_if class00 ;
initial begin
class00 = new( ) ;
for(int iii=0;iii<10;iii++) begin
class00.randomize() ;
$display("a00=%d b00=%d",class00.a00,class00.b00) ;
end
end
endmodule
実行結果
制約通りの結果が確認できました。
a00= 11 b00= 10
a00= 11 b00= 10
a00= 13 b00= 10
a00= 13 b00= 10
a00= 0 b00= 1
a00= 10 b00= 1
a00= 1 b00= 1
a00= 10 b00= 1
a00= 14 b00= 10
a00= 15 b00= 10
else if
if と elseの間にelse ifも制約条件で利用できます。
以下の例では、a00が10以下で5より大きい場合はelse ifの条件となり、b00に5を設定します。
(module部分は前回と同様の記述)
class_if ;
rand bit [3:0] a00,b00 ;
constraint C1 {
if(a00>10)
b00==10 ;
else if (a00>5)
b00==5 ;
else
b00==1 ;
}
endclass
実行結果
a00= 11 b00= 10
a00= 11 b00= 10
a00= 13 b00= 10
a00= 13 b00= 10
a00= 0 b00= 1
a00= 10 b00= 5
a00= 1 b00= 1
a00= 10 b00= 5
a00= 14 b00= 10
a00= 15 b00= 10
複数の変数に対して制約
もう一つ変数を追加した例です。同じ条件で別々の変数にそれぞれ設定したい場合は、”&”記号でつなぎます。
class_if ;
rand bit [3:0] a00,b00,c00 ;
constraint C1 {
if(a00>10)
b00==10 & c00==5;
else if (a00>5)
b00==5 & c00==10;
else
b00==1 & c00 ==1;
}
endclass
module test () ;
・・・
$display("a00=%3d b00=%3d c00=%3d",class00.a00,class00.b00,class00.c00) ;
・・・
endmodule
実行結果
a00= 11 b00= 10 c00= 5
a00= 11 b00= 10 c00= 5
a00= 13 b00= 10 c00= 5
a00= 13 b00= 10 c00= 5
a00= 0 b00= 1 c00= 1
a00= 10 b00= 5 c00= 10
a00= 1 b00= 1 c00= 1
a00= 10 b00= 5 c00= 10
a00= 14 b00= 10 c00= 5
a00= 15 b00= 10 c00= 5
solve a before b
-> やif文などの制約を付加する前に条件に利用する変数をランダマイズする場合に使用します。
例えば、”constraint C00 {a00>5 -> b00>5 ; }”のようにa00が5より大きい場合にb00も5より大きい値であると設定する場合、b00が確定するためには事前にa00がランダムされ確定されている必要があります。
その場合”constraint C01 {solve a00 before b00 ; }”を追加することで明示的にa00の値をb00の設定前に設定することを表しています。(なくてもうまくいくときもあります)
”constraint C01 {solve b00 before a00 ; }”としてしまうと、b00がa00より先に値が決定するため、2つ目の制約C02 の制約は無効となります。
class c_solve ;
rand [3:0] a00,b00 ;
constraint C01 {solve b00 before a00 ; }
constraint C02 {a00>5 -> b00>5 ; }
endclass
module test () ;
c_solve class00 ;
initial begin
class00 = new() ;
for(int iii=0;iii<10;iii++) begin
class00.randomize() ;
$display("a00=%3d b00=%3d",class00.a00,clas00.b00) ;
end
end
endmodule
実行結果
b00=4のとき、a00=6となり、制約C02に合っていません。これは先にC01が実行され、b00の値が6に決定した後にa00がランダム生成され4になったためです。
a00= 3 b00= 4
a00= 0 b00= 3
a00= 5 b00= 1
a00= 2 b00= 2
a00= 3 b00= 4
a00= 7 b00= 12
a00= 5 b00= 14
a00= 13 b00= 6
a00= 4 b00= 6
a00= 12 b00= 6
”class00.randomize() ;”の前に”class00.C01.constraint_mode(0);” を追加し、制約を
OFFにして実行すると、a00>5のときはb00>5となっていることが確認できました。
a00= 4 b00= 13
a00= 3 b00= 3
a00= 1 b00= 13
a00= 2 b00= 5
a00= 4 b00= 0
a00= 12 b00= 6
a00= 14 b00= 8
a00= 6 b00= 6
a00= 6 b00= 11
a00= 6 b00= 15

コメント