【FPGA篇章四】FPGA状态机:三段式以及书写方法

欢迎大家关注我的微信公众账号,支持程序媛写出更多优秀的文章

 

状态机是fpga设计中极其重要的一种技巧,状态机通过不同的状态迁移来完成特定的逻辑操作,掌握状态机的写法可以使fpga的开发事半功倍。

状态机的分类

  Moore型状态机:状态机的变化只与当前的状态有关
  Mealy型状态机:状态机的变化不仅与当前的状态有关,还与输入有关


如何创建状态机

状态机的创建可以分为一段式,两段式和三段式

  一段式:主要是讲所有的状态变化以及导致的输出变化都写在了一个always模块中。

  两段式:一个always模块采用同步时序描述状态转移;另一个always模块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出。

  三段式:一个always模块采用同步时序描述状态转移;一个always模块采用组合逻辑判断状态转移条件,描述状态转移规律;另一个always模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。



举个例子:从循环输入的字母中做连续检测,当连续检测到“hello”时,将led灯进行状态的翻转,继续进行下一次的检测。

 一段式的编写方式:

 1 module  hello(
 2 input clk,//系统时钟信号  50mHz
 3 input rst_n,//系统复位信号,低电平有效
 4 input [7:0] data,//连续输入的字母
 5 output reg led//led灯
 6 );
 7 
 8 //设置需要改变的状态
 9 parameter    checkh  = 5'b0000_1,
10              checke  = 5'b0001_0,
11              checkla = 5'b0010_0,
12              checklb = 5'b0100_0,
13              checko = 5'b1000_0;
14 
15 reg [4:0]state;
16 
17 always @(posedge clk or negedge rst_n)
18     if(!rst_n)
19         begin
20             led <= 1'b0;
21             state <= checkh;
22         end
23     else 
24         begin
25             case (state)
26                 checkh:
27                     if(data == "h") state <= checke;
28                     else  state <= checkh;
29                 checke:
30                     if(data == "e") state <= checkla;
31                     else  state <= checkh;
32                 checkla:
33                     if(data == "l") state <= checklb;
34                     else  state <= checkh;
35                 checklb:
36                     if(data == "l") state <= checko;
37                     else  state <= checkh;
38                 checko:
39                     if(data == "o")
40                         begin
41                         led <= ~led;
42                         state <= checkh;
43                         end
44                     else  state <= checkh;
45                 default:state <= checkh;
46             endcase
47         end
48 
49 endmodule

二段式的编写方式:

 1 module  hello(
 2 input clk,
 3 input rst_n,
 4 input [7:0] data,
 5 output reg led
 6 );
 7 
 8 parameter checkh  = 5'b0000_1,
 9                 checke  = 5'b0001_0,
10                 checkla = 5'b0010_0,
11                 checklb = 5'b0100_0,
12                 checko  = 5'b1000_0;
13 
14 reg [4:0] cstate; // 当前状态
15 reg [4:0] nstate; // 下一状态
16 
17 always @(posedge clk or negedge rst_n)
18 if(!rst_n)
19        cstate <= checkh;
20 else 
21        cstate <= nstate;
22 
23 always @(cstate or data)
24             case (cstate)
25                 checkh:
26                     if(data == "h") nstate <= checke;
27                     else  nstate <= checkh;
28                 checke:
29                     if(data == "e") nstate <= checkla;
30                     else  nstate <= checkh;
31                 checkla:
32                     if(data == "l") nstate <= checklb;
33                     else  nstate <= checkh;
34                 checklb:
35                     if(data == "l") nstate <= checko;
36                     else  nstate <= checkh;
37                 checko:
38                     if(data == "o")
39                         begin
40                         led <= ~led;
41                         nstate <= checkh;
42                         end
43                     else  nstate <= checkh;
44                 default:nstate <= checkh;
45             endcase
46 
47 endmodule

三段式的编写方式:

 1 module  hello(
 2 input clk,
 3 input rst_n,
 4 input [7:0] data,
 5 output reg led
 6 );
 7 
 8 parameter checkh  = 5'b0000_1,
 9                 checke  = 5'b0001_0,
10                 checkla = 5'b0010_0,
11                 checklb = 5'b0100_0,
12                 checko = 5'b1000_0;
13 
14 reg [4:0] cstate; // 当前状态
15 reg [4:0] nstate; // 下一状态
16 
17 //复位信号,clk的处理(主要是对初始状态进行赋值操作)
18 always @(posedge clk or negedge rst_n)
19 if(!rst_n)
20     cstate <= checkh;
21 else 
22     cstate <= nstate;
23 
24 //状态迁移的处理
25 always @(cstate or data)
26             case (cstate)
27                 checkh:
28                     if(data == "h") nstate <= checke;
29                     else  nstate <= checkh;
30                 checke:
31                     if(data == "e") nstate <= checkla;
32                     else  nstate <= checkh;
33                 checkla:
34                     if(data == "l") nstate <= checklb;
35                     else  nstate <= checkh;
36                 checklb:
37                     if(data == "l") nstate <= checko;
38                     else  nstate <= checkh;
39                 checko:
40                     if(data == "o")
41                         begin
42                             nstate <= checkh;
43                         end
44                     else  nstate <= checkh;
45                 default:nstate <= checkh;
46             endcase
47 
48 //输出数据的处理
49 always @(posedge clk or negedge rst_n)
50 if(!rst_n)
51         led <= 1'b1;
52 
53 else 
54         case (cstate)   
55                 checko:
56                     if(data == "o")
57                         led <= ~led;
58                 default;
59         endcase
60 
61 endmodule
原文地址:https://www.cnblogs.com/streetlive/p/12642287.html