有限状态机,有限状态机设计

数字系统有两大类有限状态机(Finite State Machine,FSM):Moore状态机和Mealy状态机。
Moore状态机
其最大特点是输出只由当前状态确定,与输入无关。Moore状态机的状态图中的每一个状态都包含一个输出信号。这是一个典型的Moore状态机的状态跳转图,x、y、z是输入,a、b、c是输出。
有限状态机设计有限状态机
Mealy状态机
它的输出不仅与当前状态有关系,而且与它的输入也有关系,因而在状态图中每条转移边需要包含输入和输出的信息。
有限状态机设计有限状态机
状态编码
数字逻辑系统状态机设计中常见的编码方式有:二进制码(Binary码)、格雷码(Gray码)、独热码(One-hot码)以及二一十进制码(BCD码)。
格雷码的特点:相邻的两个码组之间仅有一位不同。
普通二进制码与格雷码之间可以相互转换。
二进制码转换为格雷码:从最右边一位起,一次与左边一位“异或”,作为对应格雷码该位的值,最左边的一位不变(相当于最左边是0)。
格雷码转换为二进制码:从左边第二位起,将每一位与左边一位解码后的值“异或”,作为该解码后的值(最左边的一位依然不变)。
独热码又分为独热1码和独热0码,是一种特殊的二进制编码方式。当任何一种状态有且仅有一个1时,就是独热1码,相反任何一种状态有且仅有一个0时,就是独热0码。
状态机的描述
状态机有三种描述方式:一段式状态机、两段式状态机、三段式状态机。下面就用一个小例子来看看三种方式是如何实现的。
有限状态机设计有限状态机
一段式状态机
当把整个状态机卸载一个always模块中,并且这个模块既包含状态转移,又含有组合逻辑输入/输出时,称为一段式状态机。不推荐采用这种状态机,因为从代码风格方面来讲,一般都会要求把组合逻辑和时序逻辑分开;从代码维护和升级来说,组合逻辑和书序逻辑混合在一起不利于代码维护和修改,也不利于约束。
1 //一段式状态机来实现:在异步复位信号的控制下,一段式状态机进入IDLE 2 //状态,q_sig4被复位,一旦sig1或者sig2有效,状态机进入WAIT状态,如果 3 //sig1和sig2同时有效,那么状态机进入DONE状态, 4 //如果sig4还有效,那么q_sig4置位,同时状态机进入IDLE状态。 5 6 module _disibledevent=> 7 //数据声明部分 8 input clk,reset,sig1,sig2,sig3; 9 10 output reg q_sig4; 11 output reg [1:0] q_sm_state; 12 13 //参数声明 14 parameter IDLE = 2'b00; 15 parameter WAIT = 2'b01; 16 parameter DONE = 2'b10; 17 18 //状态跳转逻辑程序设计 19 always @(posedge clk or posedge reset) 20 begin 21 if(reset) 22 begin 23 q_sig4 <= 0; 24 q_sm_state <= IDLE; 25 end 26 else 27 begin 28 case(q_sm_state) 29 IDLE: begin 30 if(sig1 || sig2) 31 begin 32 q_sm_state <= WAIT; 33 q_sig4 <= 1'b0; 34 end 35 else 36 begin 37 q_sm_state <= IDLE; 38 q_sig4 <= 1'b0; 39 end 40 end 41 WAIT: begin 42 if(sig2 && sig3) 43 begin 44 q_sm_state <= DONE; 45 q_sig4 <= 1'b0; 46 end 47 else 48 begin 49 q_sm_state <= WAIT; 50 q_sig4 <= 1'b0; 51 end 52 end 53 54 DONE:begin 55 if(sig3) 56 begin 57 q_sm_state <= IDLE; 58 q_sig4 <= 1'b1; 59 end 60 else 61 begin 62 q_sm_state <= DONE; 63 q_sig4 <= 1'b0; 64 end 65 end 66 67 default: begin 68 q_sm_state <= IDLE; 69 q_sig4 <= 0; 70 end 71 endcase 72 end 73 end 74 endmodule

