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

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

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

UVM設(shè)計(jì)模式之狀態(tài)模式介紹

rfdqdzdg ? 來(lái)源:csdn ? 2023-08-22 09:14 ? 次閱讀

軟件設(shè)計(jì)中,F(xiàn)SM(Finite-State Machine)分為3部分:狀態(tài)(State),事件(Event),動(dòng)作(Action)。

狀態(tài)模式(State Pattern)是行為型(Behavioral)設(shè)計(jì)模式,將軟件主機(jī)端的行為歸類為各個(gè)狀態(tài),狀態(tài)之間可以互相轉(zhuǎn)化,每種狀態(tài)的行為不相同;統(tǒng)一交給一個(gè)Context類型的模塊負(fù)責(zé)調(diào)度各個(gè)狀態(tài)的跳轉(zhuǎn);

硬件設(shè)計(jì)中的FSM,不僅是一種電路的描述工具,而且也是一種思想方法;數(shù)字邏輯本質(zhì)上都可以歸一化為FSM;RTL描述FSM可以歸類為常用的幾種方法,通常采用三段式的描述;

在我們的驗(yàn)證環(huán)境中,有時(shí)也需要一個(gè)組件專門負(fù)責(zé)FSM的建模;例如驗(yàn)證USB Device DUT時(shí),驗(yàn)證環(huán)境需要模擬USB Host的行為;對(duì)于USB協(xié)議復(fù)雜的狀態(tài)機(jī),使用專門的FSM組件模擬,可以減少組件間的耦合;也可以將FSM組件的狀態(tài)賦值到virtual interface上,通過(guò)波形協(xié)助debug;

并不是所有DUT模塊中包含F(xiàn)SM,驗(yàn)證環(huán)境中就需要對(duì)應(yīng)的FSM建模;RTL的硬件電路是cycle級(jí)的時(shí)序電路,采用FSM可以很好的描述算法運(yùn)算;而驗(yàn)證環(huán)境都是事務(wù)級(jí)的基于事件的高級(jí)抽象模型,是否需要采用FSM根據(jù)驗(yàn)證環(huán)境而定;對(duì)于簡(jiǎn)單的設(shè)計(jì),不需要模擬FSM;對(duì)于復(fù)雜的標(biāo)準(zhǔn)協(xié)議,VIP中都會(huì)采用FSM建模來(lái)完成,具有高內(nèi)聚低耦合的好處。

Simple example

本篇對(duì)一個(gè)示例,分別使用兩種方式來(lái)描述:

一個(gè)簡(jiǎn)單的FSM如下,分為4種狀態(tài);對(duì)于狀態(tài)的跳轉(zhuǎn)條件,本篇通過(guò)uvm_event類型的事件觸發(fā),驗(yàn)證環(huán)境中的實(shí)際情況可以是事件,某一個(gè)signal狀態(tài),或者if的判斷等;不同狀態(tài)下的Action,僅使用一句display代表,驗(yàn)證環(huán)境中的實(shí)際情況可以調(diào)用某一個(gè)task,對(duì)signal的驅(qū)動(dòng),或者調(diào)用其他組件的API等;僅做結(jié)構(gòu)上的演示;

abca6fa2-4088-11ee-ac96-dac502259ad0.png

通過(guò)randsequence產(chǎn)生激勵(lì)sequence,遍歷狀態(tài)機(jī)跳轉(zhuǎn)條件;

classclient;

state_machineFSM;
uvm_event_poolevents_pool;
uvm_eventto_idle,to_state_a,to_state_b,to_state_c;

functionnew();
events_pool=uvm_event_pool::get_global_pool();
to_idle=events_pool.get("to_idle");
to_state_a=events_pool.get("to_state_a");
to_state_b=events_pool.get("to_state_b");
to_state_c=events_pool.get("to_state_c");
endfunction

taskrand_simulate();
for(inti=0;i<2;i++)?begin
??????bit?FLAG?=?0;
??????randsequence?(stream)

