SystemVerilog 类和对象(三)
類和對象
- 一、類的基本概念
- 二、對象的創建和銷毀
- 三、對象句柄的深拷貝 與 淺拷貝
- 四、類的特性
- 4.1.封裝
- 4.2.繼承
- 4.3.多態
- 包的使用
一、類的基本概念
二、對象的創建和銷毀
class wordbyte nb[];function new(int n);nb = new[n]; //動態數組空間開辟endfunction endclassinitial begin : initial_1word wd;//聲明句柄for(int i=1;i<=4;i++) wd = new(i); //創建了4個對象 end initial begin : initial_2#1ps$display("How many Bytes are allocated for word instance?") end若wd = new(1)所需開辟的空間為1B,那么執行完開辟空間:
wd執行完,句柄指向第四個對象,4B。由于initial中是靜態變量,即使initial執行完了,那么變量還在。
三、對象句柄的深拷貝 與 淺拷貝
1)、 淺拷貝:只拷貝對象中的數據變量,淺拷貝前后的數據變量使用不同的內存空間;而對于對象中的**數據操作(任務和函數)**和其中定義的其它類的句柄,采取類似“引用操作”的方式,淺拷貝前后共用同一內存空間。
BusTran bt0, bt1; //聲明兩個句柄 b1 = new(); //b1創建對象 b2 = new b1; //b2創建對象,同時對b1進行淺拷貝2)、 深拷貝:對于對象中的所有成員統一分配新的內存空間,區別于淺拷貝。
BusTran bt0, bt1; //聲明兩個句柄 b1 = new(); //b1創建對象 b2 = new(); //b2創建對象 b2.copy(b1); //深拷貝,自定義copy函數四、類的特性
class clock local bit is_summer = 0;local int nclock = 6;function int get_clock();if(!is_summer) return this.nclock;else return this.nclock+1;endfunctionfunction bit set_summer(bit s);this.is_summer = s;endfunction endclassclock ck;initial beginck = new();$display("now tome is %0d", ck.get_clock());ck.set_summer(1);$display("noe time is %0d", ck.nclock); end第一個打印為6;第二個編譯出錯。外部句柄ck不能訪問nclock變量(加了限定local)。但可以訪問沒加限制的function。
4.1.封裝
4.2.繼承
子類繼承了父類所有的成員方法和屬性,并且可以擁有自己特性。通過關鍵字extends實現繼承解決了代碼的重用問題。
子類既包含繼承父類的成員方法和屬性,也有自己獨特的個性方法(青出于藍而勝于藍),所以如果想要將一個指向父類的指針轉化為指向子類的指針,無法直接轉換,(父親大人,時代變了!)必須通過$cast(),在system veilog中被稱為向下類型轉換(downcasting)。
- 向上類型轉換:
- $cast向下類型轉換
子類繼承父類時新增加一個函數,該函數與父類中的某函數同名,調用時會調用新增的函數,而不是繼承下來的函數。
對于子類類新增同名函數成員的訪問:“對象名.成員名”;
對于父類中同名函數成員的訪問:“(子類)對象名.基類名::成員名”
4.3.多態
調用同一個函數,實現不同的行為就是多態。但要滿足兩點要求:
虛函數virtual function
被virtual修飾的類成員函數稱為虛函數。虛函數是動態綁定的,如果子類需要修改父類的行為(即重寫與基類函數同名的函數),就應該在父類中將相應的函數聲明為虛函數。使用虛函數應當注意:
- 父類中某一成員函數聲明為virtual虛函數后,子類中的同名函數(同名、同參、同類型)自動生成虛函數。
- 子類的同名虛函數會重寫或覆蓋原來父類中的同名虛函數.。
虛類virtual class
虛類通過關鍵字virtual聲明,不能被例化(不能創建對象),但可以通過派生,生成有用的子類,也可聲明一個虛類的指針,通過抽象類的指針指向不同的子類對象。進而訪問子類對象的虛函數,實現多態性。
正常情況下,父類是不可以訪問子類中方法的,但是通過虛父類可以實現。
注意:虛方法定義盡量在底層父類中,因為虛方法只需要聲明一次即可。在父類之下的子類都無需聲明了,如果virtual是聲明在類繼承關系的中間層類中,那么只有從該中間類到其子類的調用鏈中會遵循動態查找,而最底層類到該中間類的方法調用仍然會遵循靜態查找。
A、虛方法只需要在父類中聲明,不需要在子類定義時添加virtual關鍵詞。
B、虛方法可以使子類在不調用super.method()時也會自動執行父類的方法。
C、使用了虛方法定義的父類句柄在指向子類對象時,可以動態索引到同名的子類變量。
D、與父類虛方法同名的子類方法在繼承時可以使用不同類型的參數。
只有A正確
其他 virtual interface;virtual function/task 參考https://blog.csdn.net/liujingyu_1205/article/details/81563010
module OOP_EXTENDS();class BusTran;bit [31:0] addr,crc,data[7];virtual function bit[31:0] calc_crc; //虛方法目的——實現多態crc=addr^data.xor; //異或:奇數個1異或,結果為1;偶數個1異或,結果為0calc_crc=crc; //返回值 endfunctionfunction void dsp_addr(input string handle);$display("*****%s.ADDR = %0h",handle,addr);endfunctionfunction void dsp_crc(input string handle);$display("*****BusTran %s.crc = %h",handle,crc);endfunctionendclassclass BadBusTran extends BusTran; //繼承bit bad_crc;virtual function bit[31:0] calc_crc(); //虛方法目的——實現多態; 派生類中的同名函數的virtual可以省略super.calc_crc(); //通過關鍵字super,實現子類對父類成員的調用if(bad_crc) crc = ~crc;calc_crc = crc;endfunctionendclassBusTrans bt0; //聲明父類句柄BadBusTran bbt0; //聲明父類句柄initial beginbt0 = new;$display("*****handle bt0 is : %0h",bt0);bbt0 = new;$display("*****handle bbt0 is : %0h",bbt0);bt0.addr = 32'hFFFF_FFFF;bt0.dsp_addr("bt0");bbt0.addr = 32'h1111_1111;bt0.dsp_addr("bbt0"); foreach(bt0.data[i]) beginbt0.data[i] = 32'h0000_FFFF;endbt0.calc_crc;bt0.dsp_crc("bt0");foreach(bbt0.data[i]) beginbbt0.data[i] = 32'hFFFF_FFFF;endbbt0.calc_crc; //此時未設置bad_crc,二值變量默認初始值為0bbt0.dsp_crc("bbt0");bbt0.bad_crc = 1;$display("*****After bad crc set to 1");bbt0.calc_crc;bbt0.dsp_crc("bbt0");end //Polymorphism——多態function bit[31:0] crc(BusTran bt); //多態——句柄傳遞過程中,會根據句柄自動識別所屬類crc = bt.calc_crc();endfunctionbit [31:0] crc_value;initial begin #10;crc_value = crc(bt0);$display("*****crc from bt0 = %0h",crc_value);crc_value = crc(bbt0);$display("*****crc from bt0 = %0h",crc_value); endendmodule包的使用
參考:
Mr.翟的博客
Systemverilog(綠皮書)
總結
以上是生活随笔為你收集整理的SystemVerilog 类和对象(三)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Pr学习DAY3-----详解“源监视器
- 下一篇: 可可英语奇文老师 全方位搞定英语词汇听说