什么是状态机:状态机通过不同的状态迁移来完成特定的逻辑操作
状态机的分类:Moore型状态机和Mealy型状态机
Moore型:状态机的变化只与当前的状态有关
Mealy型:状态机的变化不仅与当前的状态有关,还与输入有关
如何创建状态机:状态机的创建可以分为一段式,两段式和三段式:
一段式:所有的状态变化以及导致的输出变化都写在了一个always快中。在该模块中既描述状态转移,又描述状态的输入和输出。
两段式:用两个always模块来描述状态机。其中一个模块采用同步时序逻辑电路描述状态转移,另一个模块采用组合逻辑判断状态转移条件。它需要两个状态——现态和次态,然后通过现态和次态的转换来实现时序逻辑。
三段式:用三个always模块来描述状态机。其中一个模块采用同步时序逻辑电路描述状态转移,另一个模块采用组合逻辑判断状态转移条件(注意和两段式的区别)。第三个模块描述状态的输出(既可以用组合逻辑也可以用时序逻辑)
一般来说,状态机实现后,状态转移部分是同步时序电路,而状态转移条件的判断是组合逻辑。
两段式状态机设计中描述当前状态的输出用的是组合逻辑实现的,但组合逻辑容易出现毛刺而且不利于约束。
三段式状态机在设计时,组合逻辑判断状态转移条件时与两段式不同点在于:三段式状态机在上一状态中根据输入条件判断当前状态的输出,从而在不插入额外时钟节拍的前提下,实现寄存器的输出。
还有一种两段式状态机是这样的:状态转移和状态转移条件判断放在一个模块中,而输出用的是时序同步输出。类似例子为UART的状态机。
灵活选择状态机,不一定要拘泥理论,怎样方面怎样来
三段式状态机模板:
module three_fsm(clk,rst_n,a,z); input clk; input rst_n; input a; output reg z; reg [5:0] current_state; reg [5:0] next_state; parameter S0 = 6'b00_0001; parameter S1 = 6'b00_0010; parameter S2 = 6'b00_0100; parameter S3 = 6'b00_1000; parameter S4 = 6'b01_0000; parameter S5 = 6'b10_0000; //第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器 //相当于是一个D触发器 always@(posedge clk or negedge rst_n) begin if(!rst_n) current_state <= S0; else current_state <= next_state; end //第二个进程,组合逻辑always模块,描述状态转移条件判断 always@(*) begin case(current_state) S0: next_state = (a==1)?S1:S0; S1: next_state = (a==0)?S2:S1; S2: next_state = (a==0)?S3:S1; S3: next_state = (a==1)?S4:S0; S4: next_state = (a==0)?S5:S1; S5: next_state = (a==0)?S3:S1; default: next_state = S0; endcase end //第三个进程,同步时序always模块,格式化描述次态寄存器输出 always@(posedge clk or negedge rst_n) begin if(!rst_n) z = 0; else case(next_state) S0: z = 0; S1: z = 0; S2: z = 0; S3: z = 0; S4: z = 0; S5: z = 1; default: z = 0; endcase end endmodule |