亚洲精品久久久久久久久久久,亚洲国产精品一区二区制服,亚洲精品午夜精品,国产成人精品综合在线观看,最近2019中文字幕一页二页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

教你如何寫(xiě)出性能更高的SystemVerilog代碼

冬至子 ? 來(lái)源:CSDN ? 作者:谷公子 ? 2023-07-26 17:31 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

本文旨在幫助大家降低在編碼過(guò)程中寫(xiě)出低性能和耗內(nèi)存的概率,只要大家在寫(xiě)代碼時(shí)稍注意下,積少成多。當(dāng)然,使用代碼分析工具也可以調(diào)試優(yōu)化代碼的性能,它可以分析出代碼中性能和內(nèi)存消耗的問(wèn)題,如果這些地方可以重構(gòu),那么代碼也可以得到改進(jìn)。但在沒(méi)有分析工具的情況下,可視化代碼檢查是必需。

1. 循環(huán)

循環(huán)的性能是由以下因素決定:

  • 循環(huán)內(nèi)進(jìn)行的工作;
  • 在循環(huán)中進(jìn)行的檢查,以確定它是否可以退出;

在循環(huán)內(nèi)進(jìn)行的工作應(yīng)該保持在最低限度,并且對(duì)循環(huán)邊界進(jìn)行的檢查應(yīng)該具有最低的開(kāi)銷。典型例子如下:

例子1:在循環(huán)開(kāi)始之前將變量設(shè)置為數(shù)組的大小,可以節(jié)省每次迭代時(shí)計(jì)算a.size()的開(kāi)銷。

// Lower Performance Version
int a[];
int total = 0;
for(int i = 0; i < a.size(); i++) begin
    total += a[i];
end
// Higher Performance Version
int a[];
int a_size;
int total = 0;
a_size = a.size();
for(int i = 0; i < a_size; i++) begin
    total += a[i];
end

例子2:在循環(huán)中搜索數(shù)組的特定值,一旦找到就可以終止循環(huán)了。

// Lower Performance Version
int a[50];
int find = -1;
// Look up an index via the array:
foreach(a[i]) begin
    if(a[i] == 20) begin
        find = i;
    end
end
// Higher Performance Version
int a[50];
int find = -1;
// Look up an index via the array:
foreach(a[i]) begin
    if(a[i] == 20) begin
        find = i;
        break;
    end
end

