赞
踩
状态机的本质就是对具有逻辑顺序和时序规律的事件的一种描述方法,它有三个要素:状态、输入、输出:状态也叫做状态变量(比如可以用电机的不同转速作为状态),输出指在某一个状态的特定输出,输入指状态机中进入每个状态的条件。
有限状态机(Finite State Machine, FSM),根据状态机的输出是否与输入有关,可分为Moore型状态机和Mealy型状态机。
Moore型状态机输出仅仅与现态有关,Mealy型状态机不仅与现态有关,也与输入有关,所以会受到输入的干扰,可能会产生毛刺(Glith)的现象,所以我们通常使用的是Moore型状态机。
Mealy型状态机:
Moore型状态机:
状态机描述时关键是要描述清楚几个状态机的要素,即如何进行状态转移,每个状态的输出是什么,状态转移的条件等。具体描述时方法各种各样,最常见的有三种描述方式:
一段式:整个状态机写到一个always模块里面,在该模块中既描述状态转移,又描述状态的输入和输出;
二段式:用两个always模块来描述状态机,其中一个always模块采用同步时序描述状态转移;另一个模块采用组合逻辑判断状态转移条件,描述状态转移规律以及输出;
三段式:在两个always模块描述方法基础上,使用三个always模块,一个always模块采用同步时序描述状态转移,一个always采用组合逻辑判断状态转移条件,描述状态转移规律,另一个always模块描述状态输出(可以用组合电路输出,也可以时序电路输出)。
一般而言,推荐的FSM 描述方法是后两种。这是因为:FSM和其他设计一样,最好使用同步时序方式设计,以提高设计的稳定性,消除毛刺。状态机实现后,一般来说,状态转移部分是同步时序电路而状态的转移条件的判断是组合逻辑。
一段式:虽然一个always块就可以解决问题,但描述不清晰,不利于维护修改,并且不利用附加约束,不利于综合其和布局布线器对设计的优化;
二段式:第二种描述方法同第一种描述方法相比,将同步时序和组合逻辑分别放到不同的always模块中实现,这样做的好处不仅仅是便于阅读、理解、维护,更重要的是利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。在第二种方式的描述中,描述当前状态的输出用组合逻辑实现,组合逻辑很容易产生毛刺,而且不利于约束,不利于综合器和布局布线器实现高性能的设计。
三段式:
但是为什么要使用状态机而不使用一般时序电路呢?这是因为它具有一些一般时序电路无法比拟的优点.
好的状态机的标准很多,最重要的几个方面如下:
对于格雷码和独热码,到底应该怎么选择才能达到最优综合?查阅书籍及网络资料,总结起来就是:
binary和gray-code适用于触发器资源较少,组合电路资源丰富的情况(CPLD),对于FPGA,适用one-hot code。这样不但充分利用FPGA丰富的触发器资源,还因为只需比较一个bit,速度快,组合电路简单。
自动售货机
一段式:
- module auto_sell(
- input clk,
- input rst_n,
- input coin_one,
- input coin_half,
-
- output reg water,
- output reg coin_back
- );
-
- parameter ZERO = 3'b000;
- parameter HALF = 3'b001;
- parameter ONE = 3'b010;
- parameter ONE_HALF = 3'b011;
- parameter TWO = 3'b100;
-
- //一段式状态机
- reg [2:0] status;
-
- always@(posedge clk,negedge rst_n)begin
- if(!rst_n)
- begin
- status <= ZERO;
- water <= 0;
- coin_back <= 0;
- end
- else
- case(status)
- ZERO :
- begin
- water <= 0;
- coin_back <= 0;
- if(coin_half)
- status <= HALF;
- else if(coin_one)
- status <= ONE;
- else
- status <= status;
- end
- HALF :
- begin
- water <= 0;
- coin_back <= 0;
- if(coin_half)
- status <= ONE;
- else if(coin_one)
- status <= ONE_HALF;
- else
- status <= status;
- end
- ONE :
- begin
- water <= 0;
- coin_back <= 0;
- if(coin_half)
- status <= ONE_HALF;
- else if(coin_one)
- status <= TWO;
- else
- status <= status;
- end
- ONE_HALF :
- begin
- if(coin_half)
- begin
- status <= TWO;
- water <= 1'b0;
- coin_back <= 1'b0;
- end
- else if(coin_one)
- begin
- status <= ZERO;
- water <= 1'b1;
- coin_back <= 1'b0;
- end
- else
- begin
- status <= status;
- water <= 1'b0;
- coin_back <= 1'b0;
- end
- end
- TWO :
- begin
- if(coin_half)
- begin
- status <= ZERO;
- water <= 1'b1;
- coin_back <= 1'b0;
- end
- else if(coin_one)
- begin
- status <= ZERO;
- water <= 1'b1;
- coin_back <= 1'b1;
- end
- else
- begin
- status <= status;
- water <= 1'b0;
- coin_back <= 1'b0;
- end
- end
- default:
- begin
- status <= ZERO;
- water <= 1'b0;
- coin_back <= 1'b0;
- end
- endcase
- end
-
- endmodule

