SystemC是基于C++的系統級設計語言,兼具描述硬件電路模型和面向對象的抽象能力。在芯片設計開發中,常用于芯片架構的建模、性能仿真和評估、軟硬件聯合仿真等場景。尤其是在融合TLM2.0事務級建模方法以后,SystemC的模型也出現事務級、cycle級等不同抽象等級的劃分,用于不同的場景需求。
隨著基于systemC建模的廣泛適用,對SC模型的驗證也是應運而生;正如Systemverilog用于對verilog的驗證。SystemC Verification (SCV)就是SC中的一個驗證庫,其包含了:
transaction-based verification
data introspection
constrainted and weighted randomization
這篇文章準備介紹SCV中的約束隨機:constrainted randomization。在systemverilog中隨機約束是CDV的一大利器,SV中具有豐富的隨機表達語法,比如inside、dist、solve before、->、unique等。C/C++中卻不具備如此豐富的約束能力,而SCV作為SC的驗證庫,引入了約束隨機描述。
Basic Randomization
無論是sc內建的基本數據類型,如sc_int/sc_uint等;還是自定義的struct數據,都可以使用scv_smart_ptr修飾,進行基本的隨機化操作。常見的用法如下:
//基本數據類型隨機 scv_smart_ptr< sc_uint<8> > data; data->next(); //自定義數據結構隨機 struct packet_t { int data; int array[10]; }; scv_smart_ptr< packet_t > p; // generate a random value and assign it to the data field p->data.next(); //generate a random value and assign it to the array element with index 3 p->array[3].next(); // generate random values for all fields and all array elements p->next(); // generate random values for all fields and all array elements, //except for the data field p->data.disable_randomization(); p->next();
scv_smart_ptr會例化一個內部的隨機對象,使用next方法產生隨機值。
對于自定義符合數據結構,也可以只針對其中部分參數進行隨機;不需要隨機的參數,使用disable_randomization關閉隨機。
Constrained Randomization
上述的簡單約束,可以使用scv_smart_ptr實現。對于其他的復雜約束,則需要借助scv_constraint_base實現。(scv_smart_ptr可以認為是systemverilog中的random函數,而constraint或者solve-before,則必須要在class中實現)。
用法如下:
class write_constraint : virtual public scv_constraint_base { public: scv_smart_ptr< rw_task_if::write_t > write; SCV_CONSTRAINT_CTOR(write_constraint) { SCV_CONSTRAINT( write->addr() < 0x00FF ); SCV_CONSTRAINT( write->addr() != write->data() ); } }; //上面SCV代碼的systemverilog等效格式: class write_constraint extend scv_constraint_base ; rand rw_task_if::write_t write; constraint write_constraint { write.addr < 0x00FF; write.addr != write.data; } endclass
在scv_constraint_base擴展出的子類中,需要隨機的參數仍需要使用scv_smart_ptr修飾。使用SCV_CONSTRAINT_CTOR聲明一段約束,SCV_CONSTRAINT用于添加一條約束表達式。
約束表達式可以支持:算術表達式(+,-,*,/),關系表達式(==, !=, >, >=, <, <=),邏輯表達式( !, &&, ||)。約束表達式有三種:
1.SCV_CONSTRAINT代表是一種hard constraint;
2.SCV_SOFT_CONSTRAINT表達一種soft constraint;
3. SCV_BASE_CONSTRAINT代表基類中的約束。
此處的hard和soft constraint含義和systemverilog中soft修飾隨機的含義基本一致。
上述的隨機類定義好后,便可以進行實例化和隨機。前面提到的disable_randomization仍然可以使用,并且統一使用next方法進行隨機生成。
write_constraint c("write constraint"); for (int i=0; i<2; ++i) { c.next(); cout << *c.write << endl; } write_constraint c("write constraint"); c.write->addr->disable_randomization(); for (int i=0; i<2; ++i) { c.write->addr = i; c.next(); cout << *c.write << endl; }
Weight and Biased Randomization
在systemverilog隨機約束中,經常會使用到inside、dist,用來表達帶有權重的隨機。同樣,SCV支持指定范圍隨機和帶權重的隨機,通過scv_bag實現。scv_bag可以用來收集需要范圍隨機信息以及權重信息。
單值權重設置使用scv_bag表達,實例:
scv_bagbag; bag.push(1,60); bag.push(2,40); scv_smart_ptr data; data->set_mode(bag); data->next(); //systemverilog的等效表達 rand int data; data dist {1:/60,2:/40};
在scv_bag收集好權重信息后,通過set_mode函數傳遞給參數的隨機對象即可。范圍權重設置使用scv_bag< pair< int,int> >表達,實例:
scv_smart_ptrdata; scv_bag< pair< int,int> > distribution; distribution.push( pair (0,1), 40); distribution.push( pair (2,10), 60); data->set_mode(distribution); data->next(); //systemverilog的等效表達 rand int data; data dist {[0:1]:/60,[2:10]:/40};
從上面可以看出如果需要添加范圍約束和權重約束,就必須要定義scv_bag,添加約束范圍和權重,并通過set_mode設置,稍顯復雜。因此SCV中引入keep_only和keep_out方法,用于添加隨機約束范圍,類似systemverilog中的inside和~inside。
scv_smart_ptri; i->keep_only(0,4); i->keep_out(2); i->next(); // generate a value among { 0, 1, 3, 4 } //如果使用scv_bag方式,方法如下: scv_smart_ptr i; scv_bag bag; bag.add(0); bag.add(1); bag.add(3);bag.add(4); i->next();
keep_only和keep_out除了可以接受固定數值外,還可以接收list類型的變量。
scv_smart_ptri; list i_range; i_range.push_back(0); i_range.push_back(4); i->keep_only(i_range); i->keep_out(2); i->next(); // generate a value among { 0, 3, 4 }
總結來看,設置隨機約束有如下方式:
set_mode方法
keep_only、keep_out方法
SCV_CONSTRAINT約束表達式
set_mode和keep_only/out的隨機約束設置會進行覆蓋。使用reset_distribution方法可以取消set_mode和keep_only/out方法設置的隨機約束。實例如下:
scv_smart_ptri; i->keep_only(0,4); i->keep_out(2); i->next(); // generate a value among { 0, 1, 3, 4 } scv_bag b; b.add(2); b.add(7); i->set_mode(b); i->next(); // generate a value among {2,7} i->reset_distribution(); i->next(); // generate a value between INT_MIN and INT_MAX.
寫在最后
SCV 約束除了作為SC模型的驗證隨機約束外,一方面可以把SC模型階段的驗證激勵復用到中后期的RTL驗證;
另一方面還可以在CPU核相關的C語言case中使用,由于SCV是基于C/C++語言,因此可以比較容易地和C based case結合,具體融合方式需要一些轉接件,這個后續有機會再做介紹。
審核編輯:劉清
-
芯片設計
+關注
關注
15文章
1005瀏覽量
54819 -
仿真器
+關注
關注
14文章
1016瀏覽量
83647 -
C語言
+關注
關注
180文章
7601瀏覽量
136251 -
RTL
+關注
關注
1文章
385瀏覽量
59710 -
Verilog語言
+關注
關注
0文章
113瀏覽量
8219
原文標題:聊聊SystemC的驗證隨機
文章出處:【微信號:處芯積律,微信公眾號:處芯積律】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論