例子3:在每次循環(huán)迭代時(shí)查找關(guān)聯(lián)數(shù)組中的值是不必要的,因?yàn)樗梢栽谘h(huán)開(kāi)始時(shí)查找。另外在小數(shù)組方面,foreach()循環(huán)結(jié)構(gòu)通常比f(wàn)or(int i = 0;i

// Lower Performance Version
int a[];
int b[string];
foreach ( a[i] ) begin
    total += a[i] * b["yes"];
end
// Higher Performance Version
int a[];
int b[string];
int t = b["yes"];
foreach ( a[i] ) begin
    total += a[i] * t;
end

2. 決策

在邏輯或算術(shù)基礎(chǔ)上做決策時(shí),有許多優(yōu)化可以幫助提高性能。

一旦發(fā)現(xiàn)邏輯表達(dá)式的一個(gè)元素為假,就放棄對(duì)它的求值,它可以加快決策的速度,因此邏輯表達(dá)式中各個(gè)運(yùn)算數(shù)的排序可以避免不必要的性能開(kāi)銷,如下例子:

例子1:對(duì)于AND求值,如果表達(dá)式的第一項(xiàng)為假,則跳過(guò)求值的其余部分。

if(A && B && C) begin
    // do something
end

例子2:對(duì)于OR求值,如果表達(dá)式的第一項(xiàng)為真,則跳過(guò)求值的其余部分。

if(A || B || C) begin
    // do something
end

例子3:如果表達(dá)式中的各項(xiàng)具有不同級(jí)別的性能開(kāi)銷,則應(yīng)該對(duì)這些項(xiàng)進(jìn)行排序,首先計(jì)算開(kāi)銷最小的項(xiàng)。

// Lower Performance Version
if((B.size() > 0) && B[$] == 42 && A) begin
    // do something
end
// Higher Performance Version
if(A && (B.size() > 0) && B[$] == 42) begin
    // do something
end

優(yōu)化算術(shù)運(yùn)算也可以實(shí)現(xiàn)優(yōu)化,這不僅適用于決策邏輯,也適用于計(jì)算變量。如下例子避免了一個(gè)乘法操作。

// Lower Performance Version
if(((A*B) - (A*C)) > E) begin
    // do something
end
// Higher Performance Version
if((A*(B - C)) > E) begin
    // do something
end

如果知道決策樹(shù)中條件的相對(duì)頻率,則將最頻繁出現(xiàn)的條件移到樹(shù)的頂部,這最常應(yīng)用于case語(yǔ)句和嵌套if語(yǔ)句。

例子1:大多數(shù)情況下,case語(yǔ)句在一次檢查后退出,節(jié)省了進(jìn)一步的比較。

// Lower Performance Version
// Case options follow the natural order:
case(char_state)
    START_BIT:  // do_something to start tracking the char (once per word)
    TRANS_BIT:  // do something to follow the char bit value (many times per word)
    PARITY_BIT: // Check parity (once per word, optional)
    STOP_BIT:   // Check stop bit (once per word)
endcase
// Higher Performance Version
// case options follow order of likely occurrence:
case(char_state)
    TRANS_BIT:  // do something to follow the char bit value (many times per word)
    START_BIT:  // do_something to start tracking the char (once per word)
    STOP_BIT:   // Check stop bit (once per word)
    PARITY_BIT: // Check parity (once per word, optional)
endcase

例子2:如果ready無(wú)效,則不會(huì)計(jì)算其余代碼,然后進(jìn)行read_cycle檢查,這樣就不需要進(jìn)行write_cycle檢查了。

// Lower Performance Version
// ready is not valid most of the time
// read cycles predominate
if(write_cycle) begin
    if(addr inside {[2000:10000]}) begin
        if(ready) begin
            // do something
        end
    end
end
else if(read_cycle) begin
    if(ready) begin
        // do something
    end
end
// Higher Performance Version
// ready is not valid most of the time
// read cycles predominate
if(ready) begin
    if(read_cycle) begin
        // do something
    end
    else begin
        if(addr inside {[2000:10000]}) begin
        // do something
        end
    end
end

3. 方法調(diào)用

task和function統(tǒng)稱為method(方法)。在某些情況下,重構(gòu)調(diào)用方法的代碼會(huì)更好,以便將方法的內(nèi)容展開(kāi)直接放到代碼中,而不是使用方法調(diào)用。如果方法相對(duì)較短并且有多個(gè)參數(shù),那更可以提升性能了。

在Systemverilog中,通過(guò)在task或function調(diào)用開(kāi)始時(shí)復(fù)制變量,然后將方法執(zhí)行期間所做的任何更改結(jié)果復(fù)制回去,來(lái)完成向task和function傳遞參數(shù)的功能。如果參數(shù)是復(fù)雜的變量類型(如字符串或數(shù)組),那么這可能會(huì)造成相當(dāng)大的開(kāi)銷,而另一種選擇是使用引用(ref)。使用ref節(jié)省了參數(shù)傳遞拷貝的開(kāi)銷,如果變量在任務(wù)或函數(shù)中被更新,則它不會(huì)被復(fù)制到函數(shù)中,因此它也會(huì)在調(diào)用方法中被更新。如果不想讓它被更新,可以讓變量為const ref,這將使其稱為只讀引用的。例子如下,在性能較低的代碼版本中,將一個(gè)int類型隊(duì)列和一個(gè)字符串復(fù)制到函數(shù)中。隨著隊(duì)列長(zhǎng)度的增長(zhǎng),將會(huì)影響到更多的性能和內(nèi)存。而在高性能版本中,int類型隊(duì)列和string參數(shù)都是引用,這避免了復(fù)制操作并加快了函數(shù)的執(zhí)行速度。

// Lower Performance Version
function void do_it(input int q[$], input string name);
    // ...
endfunction: do_it
// Higher Performance Version
function void do_it(ref int q[$], ref string name);
    // ...
endfunction: do_it

4. 數(shù)組

SystemVerilog有許多具有不同特征的數(shù)據(jù)類型,在使用時(shí)需要考慮哪種類型的數(shù)組最適合。如下列出了這些數(shù)組的特性。

image.png

例如,使用關(guān)聯(lián)數(shù)組而不是使用靜態(tài)數(shù)組對(duì)只有稀疏條目的大型內(nèi)存空間進(jìn)行建??赡芨行?。但是,如果關(guān)聯(lián)數(shù)組由于條目的數(shù)量而變得很大,那么使用固定數(shù)組來(lái)建模內(nèi)存空間將變得更有效。

在關(guān)聯(lián)數(shù)組的使用中,可能會(huì)使用未添加到數(shù)組的索引進(jìn)行訪問(wèn),例如稀疏內(nèi)存。當(dāng)關(guān)聯(lián)數(shù)組獲得超出范圍的訪問(wèn)權(quán)限時(shí),默認(rèn)情況下它將返回一條警告消息以及一個(gè)未初始化的值。為了避免這種情況,可以查詢數(shù)組以確定索引是否存在,如果不存在,則不進(jìn)行訪問(wèn)。如果使用默認(rèn)變量語(yǔ)法,那么可以通過(guò)性能改進(jìn)來(lái)避免這項(xiàng)工作,例子如下:

// Lower Performance Version
// Associative array declaration - no default value:
int aa[int];
if(aa.exists(i)) begin
    lookup = aa[i];
end
// Higher Performance Version
// Associative array declaration - setting the default to 0
int aa[int] = {default:0};
lookup = aa[i];

5. 類

在Systemverilog中,類封裝了屬性(數(shù)據(jù)變量)和對(duì)這些屬性進(jìn)行操作的方法。可以擴(kuò)展類以添加更多變量,并添加或擴(kuò)展現(xiàn)有方法以提供新功能。所有這些便利和功能帶來(lái)了性能開(kāi)銷,可以通過(guò)以下方法來(lái)優(yōu)化。

盡量減少創(chuàng)建對(duì)象的數(shù)量,因?yàn)槊繕?gòu)造一個(gè)對(duì)象可能會(huì)有一個(gè)與之相關(guān)的開(kāi)銷。如下優(yōu)化例子:

