systemverilog中的constraint约束的使用

约束的使用

1.逻辑关系<,<=,==, >=,>

逻辑关系约束,比较直接的指定随机数产生的范围,<,<=,==, >=,>

rand byte data;
constraint data_cons{ data
> 0;   data <5; } //约束data的值大于0,小于5

 

2.inside

inside可以约束data从指定的数据集合中获取数据值,取得每个值的概率是相同的。

rand byte data;
constraint data_cons{
     data inside {[0:3],[8:10]};
}
//data 的值可以从0,1,2,3,8,9,10中取出

 

即使如下面的array,取出的1,2,3,4的概率也是相同的


rand byte data;
int array = '{1,2,2,3,3,3,4,4,4,4}
constrain data_c {
    data inside array;
    //此时,1,2,3,4取到的概率是相同的    
}

 

3.dist

dist约束data从列表中获取数据值,可指定获取数据的权重也可不指定,有两种指定权重的方式


rand byte data;
constraint data_cons{
  data dist {0,2,[5:10]};
}
//data 的值从0,2,5,6,7,8,9,10中取出

 

第一种权重:=,表示取0的概率是10/(10+45+45+45),1、2、3的概率均是45/(10+45+45+45)


rand byte data;
constraint data_cons{
    data dist {0:=10,[1:3]:=45};
}

 

第二种权重:/,表示取0的概率是10/(10+45),1、2、3的概率均是45/3/(10+45)=15/(10+45)

rand byte data;
constraint data_cons{
    data dist {0:/10,[1:3]:/45};
}

 

  := :/
0 10/145 10/55
1 45/145 15/55
2 45/145 15/55
3 45/145 15/55

 

4.条件判定

->蕴含判定,只有在data_flag大于2时,data从1、2、3中取值,在data_flag小于等于2时,data从4、5、6中取值.


rand byte data;
constraint data_cons{
    (data_flag > 2) -> data inside {[1:3]};
  (data_flag <= 2) -> data inside {[4:6]};
}

 

if   else 条件判定,只有在data_flag大于2时,data从1、2、3中取值,在data_flag小于等于2时,data从4、5、6中取值.


rand byte data;
constraint data_cons{
    if(data_flag>2)
        data inside {[1:3]};
    else 
        data inside {[4:6]};
}   

 slove before操作符

constraint data_cons{
(x == 0) -> y== 0;
solve y before x; //规定在y产生之前先产生x
//x=0,则y必为0;y=0,x不一定为0。
}

 5.数组的约束

 
rand byte     pload[];
 
constraint   pload_cons {
    foreach(pload[i]) {
      pload[i] inside {[1:255]};
    }
    pload.sum < 1024;
    pload.size() inside {[1:8]};
  }
 
//动态数组pload,可通过foreach约束pload中每个元素的值,和整个数组的sum和还有size大小,条件同时成立

 

6.约束的开关

可控制transaction中的约束的关闭,也可控制ransaction中的某一个约束的关闭

my_transaction m_trans
m_trans.crc_err_cons.constraint_mode(0);//关闭m_trans中的crc_err_cons的约束
m_trans.constraint_mode(0);//关闭m_trans中的所有的约束
`uvm_do(m_trans)

 

7.约束的重载

先构建一个自己的my_transaction,在其中指定约束crc_err_cons和sfd_err_cons

class my_transaction extends uvm_sequence_item;

   rand bit       crc_err;
   rand bit       sfd_err;
 
   constraint crc_err_cons{
      crc_err == 1'b0;
   } 
   constraint sfd_err_cons{
      sfd_err == 1'b0;
   } 

   `uvm_object_utils_begin(my_transaction)
      `uvm_field_int(sfd_err, UVM_ALL_ON | UVM_NOPACK)
      `uvm_field_int(pre_err, UVM_ALL_ON | UVM_NOPACK)
   `uvm_object_utils_end

   function new(string name = "my_transaction");
      super.new();
   endfunction

endclass

 

在case中可以创建一个my_transaction的子类new_transaction,在子类中重新定义约束crc_err_cons,则new_transaction中的crc_err_cons约束是重载后的,sfd_err_cons得约束条件任然使用my_transaction的约束条件

class new_transaction extends my_transaction;
   `uvm_object_utils(new_transaction)
   function  new(string name= "new_transaction");
      super.new(name);
   endfunction 

   constraint crc_err_cons{
      crc_err dist {0 := 2, 1 := 1};
   }
endclass

 

case中使用时,直接使用子类的transaction即可以完成新约束的使用。

   virtual task body();
      new_transaction ntr;
      repeat (10) begin
         `uvm_do(ntr)
      end
      #100;
   endtask

 

 

 

 

 
posted @ 2021-12-31 15:23  验证cc  阅读(13518)  评论(0编辑  收藏  举报