軟件設(shè)計(jì)中,F(xiàn)SM(Finite-State Machine)分為3部分:狀態(tài)(State),事件(Event),動作(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的行為;對于USB協(xié)議復(fù)雜的狀態(tài)機(jī),使用專門的FSM組件模擬,可以減少組件間的耦合;也可以將FSM組件的狀態(tài)賦值到virtual interface上,通過波形協(xié)助debug;
并不是所有DUT模塊中包含F(xiàn)SM,驗(yàn)證環(huán)境中就需要對應(yīng)的FSM建模;RTL的硬件電路是cycle級的時(shí)序電路,采用FSM可以很好的描述算法運(yùn)算;而驗(yàn)證環(huán)境都是事務(wù)級的基于事件的高級抽象模型,是否需要采用FSM根據(jù)驗(yàn)證環(huán)境而定;對于簡單的設(shè)計(jì),不需要模擬FSM;對于復(fù)雜的標(biāo)準(zhǔn)協(xié)議,VIP中都會采用FSM建模來完成,具有高內(nèi)聚低耦合的好處。
Simple example
本篇對一個(gè)示例,分別使用兩種方式來描述:
一個(gè)簡單的FSM如下,分為4種狀態(tài);對于狀態(tài)的跳轉(zhuǎn)條件,本篇通過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,對signal的驅(qū)動,或者調(diào)用其他組件的API等;僅做結(jié)構(gòu)上的演示;

通過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;通過request_state_change函數(shù)實(shí)現(xiàn)狀態(tài)跳轉(zhuǎn);每進(jìn)入一個(gè)狀態(tài),對應(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通過宏REGISTER_STATE創(chuàng)建各個(gè)state實(shí)例;state_machine中forvever執(zhí)行;狀態(tài)模式和策略模式的實(shí)現(xiàn)類似,都是使用OOP的組合 + 多態(tài)實(shí)現(xiàn);

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收集功能覆蓋率;
審核編輯:劉清
-
RTL
+關(guān)注
關(guān)注
1文章
393瀏覽量
62371 -
UVM
+關(guān)注
關(guān)注
0文章
183瀏覽量
19933 -
狀態(tài)機(jī)
+關(guān)注
關(guān)注
2文章
497瀏覽量
28827 -
fsm
+關(guān)注
關(guān)注
0文章
36瀏覽量
13071 -
DUT
+關(guān)注
關(guān)注
0文章
193瀏覽量
13356
原文標(biāo)題:UVM設(shè)計(jì)模式 (九) 狀態(tài)模式、Modelling Finite-State Machines in Testbench
文章出處:【微信號:數(shù)字芯片設(shè)計(jì)工程師,微信公眾號:數(shù)字芯片設(shè)計(jì)工程師】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
狀態(tài)機(jī)編程實(shí)例-面向?qū)ο蟮?b class='flag-5'>狀態(tài)設(shè)計(jì)模式
數(shù)字IC驗(yàn)證之“什么是UVM”“UVM的特點(diǎn)”“UVM提供哪些資源”(2)連載中...
數(shù)字IC驗(yàn)證之“典型的UVM平臺結(jié)構(gòu)”(3)連載中...
基于多模式匹配的狀態(tài)檢測技術(shù)
談UVM之sequence/item見解 sequencer特性及應(yīng)用(下)
C語言設(shè)計(jì)模式的程序資料合集
嵌入式軟件設(shè)計(jì)之設(shè)計(jì)模式
狀態(tài)模式(狀態(tài)機(jī))
設(shè)計(jì)模式行為型:狀態(tài)模式
c語言設(shè)計(jì)模式--狀態(tài)模式(狀態(tài)機(jī))
UVM設(shè)計(jì)模式之訪問者模式

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