// Lower Performance Version
function chi_class get(chi_state_t chi_state);
    chi_class chi_txn = new();
    if ( chi_state == ON ) begin
        // ...
    end
    return null;
endfunction : get
// Higher Performance Version
function chi_class get(chi_state_t chi_state);
    chi_class chi_txn;
    if ( chi_state == ON ) begin
        chi_txn = new();
        // ...
    end
    return chi_txn;
endfunction : get

直接對(duì)變量賦值比調(diào)用set()/get()方法更快,調(diào)用方法來(lái)更新或檢查變量比通過(guò)類層次路徑直接訪問(wèn)帶來(lái)更高的開(kāi)銷。普通的OOP準(zhǔn)則建議類中的數(shù)據(jù)變量只能通過(guò)方法訪問(wèn)。使用直接類層次路徑訪問(wèn)變量可以提高性能,但可能會(huì)降低代碼的可重用性,并且依賴于用戶知道所討論的變量的名稱和類型的假設(shè)。具體情況需要具體分析。

class name;
    int A;
    function void set_A(int value);
        A = value;
    endfunction: set_A
endclass : name
// Lower Performance Version
name m = new();
m.set_A(1);
// Higher Performance Version
name m = new();
m.A = 1;

另外在類中調(diào)用方法會(huì)帶來(lái)開(kāi)銷,嵌套或?qū)⒎椒ㄕ{(diào)用鏈接在一起也會(huì)增加開(kāi)銷,在實(shí)現(xiàn)或擴(kuò)展類時(shí),盡量減少所涉及的方法嵌套層次。

6. 隨機(jī)約束

隨機(jī)約束生成是SystemVerilog中最強(qiáng)大的功能之一。在類中編寫(xiě)受約束的隨機(jī)代碼時(shí),需要考慮以下幾點(diǎn):

  • 除非必須,要盡量減少隨機(jī)函數(shù)的調(diào)用;
  • 盡量減少rand變量的數(shù)量,如果一個(gè)值可以從其它隨機(jī)變量中計(jì)算出來(lái),那么它不應(yīng)該被定義為rand;
  • 使用最小的數(shù)據(jù)類型,比如能用bit就不用logic,并將數(shù)據(jù)位寬調(diào)整到所需要的最小值;
  • 使用分層類結(jié)構(gòu)來(lái)減少隨機(jī)化;
  • 避免在約束中使用算術(shù)運(yùn)算符;
  • 隱含運(yùn)算符是雙向的,使用solve before來(lái)強(qiáng)制前項(xiàng)的概率分布;
  • 使用pre_randomize()方法預(yù)先設(shè)置或預(yù)先計(jì)算隨機(jī)化過(guò)程中使用的狀態(tài)變量;
  • 使用post_randomize()方法來(lái)計(jì)算依賴于隨機(jī)變量的變量值;

7. 覆蓋率

Covergroup基本上是一組計(jì)數(shù)器,當(dāng)采樣值與bin匹配時(shí),計(jì)數(shù)器會(huì)增加,覆蓋率提升性能的方法是盡可能使用covergroup。Covergroup的基本規(guī)則是管理采樣bins的創(chuàng)建和covergroup的采樣。

每個(gè)coverpoint自動(dòng)轉(zhuǎn)換為一組bins或計(jì)數(shù)器,用于在覆蓋點(diǎn)中采樣的變量的每個(gè)可能值。這相當(dāng)于2n個(gè)bins,其中n是變量中的位數(shù),但這通常被SystemVerilog auto_bins_max變量限制為最多64個(gè)bins。在寫(xiě)covergroup時(shí)要仔細(xì)分析,在目的達(dá)到的基礎(chǔ)上,盡量減少創(chuàng)建bins的數(shù)目,有助于提供性能。另外,在控制采樣時(shí)刻上要盡量在期望的行為發(fā)生時(shí)去調(diào)用sample,而不是在每個(gè)時(shí)鐘沿。

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編碼器
    +關(guān)注

    關(guān)注

    45

    文章

    3884

    瀏覽量

    141023
  • 計(jì)數(shù)器
    +關(guān)注

    關(guān)注

    32

    文章

    2304

    瀏覽量

    97388
  • 運(yùn)算器
    +關(guān)注

    關(guān)注

    1

    文章

    164

    瀏覽量

    16936
  • Verilog語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    113

    瀏覽量

    8714
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    何為高質(zhì)量的代碼?如何寫(xiě)出高質(zhì)量代碼

    懂得“數(shù)據(jù)結(jié)構(gòu)與算法” 寫(xiě)出高效的代碼,懂得“設(shè)計(jì)模式”寫(xiě)出高質(zhì)量的代碼
    發(fā)表于 08-02 09:44 ?1206次閱讀
    何為高質(zhì)量的<b class='flag-5'>代碼</b>?<b class='flag-5'>如何寫(xiě)出</b>高質(zhì)量<b class='flag-5'>代碼</b>?

    如何寫(xiě)出好的代碼?高質(zhì)量代碼的三要素

    膾炙人口的詩(shī)"春有百花秋有月,夏有涼風(fēng)冬有雪",意境唯美,簡(jiǎn)明易懂。好的代碼也是讓人陶醉的,那么如何寫(xiě)出好的代碼
    的頭像 發(fā)表于 01-05 11:29 ?2056次閱讀
    <b class='flag-5'>如何寫(xiě)出</b>好的<b class='flag-5'>代碼</b>?高質(zhì)量<b class='flag-5'>代碼</b>的三要素

    如何寫(xiě)出時(shí)序最優(yōu)的HDL代碼?如何寫(xiě)出時(shí)序裕量足夠的代碼?

    你想寫(xiě)出可以跑出700M以上的代碼嗎,直逼FPGA內(nèi)部PLL的極限。
    的頭像 發(fā)表于 03-12 09:59 ?1518次閱讀
    <b class='flag-5'>如何寫(xiě)出</b>時(shí)序最優(yōu)的HDL<b class='flag-5'>代碼</b>?<b class='flag-5'>如何寫(xiě)出</b>時(shí)序裕量足夠的<b class='flag-5'>代碼</b>?

    如何寫(xiě)出可以讓人理解的代碼(以verilog語(yǔ)言為例)?

    如何寫(xiě)出可以讓人理解的代碼(以verilog語(yǔ)言為例)?1. 代碼要比較好理解,最容易做到的就是把代碼寫(xiě)短,因此在每個(gè)always語(yǔ)句塊盡可能只處理一個(gè)信號(hào),或者只處理一組相關(guān)度很高的
    發(fā)表于 02-01 11:39

    round robin 的 systemverilog 代碼

    大家好,我對(duì)一個(gè) round robin 的 systemverilog 代碼有疑惑。https://www.edaplayground.com/x/2TzD代碼第49和54行是怎么解析呢 ?
    發(fā)表于 03-14 19:16

    如何寫(xiě)出高效并且簡(jiǎn)潔易于閱讀的單片機(jī)C語(yǔ)言代碼呢?

    單片機(jī)的運(yùn)行除去需要硬件的支持之外,高效簡(jiǎn)潔的C語(yǔ)言也是非常重要的因素之一。那么如何寫(xiě)出高效并且簡(jiǎn)潔易于閱讀的單片機(jī)C語(yǔ)言代碼呢?本文將為大家介紹如何寫(xiě)出優(yōu)美簡(jiǎn)潔 的單片機(jī)循環(huán)語(yǔ)句,感興趣的朋友快來(lái)
    發(fā)表于 07-15 06:34

    如何寫(xiě)出多串口共用printf函數(shù)語(yǔ)句呢

    如何寫(xiě)出多串口共用printf函數(shù)語(yǔ)句呢?求大神解答
    發(fā)表于 11-17 06:37

    用C語(yǔ)言如何寫(xiě)出單片機(jī)延時(shí)程序,且延時(shí)時(shí)間如何計(jì)算的?

    用C語(yǔ)言,如何寫(xiě)出單片機(jī)延時(shí)程序,且延時(shí)時(shí)間如何計(jì)算的?
    發(fā)表于 10-18 08:19

    設(shè)備驅(qū)動(dòng)的入門教程 (教你如何寫(xiě)驅(qū)動(dòng))

    設(shè)備驅(qū)動(dòng)的入門教程 (教你如何寫(xiě)驅(qū)動(dòng))
    發(fā)表于 03-28 09:44 ?61次下載

    如何寫(xiě)出讓CPU執(zhí)行更快的代碼

    轉(zhuǎn)自:小林coding 前言 代碼都是由 CPU 跑起來(lái)的,我們代碼寫(xiě)的好與壞就決定了 CPU 的執(zhí)行效率,特別是在編寫(xiě)計(jì)算密集型的程序,更要注重 CPU 的執(zhí)行效率,否則將會(huì)大大影響系統(tǒng)性能
    的頭像 發(fā)表于 10-29 11:21 ?2731次閱讀
    <b class='flag-5'>如何寫(xiě)出</b>讓CPU執(zhí)行更快的<b class='flag-5'>代碼</b>?

    一本教你怎么寫(xiě)出讓同事無(wú)法維護(hù)的代碼

    ?對(duì),你沒(méi)看錯(cuò),本文就是教你怎么寫(xiě)出讓同事無(wú)法維護(hù)的代碼。一、程序命名 容易輸入的變量名 。比如:Fred,asdf 單字母的變量名 。比如:a,b,c, x,y,z(如果不夠用,可以考慮a1,a2
    的頭像 發(fā)表于 10-11 15:45 ?1474次閱讀

    教你如何寫(xiě)ADC代碼,輸出電壓,讀取光敏值。

    如何寫(xiě)DA轉(zhuǎn)化代碼:s: 即startADDRESS: 即器件地址(0表示為寫(xiě))A:表示等待回應(yīng)CONTROL BYTE: 表示控制字(第二個(gè)發(fā)送的字節(jié))A:表示等待回應(yīng)DATE BYTE: 表示寫(xiě)入的電壓值(注意如果寫(xiě)入255,其實(shí)結(jié)果是5v,以此來(lái)?yè)Q算)A:表示等待
    發(fā)表于 12-20 18:44 ?6次下載
    <b class='flag-5'>教你</b><b class='flag-5'>如何寫(xiě)</b>ADC<b class='flag-5'>代碼</b>,輸出電壓,讀取光敏值。

    C語(yǔ)言如何寫(xiě)出高效代碼呢?

    當(dāng)涉及復(fù)雜的高效C代碼案例時(shí),這些代碼示例展示了C語(yǔ)言中一些復(fù)雜且高效的應(yīng)用案例,涵蓋了排序算法、圖算法、位操作、文件操作、多線程編程等領(lǐng)域。
    發(fā)表于 09-06 14:57 ?1025次閱讀
    C語(yǔ)言<b class='flag-5'>如何寫(xiě)出</b>高效<b class='flag-5'>代碼</b>呢?

    如何寫(xiě)出高效優(yōu)美的C語(yǔ)言代碼

    電子發(fā)燒友網(wǎng)站提供《如何寫(xiě)出高效優(yōu)美的C語(yǔ)言代碼.pdf》資料免費(fèi)下載
    發(fā)表于 11-18 10:55 ?0次下載
    <b class='flag-5'>如何寫(xiě)出</b>高效優(yōu)美的C語(yǔ)言<b class='flag-5'>代碼</b>

    如何寫(xiě)出穩(wěn)定的單片機(jī)代碼

    這篇文章分享怎么寫(xiě)出穩(wěn)定的單片機(jī)代碼。? ?? 我對(duì)優(yōu)秀代碼的理解,大體分為兩個(gè)部分:高效和穩(wěn)定。 ? 兩者都能做到很好的,如果靠自己摸索,沒(méi)有刻意去練習(xí),可能需要花10年,甚至更久
    的頭像 發(fā)表于 11-15 16:40 ?1024次閱讀
    <b class='flag-5'>如何寫(xiě)出</b>穩(wěn)定的單片機(jī)<b class='flag-5'>代碼</b>