二段式写法1:
- module auto_sell(
- input clk,
- input rst_n,
- input coin_one,
- input coin_half,
-
- output reg water,
- output reg coin_back
- );
-
- parameter ZERO = 3'b000;
- parameter HALF = 3'b001;
- parameter ONE = 3'b010;
- parameter ONE_HALF = 3'b011;
- parameter TWO = 3'b100;
-
- //--------------------二段式 1 ok--------------------------
- //二段式状态机
- reg [2:0] c_status;
- reg [2:0] n_status;
-
- //状态转移
- always@(posedge clk,negedge rst_n)begin
- if(!rst_n)
- c_status <= ZERO;
- else
- c_status <= n_status;
- end
-
- //描述状态转移规律以及输出
- always@(posedge clk,negedge rst_n)begin
- if(!rst_n)
- begin
- n_status <= ZERO;
- water <= 1'b0;
- coin_back <= 1'b0;
- end
- else
- case(c_status)
- ZERO :
- begin
- water <= 1'b0;
- coin_back <= 1'b0;
- if(coin_half)
- n_status <= HALF;
- else if(coin_one)
- n_status <= ONE;
- else
- n_status <= ZERO;
- end
- HALF :
- begin
- water <= 1'b0;
- coin_back <= 1'b0;
- if(coin_half)
- n_status <= ONE;
- else if(coin_one)
- n_status <= ONE_HALF;
- else
- n_status <= HALF;
- end
- ONE :
- begin
- water <= 1'b0;
- coin_back <= 1'b0;
- if(coin_half)
- n_status <= ONE_HALF;
- else if(coin_one)
- n_status <= TWO;
- else
- n_status <= ONE;
- end
- ONE_HALF :
- begin
- water <= 1'b0;
- coin_back <= 1'b0;
- if(coin_half)
- n_status <= TWO;
- else if(coin_one)
- begin
- n_status <= ZERO;
- water <= 1'b1;
- coin_back <= 1'b0;
- end
- else
- n_status <= ONE_HALF;
- end
- TWO :
- begin
- water <= 1'b0;
- coin_back <= 1'b0;
- if(coin_half)
- begin
- n_status <= ZERO;
- water <= 1'b1;
- coin_back <= 1'b0;
- end
- else if(coin_one)
- begin
- n_status <= ZERO;
- water <= 1'b1;
- coin_back <= 1'b1;
- end
- else
- n_status <= TWO;
- end
- default:
- n_status <= ZERO;
- endcase
- end
-
-
- endmodule

