有限状态机(FSM)在FPGA设计中的重要性不必多说。它作为数字系统中的控制单元,接受外部信号及数据单元产生的状态信息,产生控制信号序列。
有限状态机分为两种:Moore型与Mealy型。Moore状态机时序逻辑电路的输出只取决于当前状态,即输出=f(当前状态),Mealy状态机时序逻辑电路的输出不仅取决于当前状态,还取决于输入信号,即输出=f(当前状态,输入)。
两个状态机也是有共性的,它们的下一个状态均与当前状态+输入有关,即下一状态=f(当前状态,输入)。
(1)一段式状态机即采用一个always模块进行状态机的设计。将状态的同步转移,状态的输出以及状态的输入写入一个always模块中。
缺点:不符合设计中要将时序逻辑和组合逻辑分开的设计风格,而且在描述当前状态时就需要考虑下一状态的输出,不利于后期维护以及附加约束。
(2)二段式状态机采用两个进程进行状态机的设计。一个always模块采用同步时序描述状态之间的转移;另一个always模块采用组合逻辑判断输入条件,描述状态转移规律,并进行状态输出。
缺点:在电路的输出端因为没有寄存器对输出进行寄存,所以比较容易产生毛刺等不稳定因素,影响状态的最终输出。
(3)三段式状态机在两段式的基础上,将组合逻辑中的输出取出专门放入一个同步时序always模块进行状态输出描述,对每个输出使用寄存器进行寄存,这样设计后既保证了时序逻辑和组合逻辑的分开,使程序结构清晰,又保证了状态机的输出不会产生毛刺。
//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器
`timescale 1ns / 1ps
/
// Company:
// Engineer:
// Create Date: 09/16/2018
// Design Name: seqcheck_fsm3
// Module Name: seqcheck_101
// Project Name: seqcheck_fsm3
// Target Devices: V5 220t
// Tool versions: ise 10.1
// Description: FSM model
// Dependencies:
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
/
//3-paragraph method to describe FSM
//Describe sequential state transition in the 1st sequential always block
//State transition conditions in the 2nd combinational always block
//Describe the FSM out in the 3rd sequential always block
module seqcheck_101 #(
parameter IDLE=4'b0001,
parameter S1=4'b0010,
parameter S2=4'b0100,
parameter S3=4'b1000
)
(
input clk,
input rst,
input din,
output reg dout
);
reg [3:0] current_state,next_state;
//第一部分说明初始状态,和current_state<=next_state
//每一个时钟沿产生一次可能的状态变化
always @(posedge clk)
begin
if(rst)
current_state<=IDLE;
else
current_state<=next_state;
end
//第二部分,状态转移,产生下一状态的整合逻辑
always @(din or current_state)
begin
next_state<=4'bx; //记得要初始化
case(current_state)
IDLE:
begin
if(din==1'b1)
next_state<=S1;
else
next_state<=IDLE;
end
S1:
begin
if(din==1'b1)
next_state<=S1;
else
next_state<=S2;
end
S2:
begin
if(din==1'b1)
next_state<=S3;
else
next_state<=IDLE;
end
S3:
begin
if(din==1'b1)
next_state<=S1;
else
next_state<=S2;
end
default:
next_state<=4'bx;
endcase
end
//第三段,产生输出
always @(posedge clk)
begin
if(rst)
dout<=1'b0;
else
begin
case(next_state)
IDLE:dout<=1'b0;
S1:dout<=1'b0;
S2:dout<=1'b0;
S3:dout<=1'b1;
default:dout<=1'bx;
endcase
end
end
endmodule
下一篇探讨下状态机的设计要点