class,是面向?qū)ο?a href="http://ttokpm.com/v/tag/1315/" target="_blank">編程(object-oriented programming (OOP))的基礎(chǔ),而OOP可以讓你創(chuàng)建更高抽象級(jí)別的驗(yàn)證環(huán)境(如UVM)。
class就是相對(duì)于verilog更高級(jí)別的抽象,因?yàn)関erilog太過(guò)關(guān)注細(xì)節(jié),不利于驗(yàn)證和建模。
隨著SystemVerilog中class的引入,這一切都變了。
class包括變量(類屬性,properties)和子程序(類方法,methods)。
SystemVerilog中的類方法一般就是SystemVerilog task(可能消耗時(shí)間)/function(不能消耗時(shí)間)。
簡(jiǎn)言之,類屬性和類方法定義了這個(gè)類有什么以及能夠干什么。
通過(guò)類屬性和類方法,我們可以更加容易地創(chuàng)建模塊化的驗(yàn)證平臺(tái),因?yàn)樵谑聞?wù)級(jí)而不是RTL級(jí)別,能夠更容易理解設(shè)計(jì)和編碼驗(yàn)證用例。
一般,類中會(huì)有一個(gè)構(gòu)造函數(shù)(new,我們可以理解為RTL中module的例化,只有調(diào)用構(gòu)造函數(shù)后,才真正存在類的實(shí)體,在這之前就只是一個(gè)文本的定義而已。
在一個(gè)類沒(méi)有指向任何的對(duì)象實(shí)體時(shí),Systemverilog的垃圾回收機(jī)制會(huì)自動(dòng)地釋放相應(yīng)的內(nèi)存空間。
Base Class
基類是類層次結(jié)構(gòu)中最頂層的類,從這個(gè)基類可以派生出更加豐富多彩的派生類。
下面是一個(gè)基類PCI的例子,類中有command、address,data,CycleType等屬性。此外,這個(gè)基類還可以基于這些屬性,做各種各樣的事情,例如命令的發(fā)送。
每個(gè)設(shè)計(jì)中PCI總線支持的特性都是不同的,但是作為一個(gè)基類,PCI具有一些可以統(tǒng)一封裝在定義中的公共屬性和方法。
module class_TOP( ); class PCI; //Class properties logic [3:0] command; logic [31:0] address; logic [31:0] data; logic [3:0] CycleType; //base class constructor - initialization function new( ); command = 0; address = 0; CycleType = 4'hf; data = 64'bz; $display("PCI Init: data=%h command=%b addr=%h CycleType=%b", data, command, address, CycleType); endfunction task PCIWriteCycle (clk); begin command = $urandom; address = $urandom; CycleType = $urandom; $display("PCI Write Cycle : clk=%b data=%h command=%b addr=%h CycleType=%b", clk, data, command, address, CycleType); end endtask endclass : PCI bit clock; PCI PCI1; //defne variable PCI1 of type PCI initial begin PCI1 = new( ); //instantiate class – allocate memory //PCI1 now holds an object handle. end initial begin clock = 0; forever begin #10; clock=!clock; end end always @(posedge clock) begin //access class property using object handle PCI1 PCI1.data = $urandom; //Call Class method PCIWriteCycle PCI1.PCIWriteCycle(clock); end initial #60 $finish(2); endmodule
1、首先,我們聲明一個(gè)名為PCI的類。在這個(gè)類中,我們聲明了類屬性:
logic [3:0] command; logic [31:0] address; logic [31:0] data, mem; logic [3:0] CycleType;
2、然后聲明類構(gòu)造函數(shù)new(),用于初始化類屬性。如果不聲明,當(dāng)類被實(shí)例化時(shí)會(huì)調(diào)用隱式的new()函數(shù)。在本例中,函數(shù)new()將初始化為類中各個(gè)屬性的默認(rèn)值。2態(tài)變量初始化為0,4態(tài)變量初始化為x。
function new( ); command = 0; address = 0; CycleType = 4'hf; data = 64'bz; $display("PCI Init: data=%h command=%b addr=%h CycleType=%b", data, command, address, CycleType); endfunction
3、然后定義一個(gè)名為PCIWriteCycle的方法,這里是一個(gè)systemverilog function。在這個(gè)方法我們我們完成一些類屬性的簡(jiǎn)單賦值,從設(shè)計(jì)的含義上就是隨機(jī)發(fā)送不同的命令/地址/傳輸類型等信息。
task PCIWriteCycle (clk); begin command = $urandom; address = $urandom; CycleType = $urandom; $display("PCI Write Cycle : clk=%b data=%h command=%b addr=%h CycleType=%b", clk, data, command, address, CycleType); end endtask
4、在類定義之后,我們繼續(xù)聲明一個(gè)類的對(duì)象并示例化。注意:只有在調(diào)用new()之后才分配了實(shí)際的內(nèi)存,PCI1(對(duì)象)就是一個(gè)指向這個(gè)內(nèi)存空間的指針(或者是句柄,handle)。而如果不示例化,變量PCI1就是一個(gè)空指針“null”。
PCI PCI1; //defne variable PCI1 of type PCI PCI1 = new( ); //instantiate class – allocate memory
5、然后,我們使用對(duì)象句柄PCI1去調(diào)用類的方法PCIWriteCycle。
always @(posedge clock) begin //access class property using object handle PCI1 PCI1.data = $urandom; //Call Class method PCIWriteCycle PCI1.PCIWriteCycle(clock); end
仿真log:
PCI Init: data=zzzzzzzz command=0000 addr=00000000 CycleType=1111 PCI Write Cycle : clk=1 data=12153524 command=0001 addr=8484d609 CycleType=0011 PCI Write Cycle : clk=1 data=06b97b0d command=1101 addr=b2c28465 CycleType=0010 PCI Write Cycle : clk=1 data=00f3e301 command=1101 addr=3b23f176 CycleType=1101 $fnish called from fle "testbench.sv", line 52. $fnish at simulation time 60 V C S S i m u l a t i o n R e p o r t
審核編輯:湯梓紅
-
Verilog
+關(guān)注
關(guān)注
28文章
1343瀏覽量
109925 -
System
+關(guān)注
關(guān)注
0文章
165瀏覽量
36847 -
Class
+關(guān)注
關(guān)注
0文章
53瀏覽量
19701
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論