日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

SystemVerilog 类和对象(三)

發布時間:2024/3/24 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SystemVerilog 类和对象(三) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

類和對象

  • 一、類的基本概念
  • 二、對象的創建和銷毀
  • 三、對象句柄的深拷貝 與 淺拷貝
  • 四、類的特性
    • 4.1.封裝
    • 4.2.繼承
    • 4.3.多態
  • 包的使用

一、類的基本概念

  • 類class:是一種用來進行數據抽象的工具,將數據和對數據的操作封裝在一起,提供建立對象的模板,可以看做是一種數據結構。
  • 對象object:是所屬類class的某一特定實體(也稱實例)。
  • 句柄handle:指向對象的指針,即內存的基地址。
  • 屬性property:類class的實體object中所包含的各種變量variable。
  • 方法method:操作變量的任務task和函數function。
  • 二、對象的創建和銷毀

    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)。

    • 向上類型轉換
    transaction_class tr = new(); //父類 subtransaction_class sc = new(); //子類 tr = sc; //子類(右)指向父類(左),這是正確的可以直接轉換
    • $cast向下類型轉換
    transaction_class tr;//父類 subtransaction_class sc; //子類 sc = new(); tr = sc; //句柄類型轉化為同一類型,父句柄類型轉化為子句柄類型 $cast(sc,tr); // 通過cast方式可以實現,可以看到tr的句柄類型雖然是父類,但其指的對象類型是子類

    子類繼承父類時新增加一個函數,該函數與父類中的某函數同名,調用時會調用新增的函數,而不是繼承下來的函數。

  • 如果父類與子類的函數同名,但是參數不同,此時不論有無關鍵字virtual,父類的函數都將被隱藏。
  • 如果父類與子類的函數同名,參數也相同,但是基類函數無關鍵字virtual,父類的函數都將被隱藏。(如果父類函數有virtual,則會形成多態)
  • 對于子類類新增同名函數成員的訪問:“對象名.成員名”;
    對于父類中同名函數成員的訪問:“(子類)對象名.基類名::成員名”

    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 类和对象(三)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。