二段式写法2:
- module auto_sell(
- input clk,
- input rst_n,
- input coin_one,
- input coin_half,
-
- output reg water,
- output reg coin_back
- );
-
- parameter ZERO = 3'b000;
- parameter HALF = 3'b001;
- parameter ONE = 3'b010;
- parameter ONE_HALF = 3'b011;
- parameter TWO = 3'b100;
-
- //---------------------二段式 2 ok--------------------------------------
-
- //二段式状态机
- reg [2:0] status;
-
- //状态转移
- always@(posedge clk,negedge rst_n)begin
- if(!rst_n)
- status <= ZERO;
- else
- begin
- case(status)
- ZERO :
- begin
- if(coin_half)
- status <= HALF;
- else if(coin_one)
- status <= ONE;
- else
- status <= ZERO;
- end
- HALF :
- begin
- if(coin_half)
- status <= ONE;
- else if(coin_one)
- status <= ONE_HALF;
- else
- status <= HALF;
- end
- ONE :
- begin
- if(coin_half)
- status <= ONE_HALF;
- else if(coin_one)
- status <= TWO;
- else
- status <= ONE;
- end
- ONE_HALF :
- begin
- if(coin_half)
- status <= TWO;
- else if(coin_one)
- begin
- status <= ZERO;
- end
- else
- status <= ONE_HALF;
- end
- TWO :
- begin
- if(coin_half)
- begin
- status <= ZERO;
- end
- else if(coin_one)
- begin
- status <= ZERO;
- end
- else
- status <= TWO;
- end
- default:
- status <= ZERO;
- endcase
- end
- end
- //输出 时序逻辑
- always@(posedge clk,negedge rst_n)begin
- if(!rst_n)
- begin
- water <= 1'b1;
- coin_back <= 1'b0;
- end
- else
- case(status)
- ONE_HALF:
- begin
- if(coin_one)
- begin
- water <= 1'b1;
- coin_back <= 1'b0;
- end
- else
- begin
- water <= 1'b0;
- coin_back <= 1'b0;
- end
- end
- TWO:
- begin
- if(coin_half)
- begin
- water <= 1'b1;
- coin_back <= 1'b0;
- end
- else if(coin_one)
- begin
- water <= 1'b1;
- coin_back <= 1'b1;
- end
- else
- begin
- water <= 1'b0;
- coin_back <= 1'b0;
- end
- end
- default:
- begin
- water <= 1'b0;
- coin_back <= 1'b0;
- end
- endcase
- end
-
- endmodule

三段式:
- module auto_sell(
- input clk,
- input rst_n,
- input coin_one,
- input coin_half,
-
- output reg water,
- output reg coin_back
- );
-
- parameter ZERO = 3'b000;
- parameter HALF = 3'b001;
- parameter ONE = 3'b010;
- parameter ONE_HALF = 3'b011;
- parameter TWO = 3'b100;
-
- //三段式状态机
- reg [2:0] c_status;
- reg [2:0] n_status;
-
- //状态转移
- always@(posedge clk,negedge rst_n)begin
- if(!rst_n)
- c_status <= ZERO;
- else
- c_status <= n_status;
- end
-
- //状态转移规律及状态输出,组合逻辑输出只与输入有关
- //如果有n_status = n_status,电路会出错;
- always@(*)begin
- case(c_status)
- ZERO :
- begin
- if(coin_half)
- n_status = HALF;
- else if(coin_one)
- n_status = ONE;
- else
- n_status = ZERO;
- end
- HALF :
- begin
- if(coin_half)
- n_status = ONE;
- else if(coin_one)
- n_status = ONE_HALF;
- else
- n_status = HALF;
- end
- ONE :
- begin
- if(coin_half)
- n_status = ONE_HALF;
- else if(coin_one)
- n_status = TWO;
- else
- n_status = ONE;
- end
- ONE_HALF :
- begin
- if(coin_half)
- n_status = TWO;
- else if(coin_one)
- n_status = ZERO;
- else
- n_status = ONE_HALF;
- end
- TWO :
- begin
- if(coin_half)
- n_status = ZERO;
- else if(coin_one)
- n_status = ZERO;
- else
- n_status = TWO;
- end
- default:
- n_status = ZERO;
- endcase
- end
- always@(posedge clk,negedge rst_n)begin
- if(!rst_n)
- begin
- water = 1'b1;
- coin_back = 1'b0;
- end
- else
- case(c_status)
- ONE_HALF:
- begin
- if(coin_one)
- begin
- water = 1'b1;
- coin_back = 1'b0;
- end
- else
- begin
- water = 1'b0;
- coin_back = 1'b0;
- end
- end
- TWO:
- begin
- if(coin_half)
- begin
- water = 1'b1;
- coin_back = 1'b0;
- end
- else if(coin_one)
- begin
- water = 1'b1;
- coin_back = 1'b1;
- end
- else
- begin
- water = 1'b0;
- coin_back = 1'b0;
- end
- end
- default:
- begin
- water = 1'b0;
- coin_back = 1'b0;
- end
- endcase
- end
-
- endmodule
-

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。