加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長(zhǎng)期合作伙伴
立即加入
  • 正文
    • 1.?策略模式
    • 2.?參考代碼
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

設(shè)計(jì)模式在芯片驗(yàn)證中的應(yīng)用——策略

06/12 16:25
1257
閱讀需 11 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

1.?策略模式

策略模式是一種行為設(shè)計(jì)模式, 它能讓你定義一系列算法, 并將每種算法分別放入獨(dú)立的類中, 以使算法的對(duì)象能夠相互替換。

在RTL設(shè)計(jì)中可能包含了復(fù)雜的多個(gè)訪問仲裁邏輯,使用了多種算法來確定訪問內(nèi)存優(yōu)先級(jí)順序,包括規(guī)定優(yōu)先級(jí)、輪詢仲裁等等。仲裁器的輸入是多個(gè)請(qǐng)求者信號(hào),以及選擇要使用的仲裁算法的配置。根據(jù)選擇的類型和請(qǐng)求者信號(hào)的值,仲裁器確定具有最高優(yōu)先級(jí)的請(qǐng)求源,并授予它訪問內(nèi)存的權(quán)利。如下圖所示,仲裁類型可以動(dòng)態(tài)配置,這就是為什么該特性適合使用策略設(shè)計(jì)模式進(jìn)行建模。

在該模式中,可以在testcase運(yùn)行中從提供的一系列算法中選擇要應(yīng)用的特定算法。此外,還可以直接為仲裁添加新算法,而無需修改之前代碼。值得注意的是,之前講到的裝飾器設(shè)計(jì)模式也可用于動(dòng)態(tài)更改行為,關(guān)鍵的區(qū)別在于,裝飾器模式在原功能基礎(chǔ)上添加額外的功能,而策略者模式直接更改原先功能??偟脕碚f,策略模式可以讓你改變對(duì)象的內(nèi)部結(jié)構(gòu),裝飾器模式允許你更改對(duì)象的皮膚。

策略設(shè)計(jì)模式主要包括以下幾個(gè)組件:

策略(Strategy):定義了所有具體策略(Concrete Strategies)的通用接口,它聲明了一個(gè)上下文(Context)用于執(zhí)行策略的方法。在這個(gè)例子中,策略定義了仲裁的接口函數(shù)arb_winner()。

具體策略(Concrete Strategies):實(shí)現(xiàn)了上下文所用算法的各種不同變體。在這個(gè)例子中,對(duì)于每個(gè)必要的算法,定義了一個(gè)具體策略類,提供特定算法的實(shí)現(xiàn)。將每個(gè)算法包裝到一個(gè)單獨(dú)的類中可以提高代碼的可讀性和可擴(kuò)展性。

上下文(Context):維護(hù)指向具體策略的引用,且僅通過策略接口與該對(duì)象進(jìn)行交流。比如UVM scoreboard組件依賴于Strategy,檢查RTL內(nèi)的仲裁邏輯是否正確實(shí)現(xiàn),那么UVM scoreboard可以被認(rèn)為是Context。

客戶端(Client):會(huì)創(chuàng)建一個(gè)特定策略對(duì)象并將其傳遞給上下文。上下文則會(huì)提供一個(gè)設(shè)置函數(shù)以便客戶端在運(yùn)行時(shí)替換相關(guān)聯(lián)的策略。當(dāng)上下文需要運(yùn)行算法時(shí),它會(huì)在其已連接的策略對(duì)象上調(diào)用執(zhí)行方法。上下文并不清楚其所涉及的策略類型與算法的執(zhí)行方式。本例的客戶端是example_application。

下圖為策略設(shè)計(jì)模式在仲裁中應(yīng)用的UML類圖。

