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

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM