状态机的基本概念
1) 摩尔型 和 米莉型状态机都是有限状态机( FSM );
2) 摩尔型状态机:时序电路的输出只取决于当前状态;
3) 米莉型状态机:时序电路的输出不但取决于状态还取决于输入;
4) 对于FPGA设计实现的有限状态机,建议使用独热码,因为虽然独热编码多用了连个触发器,但是所使用的的组合电路省一些,但是所使用的组合电路可省一些,因而使得电路速度和可靠性显著高,而总的单元数并无显著增加。采用独热编码后有了很多多余的状态,因此在case语句的最后一定要添加default分支项。可以使用默认项表示该项,也可以使用确定项表示该项,确保回到Idle状态。一般综合器都可以通过综合指令的控制合理地处理默认项。
5) 一般使用同步置位与复位状态机,always块的执行只由时钟跳边沿触发,是否置位 或者 复位,应该在always块中首先检查set 和 reset 信号的电平。所以set和reset饿电平维持时间必须大于时钟沿的间隔时间,否则set和reset不能每次都能有效的完成置位和复位的工作。
一段式状态机
整个电路用一个always块(即一段)描述,包含状态转移条件判断、状态输出和状态寄存器转移,如下图。
特点:
一段式建模必须考虑现在何种状态转移条件下会进入哪些次态,然后在每个现态的case分支下分别描述每个次态的输出。
缺点:
1)不利于修改和维护代码;
2)不符合时序逻辑与组合逻辑分开描述的代码描述风格;
3)不利于附加约束;
4)不利于综合器 和 布局布线器对设计的优化;
5)代码冗长。
两段式状态机
第一个进程(同步时序always模块),格式化描述次态到现态的转移;第二个进程(纯组合逻辑always模块),一般情况下是组合逻辑输出,如果时序允许,尽量寄存器输出。
缺点: 使用两段式,其输出一般使用组合逻辑描述,而组合逻辑易产生毛刺等不稳定因素。
三段式状态机
特点:
只需要指定case敏感列表次态寄存器,然后在每个次态case分支中描述该状态的输出即可(根本不用考虑状态转移条件)。
三段式优点:
1)FSM做到了同步寄存器输出;
2)消除了组合逻辑输出的不稳定与毛刺的隐患;
3)更利于时序路径分组;
4)在FPGA/CPLD等可编程逻辑器件上的综合与布局布线效果更佳。
代码设计举例
针对上述状态转移图,设计状态机代码如下。
一段式状态机设计。
`timescale 1ns / 1ps
module module_name(
// Defines the input signal
// Defines the output signal as reg --To reduce the probability of Matastable State
input sys_clk,
input areset,
input in,
output reg out
);
parameter A = 1'b0;
parameter B = 1'b1;
// Define intermediate signal as reg --To reduce the probability of Matastable State
reg state;
always @(posedge clk or posedge areset) begin
if (areset) begin
state <= B;
out <= 1'b1;
end
else begin
case( state )
B:begin
if( in == 1'b1 ) begin
state <= B;
out <= 1'b1;
end
else begin
state <= A;
out <= 1'b0;
end
end
A:begin
if( in <= 1'b1 ) begin
state <= A;
out <= 1'b0;
end
end
default:begin
state <= B;
out <= 1'b1;
end
endcase
end
end
endmodule
二段式状态机设计
`timescale 1ns / 1ps
module module_name(
// Defines the input signal
// Defines the output signal as reg --To reduce the probability of Matastable State
input sys_clk,
input areset,
input in,
output reg out
);
parameter A = 1'b0;
parameter B = 1'b1;
// Define intermediate signal as reg --To reduce the probability of Matastable State
// reg state;
reg current_state;
reg next_state;
always @(posedge clk or posedge areset) begin
if (areset) begin
current_state <= B;
end
else begin
current_state <= next_state;
end
end
always @ (*) begin
case( current_state )
B:begin
if( in == 1'b1 ) begin
next_state = B;
end
else begin
next_state = A;
end
out = 1'b1;
end
A:begin
out = 1'b0;
if( in == 1'b1 ) begin
next_state = A;
end
else begin
next_state = B;
end
out = 1'b0;
end
endcase
end
endmodule
三段式状态机
`timescale 1ns / 1ps
module module_name(
// Defines the input signal
// Defines the output signal as reg --To reduce the probability of Matastable State
input sys_clk,
input areset,
input in,
output reg out
);
parameter A = 1'b0;
parameter B = 1'b1;
// Define intermediate signal as reg --To reduce the probability of Matastable State
// reg state;
reg current_state;
reg next_state;
always @(posedge sys_clk or posedge areset) begin
if (areset) begin
current_state <= B;
end
else begin
current_state <= next_state;
end
end
always @ (*) begin
case( current_state )
B:begin
if( in == 1'b1 ) begin
next_state = B;
end
else begin
next_state = A;
end
// out = 1'b1;
end
A:begin
out = 1'b0;
if( in == 1'b1 ) begin
next_state = A;
end
else begin
next_state = B;
end
// out = 1'b0;
end
endcase
end
always @( posedge sys_clk or negedge areset )
begin
if ( areset ) begin
out <= 1'b1;
end
else if( next_state == B ) begin
out <= 1'b1;
end
else begin
out <= 1'b0;
end
end
endmodule