策略模式讓你能將不同行為抽取到一個(gè)獨(dú)立類層次結(jié)構(gòu)中, 并將原始類組合成同一個(gè), 從而減少重復(fù)代碼。而且讓你能將各種算法的代碼、 內(nèi)部數(shù)據(jù)和依賴關(guān)系與其他代碼隔離開來。不同客戶端可通過一個(gè)簡(jiǎn)單接口執(zhí)行算法, 并能在運(yùn)行時(shí)進(jìn)行切換。

2.?參考代碼

仲裁處理的策略設(shè)計(jì)模式參考代碼如下:

virtual class strategy;    pure virtual function int arb_winner(ref bit req_arr[3]);endclass : strategy

class strategy_low_priority extends strategy;
    virtual function int arb_winner(ref bit req_arr[3]);        for (int i=0; i<3; i++) begin            if (req_arr[i] == 1) begin                return i;            end        end        return -1;    endfunction : arb_winner
endclass : strategy_low_priority

class strategy_high_priority extends strategy;
    virtual function int arb_winner(ref bit req_arr[3]);        for (int i=2; i>=0; i++) begin            if (req_arr[i] == 1) begin                return i;            end        end        return -1;    endfunction : arb_winner
endclass : strategy_high_priority
class my_context;
    local strategy m_strategy;
    function void set_strategy(strategy _m);        m_strategy = _m;    endfunction : set_strategy
    function int execute_strategy(ref bit req_arr[3]);        return m_strategy.arb_winner(req_arr);    endfunction : execute_strategy
endclass : my_context

模擬測(cè)試代碼如下:

class example_application;
    rand bit low_priority;    rand bit high_priority;
    constraint p_cons { low_priority + high_priority >= 1; }
    function void main();        int result;        bit req_arrary[3] = '{1'b0, 1'b1, 1'b1};        strategy stg;        my_context m_ctx = new();        `uvm_info("strategy", $psprintf("low_priority:%b, high_priority:%b", low_priority, high_priority), UVM_LOW)        $display("The input req0:%b, req1:%b, req2:%b", req_arrary[0], req_arrary[1], req_arrary[2]);        if ( low_priority ) begin            stg = strategy_low_priority::new();            m_ctx.set_strategy(stg);            result = m_ctx.execute_strategy(req_arrary);            $display("For low priority, the result is: %0d", result);        end        if ( high_priority ) begin            stg = strategy_high_priority::new();            m_ctx.set_strategy(stg);            result = m_ctx.execute_strategy(req_arrary);            $display("For high priority, the result is: %0d", result);        end
    endfunction : main
endclass : example_application

輸出仿真日志如下:

 | # [strategy] low_priority:1, high_priority:1 | # The input req0:0, req1:1, req2:1 | # For low priority, the result is: 1 | # For high priority, the result is: 2

從仿真結(jié)果可知,low_priority為1,high_priority為1,因此example_application類選取了strategy_low_priority類和strategy_high_priority類兩個(gè)算法。

在strategy_low_priority類中,輸入信號(hào)中,req0=0,req1=1,req2=1,req1輸入口被選中,因此輸出的結(jié)果是1。

在strategy_high_priority類中,輸入信號(hào)中,req0=0,req1=1,req2=1,req2輸入口被選中,因此輸出的結(jié)果是2。

微信號(hào)|c(diǎn)hip_yes,微信公眾號(hào)|專芯致志er

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
ST3215SB32768B0HSZA1 1 Kyocera AVX Components Quartz Crystal,

ECAD模型

下載ECAD模型
暫無數(shù)據(jù) 查看
KSZ8895RQXIA 1 Microchip Technology Inc DATACOM, ETHERNET TRANSCEIVER, PQFP128

ECAD模型

下載ECAD模型
$7.22 查看
HFBR-2528 1 Hewlett Packard Co Receiver, 5Mbps, DIP, Through Hole Mount
暫無數(shù)據(jù) 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜

分享Arm architecture, AMBA, 芯片驗(yàn)證, 腳本, EDA, Linux等知識(shí)。

微信公眾號(hào)