?????????stream?:?first?second?third?last;
?????????first??:?state_a;
?????????second?:?state_b?{FLAG?=?1;}?|?state_c;
?????????third??:?if?(FLAG?==1)?state_c?else?state_b;
?????????last???:?state_idle;

?????????state_idle:?{`INTERVALTIME;to_idle.trigger();};
?????????state_a???:?{`INTERVALTIME;to_state_a.trigger();};
?????????state_b???:?{`INTERVALTIME;to_state_b.trigger();};
?????????state_c???:?{`INTERVALTIME;to_state_c.trigger();};

??????endsequence
??????end
???endtask
?......
?......

use task

類state_machine包含四個(gè)狀態(tài)的task;通過(guò)request_state_change函數(shù)實(shí)現(xiàn)狀態(tài)跳轉(zhuǎn);每進(jìn)入一個(gè)狀態(tài),對(duì)應(yīng)一個(gè)線程,當(dāng)跳出狀態(tài)時(shí),注意線程需要disable掉;

classstate_machine;

typedefenum{
IDLE,STATE_A,STATE_B,STATE_C
}state_t;

uvm_event_poolevents_pool;
uvm_eventto_idle,to_state_a,to_state_b,to_state_c;

localstate_tcur_state;

externfunctionnew();
externfunctionvoidstart();
externfunctionvoidrequest_state_change(state_tcur_state);
externtaskdo_idle();
externtaskdo_state_a();
externtaskdo_state_b();
externtaskdo_state_c();

endclass

functionstate_machine::new();
events_pool=uvm_event_pool::get_global_pool();
to_idle=events_pool.get("to_idle");
to_state_a=events_pool.get("to_state_a");
to_state_b=events_pool.get("to_state_b");
to_state_c=events_pool.get("to_state_c");
endfunction

functionvoidstate_machine::start();
cur_state=IDLE;
request_state_change(cur_state);
endfunction

functionvoidstate_machine::request_state_change(state_tcur_state);
case(cur_state)
IDLE:begin
fork
begin
$display("Enter%sstate!",cur_state.name());
do_idle();
end
join_none
return;
end
STATE_A:begin
fork
begin
$display("Enter%sstate!",cur_state.name());
do_state_a();
end
join_none
return;
end
STATE_B:begin
fork
begin
$display("Enter%sstate!",cur_state.name());
do_state_b();
end
join_none
return;
end
STATE_C:begin
fork
begin
$display("Enter%sstate!",cur_state.name());
do_state_c();
end
join_none
return;
end
default:begin
$display("Enterunknowstate!");
$finish;
end
endcase
endfunction

