約束的使用
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
