SystemVerilog隐含约束

SystemVerilog为我们提供了两种声明条件关系的结构-implication和if_else.
以下代码片段显示了两种样式:

// implication运算符“->”告诉您,当mode等于2时len应该大于10
constraint c_mode {  mode == 2 -> len > 10; }
 
// Same thing can be achieved with "if-else" construct
constraint c_mode { if (mode == 2) 
            len > 10; 
          }

注意,对于所有大于10的len值,mode不必为2。但是,如果mode是2,则约束条件是len应该大于10。

Example

class ABC;
  rand bit [2:0] mode;
  rand bit [3:0] len;
 
  constraint c_mode { mode == 2 -> len > 10; }
endclass
 
module tb;
  initial begin
    ABC abc = new;
    for(int i = 0; i < 10; i++) begin
      abc.randomize();
      $display ("mode=%0d len=%0d", abc.mode, abc.len);
    end
  end
endmodule

Simulation Log
ncsim> run
mode=1 len=11
mode=6 len=3
mode=3 len=9
mode=7 len=11
mode=3 len=15
mode=2 len=12
mode=3 len=6
mode=2 len=12
mode=4 len=9
mode=7 len=13
ncsim: *W,RNQUIE: Simulation is complete.

仿真结果表明,当len大于10时,模式不必取值为2。

implication运算符

implication运算符->可以在约束表达式中使用,以显示两个变量之间的条件关系。

如果->运算符的LHS上的表达式为true,则将满足RHS上的约束表达式。 如果LHS不为真,则不考虑RHS约束表达式。
(LHS和RHS含义是赋值操作的左侧与右侧。)

Example

class ABC;
  rand bit [3:0] mode;
  rand bit      mod_en;
 
  // If 5 <= mode <= 11, mod_en should be 1
  constraint c_mode {  mode inside {[4'h5:4'hB]} -> mod_en == 1; }
 
endclass
 
module tb;
  initial begin
    ABC abc = new;
    for (int i = 0; i < 10; i++) begin
      abc.randomize();
      $display ("mode=0x%0h mod_en=0x%0h", abc.mode, abc.mod_en);
    end
  end
 
endmodule  


Simulation Log
ncsim> run
mode=0xf mod_en=0x1
mode=0x9 mod_en=0x1
mode=0x3 mod_en=0x1
mode=0xe mod_en=0x1
mode=0x1 mod_en=0x1
mode=0x0 mod_en=0x0
mode=0x1 mod_en=0x0
mode=0xe mod_en=0x0
mode=0x5 mod_en=0x1
mode=0x0 mod_en=0x0
ncsim: *W,RNQUIE: Simulation is complete.

请注意,每当mode的LHS表达式在4’h5和4’hB内部时,mod_en为1。但是,如果LHS评估为false,则可以将mod_en随机化为任何值。

if-else约束

if-else约束提供了一个选项,用于指定条件表达式的else部分。 如果条件表达式为真,则应满足第一个约束中指定的所有约束。 否则,将满足可选else部分中的所有约束。

允许嵌套的if-else块,并且多个约束语句要求将它们括在花括号{}中。 这类似于在程序块(如initial和always)中使用的begin-end。 但是,约束被归类为声明性代码,因此需要大括号。

Example

在下面显示的代码中,第一个if块检查mode是否在5和11内。如果此条件为true,则应将mod_en约束为1,如果为false,则执行else部分。 else部分中还有另一个if-else块,该块检查mode是否为1并尝试满足相应部分中提到的约束。

class ABC;
  rand bit [3:0] mode;
  rand bit      mod_en;
 
  constraint c_mode {  
              // If 5 <= mode <= 11, then constrain mod_en to 1
              // This part only has 1 statement and hence do not
              // require curly braces {}
              if (mode inside {[4'h5:4'hB]}) 
                mod_en == 1;
 
              // If the above condition is false, then do the following
               else {
                          // If mode is constrained to be 1, then mod_en should be 1
                          if ( mode == 4'h1) {
                    mod_en == 1;
                            // If mode is any other value than 1 and not within
                            // 5:11, then mod_en should be constrained to 0
                } else {
                    mod_en == 0;
                }
              }
                    }
 
endclass
 
module tb;
  initial begin
    ABC abc = new;
    for (int i = 0; i < 10; i++) begin
      abc.randomize();
      $display ("mode=0x%0h mod_en=0x%0h", abc.mode, abc.mod_en);
    end
  end
 
endmodule
 
Simulation Log
ncsim> run
mode=0xb mod_en=0x1
mode=0x1 mod_en=0x1
mode=0x6 mod_en=0x1
mode=0x7 mod_en=0x1
mode=0x2 mod_en=0x0
mode=0x2 mod_en=0x0
mode=0x2 mod_en=0x0
mode=0x9 mod_en=0x1
mode=0x7 mod_en=0x1
mode=0x8 mod_en=0x1
ncsim: *W,RNQUIE: Simulation is complete.

参考文献:
【1】https://www.chipverify.com/systemverilog/systemverilog-implication-constraint

发布了71 篇原创文章 · 获赞 8 · 访问量 7386

猜你喜欢

转载自blog.csdn.net/qq_43042339/article/details/104586690