首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

FPGA状态机

FPGA状态机

什么是状态机:状态机通过不同的状态迁移来完成特定的逻辑操作
状态机的分类: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
返回列表