FSM(Finite State Machine)
分為2大類:
第一類,若輸出只和狀態有關而與輸入無關,則稱為Moore狀態機
第二類,輸出不僅和狀態有關而且和輸入有關系,則稱為Mealy狀態機
Mealy狀態機,常采用一段式寫法,只用了一個always陳述句,所有的狀態轉移,判斷狀態轉移條件,資料輸出都在一個always陳述句里,缺點是如果狀態太多,會使整段程式顯的冗長,
Moore狀態機,常采用三段式的寫法,狀態轉移用了一個always陳述句,判斷狀態轉移條件是組合邏輯always @(*),采用了一個always陳述句,資料輸出也是單獨的 always陳述句,這樣寫起來比較直觀清晰,狀態很多時也不會顯得繁瑣,
1. 旅鼠游戲介紹
在《旅鼠》這款游戲中,小動物的大腦相當簡單,簡單到我們要用一個有限狀態機來建立模型,在《旅鼠》的2D世界中,旅鼠可能會處于兩種狀態之一:向左走或向右走,如果碰到障礙物,它會改變方向,特別是,如果一只旅鼠被撞到左邊,它就會向右走,如果它在右邊被撞到,它就會向左走,如果它同時在兩邊碰撞,它仍然會改變方向,

實作一個Moore狀態機,它有兩個狀態、兩個輸入和一個輸出來模擬這種行為,
1 module top_module (
2 input clk,
3 input areset, //異步復位
4 input bump_left,
5 input bump_right,
6 output walk_left,
7 output walk_right
8 );
9
10
11 // 狀態引數設定,常見:二進制碼、格雷碼、獨熱碼、BCD碼
12 parameter WL=0, WR=1;
13 reg state; //當前狀態
14 reg next; //下個狀態
15
16
17 // Combinational always block for state transition logic. Given the current state and inputs,
18 // what should be next state be?
19 // Combinational always block: Use blocking assignments.
20 always@(*) begin
21 case (state)
22 WL: next = bump_left ? WR : WL;
23 WR: next = bump_right ? WL : WR;
24 endcase
25 end
26
27
28 // Combinational always block for state transition logic. Given the current state and inputs,
29 // what should be next state be?
30 // Combinational always block: Use blocking assignments.
31 always @(posedge clk, posedge areset) begin
32 if (areset) state <= WL;
33 else state <= next;
34 end
35
36
37 // 輸出組合邏輯,
38 // In more complex circuits, a combinational always block may be more suitable.
39 assign walk_left = (state==WL);
40 assign walk_right = (state==WR);
41
42
43 endmodule
2.旅鼠游戲補充
除了左右行走,旅鼠還會在地面消失時摔倒(可能會發出“啊!”的聲音),除了左右行走和顛簸時改變方向外,當地面=0時,旅鼠還會摔倒并說“啊!”當地面重新出現(地面=1)時,旅鼠會繼續沿著墜落前的方向行走,摔倒時被撞不會影響行走方向,在地面消失(但還沒有摔倒)的同一周期內被撞,或摔倒時地面重新出現,也不會影響行走危難,


除了行走和跌倒,有時候還會讓旅鼠做一些有用的事情,比如挖(當挖=1時它就開始挖了),如果旅鼠正在地面上行走(地面=1并且沒有掉下來),它可以繼續挖掘,直到它到達另一邊(地面=0),在這一點上,因為沒有地面,它會掉下來(啊!),然后在它再次撞擊地面時繼續朝原來的方向走,就像摔倒一樣,在挖的時候被撞到是沒有影響的,在摔倒或沒有地面的時候被告知挖也被忽略了,


雖然旅鼠可以走路、摔倒和挖洞,但旅鼠并非無懈可擊,如果旅鼠跌倒的時間過長就會撞到地面,它可能會GG,特別是,如果旅鼠跌倒超過20個時鐘周期,然后擊中地面,它將GG和停止行走,掉落,或挖掘(所有4個輸出變成0),永遠(或直到FSM重置),旅鼠在落地前墜落的距離沒有上限,旅鼠只有在撞擊地面時才會GG;它們不會在半空中GG,


1 module top_module(
2 input clk,
3 input areset, // Freshly brainwashed Lemmings walk left.
4 input bump_left,
5 input bump_right,
6 input ground,
7 input dig,
8 output walk_left,
9 output walk_right,
10 output aaah,
11 output digging );
12 parameter LEFT = 4'd0, RIGHT = 4'd1, FALL_L = 4'd2, FALL_R = 4'd3;
13 parameter DIG_L = 4'd4, DIG_R = 4'd5, DYING = 4'd6, SPLAT = 4'd7;
14 reg [3:0] current_state;
15 reg [3:0] next_state;
16 reg cnt_start;
17 reg [4:0]cnt_fall;
18
19 always@(posedge clk or posedge areset)begin
20 if(areset)begin
21 current_state <= LEFT;
22 end
23 else begin
24 current_state <= next_state;
25 end
26 end
27
28 always@(*)begin
29 case(current_state)
30 LEFT:begin
31 next_state = ground ? (dig ? DIG_L : (bump_left ? RIGHT : LEFT)) : FALL_L;
32 end
33 RIGHT:begin
34 next_state = ground ? (dig ? DIG_R : (bump_right ? LEFT : RIGHT)) : FALL_R;
35 end
36 FALL_L:begin
37 next_state = ground ? LEFT : ((cnt_fall==5'd20)?DYING:FALL_L);
38 end
39 FALL_R:begin
40 next_state = ground ? RIGHT : ((cnt_fall==5'd20)?DYING:FALL_R);
41 end
42 DIG_L:begin
43 next_state = ground ? DIG_L : FALL_L;
44 end
45 DIG_R:begin
46 next_state = ground ? DIG_R : FALL_R;
47 end
48 DYING:begin
49 next_state = ground ? SPLAT : DYING;
50 end
51 SPLAT:begin
52 next_state = SPLAT;
53 end
54 default:begin
55 next_state = LEFT;
56 end
57 endcase
58 end
59
60 always@(posedge clk or posedge areset)begin
61 if(areset)
62 cnt_fall <= 0;
63 else if(cnt_start)
64 cnt_fall <= cnt_fall+1'b1;
65 else
66 cnt_fall <= 0;
67 end
68
69 assign cnt_start = (next_state==FALL_L) || (next_state==FALL_R);
70
71 assign walk_left = (current_state == LEFT);
72 assign walk_right = (current_state == RIGHT);
73 assign digging = (current_state == DIG_L || current_state == DIG_R);
74 assign aaah = (current_state == FALL_L || current_state == FALL_R || current_state == DYING);
75
76 endmodule
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/270640.html
標籤:Verilog
