狀態機可以用兩種方法實現:豎著寫
(在狀態中判斷事件
)和橫著寫
(在事件中判斷狀態
)。這兩種實現在本質上是完全等效的,但在實際操作中,效果卻截然不同。
******************************====
豎著寫
(在狀態中判斷事件
)c
**片段
******************************====
cur_state = nxt_state;
switch(cur_state)
else if(e1_event)
else if(e2_event)
break;
case s1: //在
s1狀態
if(e2_event)
break;
case s2: //在
s2狀態
if(e0_event)
}******************************====
橫著寫
(在事件中判斷狀態
)c
**片段
******************************====
//e0
事件發生時,執行的函式
void e0_event_function(int * nxt_state)
} //e1
事件發生時,執行的函式
void e1_event_function(int * nxt_state)
} //e2
事件發生時,執行的函式
void e2_event_function(int * nxt_state)
} 上面橫豎兩種寫法的**片段,實現的功能完全相同,但是,橫著寫的效果明顯好於豎著寫的效果。理由如下:
1、豎著寫隱含了優先順序排序
(其實各個事件是同優先順序的
),排在前面的事件判斷將毫無疑問地優先於排在後面的事件判斷。這種
if/else if
寫法上的限制將破壞事件間原有的關係。而橫著寫不存在此問題。
2、由於處在每個狀態時的事件數目不一致,而且事件發生的時間是隨機的,無法預先確定,導致豎著寫淪落為順序查詢方式,結構上的缺陷使得大量時間被浪費。對於橫著寫,在某個時間點,狀態是唯一確定的,在事件裡查詢狀態只要使用
switch
語句,就能一步定位到相應的狀態,延遲時間可以預先準確估算。而且在事件發生時,呼叫事件函式,在函式裡查詢唯一確定的狀態,並根據其執行動作和狀態轉移的思路清晰簡潔,效率高,富有美感。
總之,我個人認為,在軟體裡寫狀態機,使用橫著寫的方法比較妥帖。
豎著寫的方法也不是完全不能使用,在一些小專案裡,邏輯不太複雜,功能精簡,同時為了節約記憶體耗費,豎著寫的方法也不失為一種合適的選擇。
三種不同狀態機寫法
1 reg 3 0 cs,ns 2 always posedge clk or negedge rst n begin 3 if rst n begin 4 cs idle 5 cmd 3 b111 6 end 7 else begin 8 case cs 9 idle if wr req begi...
三種狀態機 分析 對比和小結
本文簡化所有邏輯重點講解狀態機的框架。先給幾點小結 小結1.在原理圖和實際變現上來說,一段式和三段式完全一致,但在 量大的情況下三段式 更容易維護。小結2.二段式的輸出由組合邏輯驅動,不僅可能輸出毛刺,而且不利於時許約束 分析。小結3.狀態機有著流水線的 缺點 上電之初若不全面指定初始狀態,則可能有...
OSPF的七種狀態機
router id 在乙個ospf域內,用於標識每台路由器的id。選舉規則 1.手工指定 建議 2.如果沒有手工指定,使用loopback介面中最大的ip位址作為router id 3.如果沒有配置loopback介面,那麼使用物理介面中最大的ip位址作為router id 鏈路狀態資訊 鏈路資訊包...