《SystemVerilog驗證測試平臺編寫指南》學習筆記——藍圖模式
技術標籤:SystemVerilogsystemverilogverilog晶片
一、藍圖模式
藍圖模式是OOP中一種非常有用的技術。如果你用一臺機器來生產標記,那麼並不需要預先知道每一個可能的標記形狀,你所需要的只是一個壓印機然後變換金屬模子以剪裁出不同的形狀。同樣的。當你想要構建一個事務發生器的時候,不需要知道怎樣建立各種型別的事務,只需要能夠根據給定的事務建立一個類似的新的事務即可。
藍圖模式發生器:
我們先構建一個物件的藍圖(建材金屬模),然後修改它的約束,甚至使用一個擴充套件物件替換它。然後隨機化這個藍圖的時候,它就會具有你想賦予的隨機值,接著複製這個物件,並將拷貝值傳送給下游的事務處理器。此技術出色的地方在於如果你改變了藍圖物件,你的發生器就會建立一個不同型別的物件。在生產標誌的那個比方中,相對於你使用了一個三角形金屬模子取代了正確性金屬模子來製作。這個藍圖是一個“鉤子”,它允許你改變發生器類的行為而無需改變其類程式碼,但是在使用時你需要建立一個複製方法來複制藍圖以便傳送,這樣最原始的藍圖物件在迴圈中的下一輪呼叫時就可以隨時使用了。
使用新模式的藍圖發生器:
使用藍圖模式的發生器類
class Generator;
mailbox gen2drv;
Transaction blueprint;
function new(input mailbox gen2drv);
this.gen2drv = gen2drv;
blueprint = new();
endfunction
task run;
Transaction tr;
forever begin
assert(blueprint.randomize);
tr = blueprint.copy();
gen2drv. put(tr); //傳送到驅動器
end
endtask
endclass
二、Environment類
測試平臺要執行的三個階段:build、run、wrap_up,而Environment類例化了測試平臺的所有元素,並且執行這三個階段。
Environment類
class Environment;
Generator gen;
Driver drv;
mailbox gen2drv;
function void build(); //通過構建郵箱、發生器、驅動器來建立環境
gen2drv = new();
gen = new(gen2drv);
drv = new (gen2drv);
endfunction
task run();
fork
gen.run();
drv.run();
join_none
endtask
task wrap_up();
...
endtask
endclass
三、一個簡單的測試平臺
測試包含在頂層程式中,基本的測試僅僅使Environment類按預設方式執行。
program automatic test;
Environment env;
initial begin
env = new(); //建立Environment物件
env.build(); //建立測試平臺物件
env.run(); //執行測試
env.wrap_up(); //清理
end
endprogram
四、使用擴充套件的Transaction類
為了注入錯誤,你需要將藍圖物件從Transaction物件變成BadTr物件。必須在環境的建立和執行階段完成這個操作,這樣頂層測試平臺將執行環境的每個階段並且改變藍圖。
在測試平臺中增加了擴充套件了的事務
program automatic test;
Environment env;
initial begin
env = new();
env.build();
begin
BadTr bad = new(); //以bad物件取代藍圖
env.gen.blueprint = bad;
end
env.run; //執行帶BadTr的測試
env.wrap_up();
end
endprogram
五、使用擴充套件類改變隨機約束
絕大多數的測試程式需要對資料做進一步的約束,繼承是實現這些要求的最佳方法。
使用繼承來增加一個約束
/*如果擴充套件類中定義了一個約束,並且擴充套件後的約束名和基類裡的約束名相同,
那麼擴充套件類的約束會替代基類中的約束,這樣你就可以改變現有約束的行為。
*/
class Nearby extends Transaction;
constraint c_nearby{
dst inside {[src-100 : src+100]};
}
endclass
program automatic test;
Environment env;
initial begin
env = new();
env.build();
begin
Nearby nb = new();
env.gen.blueprint = nb;
end
env.run();
env.wrap_up();
end
endprogram