两段式状态机
所谓的两段式状态机就是采用一个always语句来实现时序逻辑,另外一个always语句来实现组合逻辑,提高了代码的可读性,易于维护。不同于一段式状态机的是,它需要定义两个状态----现态和次态,然后通过现态和次态的转换来实现时序逻辑。
1 //本例主要采用两段式状态机:在异步复位信号的控制下,一段式状态机进入IDLE 2 //状态,q_sig4被复位,一旦sig1或者sig2有效,状态机进入WAIT状态,如果sig1和sig2同时有效,那么 3 //状态机进入DONE状态,如果sig4还有效,那么q_sig4置位,同时状态机进入IDLE状态。 4 5 module two_seg_fsm(clk,reset,sig1,sig2,sig3,q_sig4); 6 //数据声明部分 7 input clk,reset,sig1,sig2,sig3; 8 9 output reg q_sig4; 10 11 reg [1:0] current_state, next_state; 12 13 //参数声明 14 parameter IDLE = 2'b00; 15 parameter WAIT = 2'b01; 16 parameter DONE = 2'b10; 17 18 //状态跳转程序设计 19 always @(posedge clk or posedge reset) 20 if(reset) 21 current_state <= IDLE; 22 else 23 current_state <= next_state; 24 25 //状态逻辑输出 26 always @(current_state or sig1 or sig2 or sig3) 27 begin 28 case(current_state) 29 IDLE: begin 30 if(sig1 || sig2) 31 begin 32 next_state = WAIT; 33 q_sig4 = 1'b0; 34 end 35 else 36 begin 37 next_state = IDLE; 38 q_sig4 = 1'b0; 39 end 40 end 41 WAIT: begin 42 if(sig2 && sig3) 43 begin 44 next_state = DONE; 45 q_sig4 = 1'b0; 46 end 47 else 48 begin 49 next_state = WAIT; 50 q_sig4 = 1'b0; 51 end 52 end 53 54 DONE:begin 55 if(sig3) 56 begin 57 next_state = IDLE; 58 q_sig4 = 1'b1; 59 end 60 else 61 begin 62 next_state = DONE; 63 q_sig4 = 1'b0; 64 end 65 end 66 67 default: begin 68 next_state = IDLE; 69 q_sig4 = 0; 70 end 71 endcase 72 73 end 74 endmodule

三段式状态机
三段式状态机与两段式状态机的区别:两段式直接采用组合逻辑输出,而三段式则通过在组合逻辑后再增加一级寄存器来实现时序逻辑输出。这样做的好处是可以有效地滤去租个逻辑输出的毛刺,同时可以有效地进行时序计算与约束,另外对于总线形式的输出信号来说,容易使总线数据对其,从而减小总线数据间的偏移,减小接收端数据采样出错的频率。
三段式状态机的基本格式是:第一个always语句实现同步状态跳转;第二个always语句实现组合逻辑;第三个always语句实现同步输出。
1 //本例主要采用三段式状态机:在异步复位信号的控制下,一段式状态机进入IDLE 2 //状态,q_sig4被复位,一旦sig1或者sig2有效,状态机进入WAIT状态,如果sig1和sig2同时有效,那么 3 //状态机进入DONE状态,如果sig4还有效,那么q_sig4置位,同时状态机进入IDLE状态。 4 5 module three_seg_fsm(clk,reset,sig1,sig2,sig3,q_sig4); 6 //数据声明部分 7 input clk,reset,sig1,sig2,sig3; 8 9 output reg q_sig4; 10 11 reg [1:0] current_state, next_state; 12 13 //参数声明 14 parameter IDLE = 2'b00; 15 parameter WAIT = 2'b01; 16 parameter DONE = 2'b10; 17 18 //状态跳转程序设计 19 always @(posedge clk or posedge reset) 20 if(reset) 21 current_state <= IDLE; 22 else 23 current_state <= next_state; 24 25 //状态跳转输出 26 always @(current_state or sig1 or sig2 or sig3) 27 begin 28 case(current_state) 29 IDLE: begin 30 if(sig1 || sig2) 31 begin 32 next_state = WAIT; 33 end 34 else 35 begin 36 next_state = IDLE; 37 end 38 end 39 WAIT: begin 40 if(sig2 && sig3) 41 begin 42 next_state = DONE; 43 end 44 else 45 begin 46 next_state = WAIT; 47 end 48 end 49 50 DONE:begin 51 if(sig3) 52 begin 53 next_state = IDLE; 54 end 55 else 56 begin 57 next_state = DONE; 58 end 59 end 60 61 default: begin 62 next_state = IDLE; 63 end 64 endcase 65 end 66 67 //逻辑输出 68 always @(posedge clk or posedge reset) 69 if(reset) 70 q_sig4 <= 1'b0; 71 else 72 begin 73 case(next_state) 74 IDLE, 75 WAIT: q_sig4 <= 1'b0; 76 DONE: q_sig4 <= 1'b1; 77 default: q_sig4 <= 1'b0; 78 endcase 79 end 80 81 endmodule


Tags:  有限状态机原理 有限状态机代码 有限状态机优点 状态机设计交通灯 有限状态机

延伸阅读

最新评论

发表评论