taskstate_machine::do_idle();
state_tcur_state;
$display("IDLE:nothingtodo!
");
fork:disable_fork
begin
to_state_a.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_A;
end
join_any
request_state_change(cur_state);
endtask

taskstate_machine::do_state_a();
state_tcur_state;
$display("STATE_A:dosomething!
");
fork:disable_fork
begin
to_state_b.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_B;
end
begin
to_state_c.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_C;
end
join_any
disablefork;
request_state_change(cur_state);
endtask

taskstate_machine::do_state_b();
state_tcur_state;
$display("STATE_B:dosomething!
");
fork:disable_fork
begin
to_state_c.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_C;
end
begin
to_idle.wait_trigger();
//$display("dosomething!
");
cur_state=IDLE;
end
join_any
disablefork;
request_state_change(cur_state);
endtask

taskstate_machine::do_state_c();
state_tcur_state;
$display("STATE_C:dosomething!
");
fork:disable_fork
begin
to_state_b.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_B;
end
begin
to_idle.wait_trigger();
//$display("dosomething!
");
cur_state=IDLE;
end
join_any
disablefork;
request_state_change(cur_state);
endtask

use Sate Pattern

采用狀態(tài)模式的設(shè)計(jì),每個(gè)狀態(tài)繼承于virtual class state,實(shí)現(xiàn)各自的do_something和request_state_change;state_machine通過(guò)宏REGISTER_STATE創(chuàng)建各個(gè)state實(shí)例;state_machine中forvever執(zhí)行;狀態(tài)模式和策略模式的實(shí)現(xiàn)類似,都是使用OOP的組合 + 多態(tài)實(shí)現(xiàn);

abeb39b2-4088-11ee-ac96-dac502259ad0.png

virtualclassstate;

state_machineFSM;
uvm_event_poolevents_pool;
uvm_eventto_idle,to_state_a,to_state_b,to_state_c;

functionnew();
events_pool=uvm_event_pool::get_global_pool();
to_idle=events_pool.get("to_idle");
to_state_a=events_pool.get("to_state_a");
to_state_b=events_pool.get("to_state_b");
to_state_c=events_pool.get("to_state_c");
endfunction
purevirtualtaskdo_something();
purevirtualtaskrequest_state_change();
endclass

classstate_idleextendsstate;

taskdo_something();
$display("STATE_IDLE:nothingtodo!
");
endtask

taskrequest_state_change();
state_tcur_state;
fork:disable_fork
begin
to_state_a.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_A;
end
join_any
FSM.set_state(cur_state);
endtask
endclass

classstate_aextendsstate;

taskdo_something();
$display("STATE_A:dosomething!
");
endtask

taskrequest_state_change();
state_tcur_state;
fork:disable_fork
begin
to_state_b.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_B;
end
begin
to_state_c.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_C;
end
join_any
disablefork;
FSM.set_state(cur_state);
endtask
endclass

classstate_bextendsstate;

taskdo_something();
$display("STATE_B:dosomething!
");
endtask

taskrequest_state_change();
state_tcur_state;
fork:disable_fork
begin
to_state_c.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_C;
end
begin
to_idle.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_IDLE;
end
join_any
disablefork;
FSM.set_state(cur_state);
endtask
endclass

classstate_cextendsstate;

taskdo_something();
$display("STATE_C:dosomething!
");
endtask

taskrequest_state_change();
state_tcur_state;
fork:disable_fork
begin
to_state_b.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_B;
end
begin
to_idle.wait_trigger();
//$display("dosomething!
");
cur_state=STATE_IDLE;
end
join_any
disablefork;
FSM.set_state(cur_state);
endtask
endclass

classstate_machine;

localstatestate_m;
statestate_pool[state_t];

functionvoidset_state(state_tstate);
$display("Enter%sstate!",state.name());
state_m=state_pool[state];
endfunction


functionvoidfsm_init();
`REGISTER_STATE(IDLE,idle)
`REGISTER_STATE(A,a)
`REGISTER_STATE(B,b)
`REGISTER_STATE(C,c)
this.set_state(STATE_IDLE);
endfunction

taskrun();
fsm_init();
foreverbegin
state_m.do_something();
state_m.request_state_change();
end
endtask
endclass

note

state_machine中還可以加入reset stop函數(shù)控制FSM的更多行為;封裝更多API供其他模塊調(diào)用;加入assertion做基于cycle的條件判斷;加入covergroup收集功能覆蓋率;






審核編輯:劉清

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

    關(guān)注

    1

    文章

    385

    瀏覽量

    59924
  • UVM
    UVM
    +關(guān)注

    關(guān)注

    0

    文章

    182

    瀏覽量

    19215
  • 狀態(tài)機(jī)
    +關(guān)注

    關(guān)注

    2

    文章

    492

    瀏覽量

    27628
  • fsm
    fsm
    +關(guān)注

    關(guān)注

    0

    文章

    35

    瀏覽量

    12840
  • DUT
    DUT
    +關(guān)注

    關(guān)注

    0

    文章

    189

    瀏覽量

    12466

原文標(biāo)題:UVM設(shè)計(jì)模式 (九) 狀態(tài)模式、Modelling Finite-State Machines in Testbench

文章出處:【微信號(hào):數(shù)字芯片設(shè)計(jì)工程師,微信公眾號(hào):數(shù)字芯片設(shè)計(jì)工程師】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    狀態(tài)機(jī)編程實(shí)例-面向?qū)ο蟮?b class='flag-5'>狀態(tài)設(shè)計(jì)模式

    本編介紹狀態(tài)機(jī)編程的第3種方法——面向?qū)ο蟮?b class='flag-5'>狀態(tài)設(shè)計(jì)模式,通過(guò)C++的繼承特性,以及類指針,實(shí)現(xiàn)炸彈拆除小游戲中的狀態(tài)機(jī)功能。
    的頭像 發(fā)表于 06-28 09:04 ?1590次閱讀
    <b class='flag-5'>狀態(tài)</b>機(jī)編程實(shí)例-面向?qū)ο蟮?b class='flag-5'>狀態(tài)</b>設(shè)計(jì)<b class='flag-5'>模式</b>

    數(shù)字IC驗(yàn)證“什么是UVM”“UVM的特點(diǎn)”“UVM提供哪些資源”(2)連載中...

    原文鏈接:https://zhuanlan.zhihu.com/p/345775995大家好,我是一哥,上章內(nèi)容主要講述兩個(gè)內(nèi)容,芯片驗(yàn)證以及驗(yàn)證計(jì)劃。那本章我們主要講述的內(nèi)容有介紹什么是uvm
    發(fā)表于 01-21 16:00

    數(shù)字IC驗(yàn)證“典型的UVM平臺(tái)結(jié)構(gòu)”(3)連載中...

    的passitage模式,從圖中可以看出,每增加一個(gè)測(cè)試模塊,平臺(tái)中就會(huì)增加一個(gè)與相對(duì)應(yīng)的agent,因?yàn)檫@些agent在測(cè)試單個(gè)模塊的時(shí)候已經(jīng)完成了,所以這里只需要將它們集成到一個(gè)env當(dāng)中即可,這體現(xiàn)了uvm測(cè)試平臺(tái)的可重
    發(fā)表于 01-22 15:32

    基于多模式匹配的狀態(tài)檢測(cè)技術(shù)

    提出了一種基于多模式匹配的狀態(tài)檢測(cè)方案,借助網(wǎng)絡(luò)處理器PowerPC MPC8572E 的模式匹配模塊及其狀態(tài)規(guī)則引擎,能夠針對(duì)包含多種特征信息的協(xié)議,檢測(cè)出協(xié)議所
    發(fā)表于 06-22 16:38 ?21次下載
    基于多<b class='flag-5'>模式</b>匹配的<b class='flag-5'>狀態(tài)</b>檢測(cè)技術(shù)

    UVMsequence/item見解 sequencer特性及應(yīng)用(下)

    _SEQ_ARB_WEIGHTED;UVM_SEQ_ARB_RANDOM ;UVM_SEQ_ARB_STRICT_FIFO等。出其中三種需要特別區(qū)分外其它的模式可以滿足絕大多數(shù)的仲裁需求。
    的頭像 發(fā)表于 02-19 10:14 ?4839次閱讀
    談<b class='flag-5'>UVM</b><b class='flag-5'>之</b>sequence/item見解 sequencer特性及應(yīng)用(下)

    C語(yǔ)言設(shè)計(jì)模式的程序資料合集

    本文檔的主要內(nèi)容詳細(xì)介紹的是C語(yǔ)言設(shè)計(jì)模式的程序資料合集包括了:C語(yǔ)言設(shè)計(jì)模式_繼承-多態(tài)-封裝,C語(yǔ)言設(shè)計(jì)模式
    發(fā)表于 11-16 08:00 ?5次下載

    嵌入式軟件設(shè)計(jì)設(shè)計(jì)模式

    文章目錄前言1.設(shè)計(jì)模式適配器模式2.設(shè)計(jì)模式單例模式3.設(shè)計(jì)
    發(fā)表于 10-21 11:07 ?9次下載
    嵌入式軟件設(shè)計(jì)<b class='flag-5'>之</b>設(shè)計(jì)<b class='flag-5'>模式</b>

    狀態(tài)模式(狀態(tài)機(jī))

    以前寫狀態(tài)機(jī),比較常用的方式是用 if-else 或 switch-case,高級(jí)的一點(diǎn)是函數(shù)指針列表。最近,看了一文章《c語(yǔ)言設(shè)計(jì)模式狀態(tài)模式(
    發(fā)表于 12-16 16:53 ?9次下載
    <b class='flag-5'>狀態(tài)</b><b class='flag-5'>模式</b>(<b class='flag-5'>狀態(tài)</b>機(jī))

    設(shè)計(jì)模式行為型:狀態(tài)模式

    狀態(tài)模式(State Pattern)中,類的行為是基于它的狀態(tài)改變的。這種類型的設(shè)計(jì)模式屬于行為型模式。
    的頭像 發(fā)表于 06-07 11:20 ?646次閱讀
    設(shè)計(jì)<b class='flag-5'>模式</b>行為型:<b class='flag-5'>狀態(tài)</b><b class='flag-5'>模式</b>

    c語(yǔ)言設(shè)計(jì)模式--狀態(tài)模式(狀態(tài)機(jī))

    狀態(tài)模式(狀態(tài)機(jī))是嵌入式開發(fā)中最重要、最核心的設(shè)計(jì)模式之一,毫不夸張的說(shuō),是否熟練掌握狀態(tài)模式
    的頭像 發(fā)表于 06-14 15:28 ?1658次閱讀
    c語(yǔ)言設(shè)計(jì)<b class='flag-5'>模式</b>--<b class='flag-5'>狀態(tài)</b><b class='flag-5'>模式</b>(<b class='flag-5'>狀態(tài)</b>機(jī))

    CW32 低功耗模式的特性介紹

    CW32系列芯片支持3種工作模式,運(yùn)行模式、休眠模式以及深度休眠模式,本文以CW32L083為例介紹低功耗
    的頭像 發(fā)表于 12-30 10:53 ?1181次閱讀
    CW32 低功耗<b class='flag-5'>模式</b>的特性<b class='flag-5'>介紹</b>

    一文詳解UVM設(shè)計(jì)模式

    本篇是對(duì)UVM設(shè)計(jì)模式 ( 二 ) 參數(shù)化類、靜態(tài)變量/方法/類、單例模式、UVM_ROOT、工廠模式
    的頭像 發(fā)表于 08-06 10:38 ?2060次閱讀
    一文詳解<b class='flag-5'>UVM</b>設(shè)計(jì)<b class='flag-5'>模式</b>

    行為型設(shè)計(jì)模式UVM中的應(yīng)用

    接下來(lái)介紹行為型設(shè)計(jì)模式UVM中的應(yīng)用。
    的頭像 發(fā)表于 08-09 14:01 ?741次閱讀
    行為型設(shè)計(jì)<b class='flag-5'>模式</b>在<b class='flag-5'>UVM</b>中的應(yīng)用

    UVM設(shè)計(jì)模式訪問者模式

    Visitor Pattern: 允許一個(gè)或者多個(gè)操作應(yīng)用到一組對(duì)象上,解耦操作和對(duì)象本身。換言之,如果component的數(shù)據(jù)結(jié)構(gòu)是比較穩(wěn)定的,但其是易于變化的,那么使用訪問者模式是個(gè)不錯(cuò)的選擇。
    的頭像 發(fā)表于 08-11 09:28 ?806次閱讀
    <b class='flag-5'>UVM</b>設(shè)計(jì)<b class='flag-5'>模式</b><b class='flag-5'>之</b>訪問者<b class='flag-5'>模式</b>

    迭代模式UVM中的應(yīng)用有哪些

    行為型設(shè)計(jì)模式數(shù)量較多,上一篇介紹了模板模式和策略模式,下面對(duì)迭代模式進(jìn)行介紹,挖掘其在
    的頭像 發(fā)表于 08-14 17:15 ?647次閱讀
    迭代<b class='flag-5'>模式</b>在<b class='flag-5'>UVM</b>中的應(yīng)用有哪些