近期看到一種關(guān)于約束的復(fù)用方法,總結(jié)分享如下。
在不同的用例中,隨機(jī)參數(shù)的隨機(jī)約束不會(huì)完全一致,最典型的就是錯(cuò)誤或者異常用例的非法取值約束。對(duì)于這種不同的約束,常見的處理辦法就是繼承,并重寫原有參數(shù)的約束,如下所示。
class item; rand bit[3:0] A; constraint c{ A > 0; } //.... endclass class abnormal_item; constraint c{ A == 0;//覆蓋原有的A>0約束 } //.... endclass
除了存在可能的過(guò)度繼承問(wèn)題,繼承方式是一種"靜態(tài)"的is-a關(guān)系,一旦abnormal_item確定后,參數(shù)的約束就已確定,不具備動(dòng)態(tài)添加或者刪除約束的能力。
到這里,提一下Decorator Pattern(裝飾者模式)。Decorator Pattern大致是一種這樣的思路:
在Decorator Pattern的結(jié)構(gòu)中,可以動(dòng)態(tài)地給一個(gè)對(duì)象添加新的功能,同時(shí)又不改變其結(jié)構(gòu),將對(duì)象的行為分為核心功能和可選功能。核心功能指對(duì)象最基本的職責(zé),而可選功能則是在不改變核心職責(zé)的情況下增加的功能。通過(guò)使用裝飾者模式,可以動(dòng)態(tài)地將可選功能裝飾在核心功能之上,使對(duì)象的功能更加靈活......
借鑒類似的思路,可以將隨機(jī)參數(shù)和其約束分離開來(lái),將隨機(jī)約束視作對(duì)原參數(shù)的"裝飾",進(jìn)而達(dá)到動(dòng)態(tài)、可復(fù)用隨機(jī)約束的目的。
一個(gè)實(shí)例的類圖結(jié)構(gòu)如下:
在這種結(jié)構(gòu)下,大致分為兩層:
第一層是包含隨機(jī)參數(shù)的激勵(lì)定義層,item僅包含隨機(jī)參數(shù)的聲明,不包含參數(shù)的約束內(nèi)容。constrainted_item繼承于item,不包含直接的參數(shù)約束,而是通過(guò)add_instance_cons方法,動(dòng)態(tài)的添加對(duì)隨機(jī)參數(shù)的約束。
第二層是約束實(shí)現(xiàn)層,抽象類abstract_constraint僅包含item類,不實(shí)現(xiàn)對(duì)tem參數(shù)的具體約束,不同的約束由可重用的子類實(shí)現(xiàn),即圖中的reusable_cons實(shí)現(xiàn)。
相關(guān)參考代碼如下。
隨機(jī)參數(shù)定義:
class item; rand int val; endclass class constrained_item extends item; `constraints_utils(item) endclass
抽象和約束實(shí)現(xiàn)定義:
virtual class abstract_constraint #(type T = int); protected T object; function void set_object(T object); this.object = object; endfunction endclass class only_even_values extends abstract_constraint #(item); constraint c { object.val % 2 == 0; } endclass
動(dòng)態(tài)添加約束和隨機(jī):
initial begin automatic constrained_item i = new(); automatic only_even_values only_even = new(); i.add_instance_constraint(only_even); repeat (100) begin if (!i.randomize()) $fatal(0, "Randomization failure"); //.... end end
上述的constraints_utils實(shí)現(xiàn)代碼如下:
`define constraints_utils(TYPE) ... local rand constraints::abstract_constraint #(TYPE) instance_constraints[$]; function void add_instance_constraint(constraints::abstract_constraint #(TYPE) c); constraints::abstract_constraint #(TYPE) c_copy = new c; c_copy.set_object(this); instance_constraints.push_back(c_copy); endfunction ...
可以看到,constrained_item內(nèi)部包含了一個(gè)rand類型的instance_constraints隊(duì)列,用于存儲(chǔ)分離約束的句柄。同時(shí)only_even_values內(nèi)也包含了指向constrained_item的句柄。當(dāng)constrained_item進(jìn)行randomize時(shí),instance_constraints隊(duì)列也會(huì)隨機(jī),在only_even_values內(nèi)完成對(duì)constrained_item的參數(shù)約束。
審核編輯:劉清
-
Constraint
+關(guān)注
關(guān)注
0文章
2瀏覽量
7031
原文標(biāo)題:一種可重用constraint的實(shí)現(xiàn)方法:參數(shù)/隨機(jī)約束分離
文章出處:【微信號(hào):處芯積律,微信公眾號(hào):處芯積律】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論