1. 前言
總線驗證會涉及很多Masters和Slaves接口,少則十來個,多則成百上千個,每個口通常都需要掛接對應的VIP來產(chǎn)生激勵,如下圖示例,有5個Master VIP,4個Slave VIP。掛接的Master VIP用于發(fā)起激勵,掛接的Slave VIP用于響應激勵。在掛接如此眾多的VIP驗證環(huán)境匯總,需要有更高效且靈活的方法去控制每一個VIP激勵行為。
圖1 總線示例
如何判斷一種方法是否靈活且高效呢?有這幾個標準:
方便控制;
可讀性強;
代碼量少且規(guī)整;
易于修改和拓展;
我們接下來先舉一個直接例化法(不推薦的方法),再引出枚舉動態(tài)數(shù)組法(推薦的方法),方便比較兩種方法的差異。
2. 直接例化法
直接例化法是將每一個Master VIP單獨聲明和例化,每個VIP之間毫無關(guān)系,如圖2所示,紅色字體為句柄名字。
圖2 直接例化法環(huán)境
例化代碼示例如下:
AXI_MST_VIP?axi_mst_vip1 =?AXI_MST_VIP::type_id::create("axi_mst_vip1", this);
AXI_MST_VIP?axi_mst_vip2 =?AXI_MST_VIP::type_id::create("axi_mst_vip2", this);
AXI_MST_VIP?axi_mst_vip3 =?AXI_MST_VIP::type_id::create("axi_mst_vip3", this);
AHB_MST_VIP?ahb_mst_vip1 =?AHB_MST_VIP::type_id::create("ahb_mst_vip1", this);
AHB_MST_VIP?ahb_mst_vip2 =?AHB_MST_VIP::type_id::create("ahb_mst_vip2", this);
AXI_SLV_VIP?axi_slv_vip1 =?AXI_SLV_VIP::type_id::create("axi_slv_vip1", this);
AXI_SLV_VIP?axi_slv_vip2 =?AXI_SLV_VIP::type_id::create("axi_slv_vip2", this);
AHB_SLV_VIP?ahb_slv_vip1 =?AHB_SLV_VIP::type_id::create("ahb_slv_vip1", this);
APB_SLV_VIP?apb_slv_vip1 =?APB_SLV_VIP::type_id::create("apb_slv_vip1", this);
這個方法的優(yōu)點是一目了然,但代碼不緊湊美觀,而且不方便控制、修改和擴展。比如,我們要把所有VIP的sequencer都start起來,需要一行行的寫xxx.start(),或者要把VIP monitor的analysis_port和scoreboard連接起來,也需要一行行的寫xxx.connect(xxx)。再比如要新增一個或減少一個VIP,要在聲明、例化和調(diào)用的地方都一一做修改。一旦某個地方漏了改,就可能造成驗證激勵的完備性不足。
綜合來說,這個方法可以用,但是性價比不高,在小規(guī)??偩€驗證中使用還可以。
3. 枚舉動態(tài)數(shù)組法
枚舉動態(tài)數(shù)組法根據(jù)VIP類型定義一些動態(tài)數(shù)組和枚舉類型,動態(tài)數(shù)組的key是枚舉類型,value是指向VIP的例化對象。同類VIP會被包裹在同一個動態(tài)數(shù)組內(nèi),如圖3所示,相同顏色字體的句柄名字為同一個動態(tài)數(shù)組。
圖3 枚舉動態(tài)數(shù)組法環(huán)境
例化代碼示例如下:
typedef?enum?{
? ? axi_mst_vip1 =?1,
? ? axi_mst_vip2 =?2,
? ? axi_mst_vip3 =?3
}?axi_mst_t;
AXI_MST_VIP axi_mst_vip[axi_mst_t];
axi_mst_t?e = e.first();
forever begin
? ? axi_mst_vip[e] = AXI_MST_VIP::type_id::create(e.name(),?this);
? ??if?( e == e.last() )?break;
? ? e = e.next();
end
由上代碼可以看出,這種方法至少有以下幾點好處:
同類型VIP的控制可以使用foreach等循環(huán)語句進行操作;
可讀性強,根據(jù)動態(tài)數(shù)組axi_mst_vip的key值就可以看出是哪個VIP,引用起來很方便;
在規(guī)模很大的總線中,這種做法會使得代碼非常簡潔,而且讓人看起來賞心悅目;
非常容易擴展,比如要新增一個AXI_MST_VIP,只需要在枚舉里添加一個新的枚舉值就可以了,其它代碼都不需要改;反之,刪除同理。
當然,可能有人想把上述方法改成靜態(tài)數(shù)組來做,不使用枚舉類型。比如:
AXI_MST_VIP?axi_mst_vip[3];
foreach ( axi_mst_vip[i] )?begin
? ? axi_mst_vip[i] =?AXI_MST_VIP::type_id::create(“axi_mst_vip”, this);
end
這個確實也可以,但是可讀性不強,比如axi_mst_vip[0]對應哪個VIP呢?我們還得需要去查表或看圖或記住這些數(shù)字的含義,在可讀性方便略輸一籌。按枚舉動態(tài)數(shù)組法,我們可以很容易的看出來axi_mst_vip[axi_mst_vip1]對應AXI_MST1 VIP,非常好用。當然,這種方式在小規(guī)模總線中,優(yōu)勢沒有那么大,隨著規(guī)模越大,它的優(yōu)勢越明顯。