我是靠谱客的博主 平常狗,最近开发中收集的这篇文章主要介绍状态机,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.状态机分为2类,米里型和摩尔型

组成要素有:输入(包括复位),状态(包括当前状态的操作),状态转移条件,状态输出条件

设计FSM总结起来为2大类。

用状态机去实现时序逻辑

(1)将状态转移和状态的操作和判断等写到一个模块中:如

parameter IDLE= 4'd0;   
parameter START1 = 4'd1;
parameter ADD1 = 4'd2;   
parameter ACK1 = 4'd3;    
parameter ADD2 = 4'd4;    
reg[3:0] cstate; //状态寄存器
always @ (posedge clk or negedge rst_n) 
begin
  if(!rst_n) 
      begin
          cstate <= IDLE;
      end
   else  
      case (cstate)
         IDLE: 
    begin
                cstate <= START1;
             end 
        START1: 
    begin
                cstate <= ADD1;
             end 
       default: cstate <= IDLE;
       endcase
end 

(2)将状态转移单独写一个模块,将状态的操作和判断等写在另一个模块中。如:

parameter IDLE= 4'd0,
          WRT0 = 4'd1,
          WRT1 = 4'd2,
          REA0 = 4'd3,
         REA1 = 4'd4;


reg[3:0] cstate,nstate;


always @ (posedge clk or negedge rst_n)
      if(!rst_n) 
      cstate <= IDLE;
       else 
      cstate <= nstate;
  
always @ (cstate or sram_wr_req or sram_rd_req or cnt)//always 后面是一些可以引起状态变化的量
    case (cstate)
         IDLE: 
   if(sram_wr_req) 
      nstate <= WRT0;//进入写状态
            else if(sram_rd_req) 
  nstate <= REA0;//进入读状态
            else nstate <= IDLE;
         WRT0: 
   if(`DELAY_80NS) 
    nstate <= WRT1;
            else 
    nstate <= WRT0;//延时等待160ns
         WRT1: 
       nstate <= IDLE;//写结束,返回
         REA0: 
  if(`DELAY_80NS) 
       nstate <= REA1;
           else
        nstate <= REA0;//延时等待160ns
        REA1: 
   nstate <= IDLE;//读结束,返回
        default: nstate <= IDLE;
   endcase
           2个always 块一个为时序模块,一个为组合逻辑。

       

Binary、gray-code 编码使用最少的触发器,较多的组合逻辑。而 one-hot 编码反之。由于 CPLD 更多的提供组合逻辑资源,而 FPGA 更多的提供触发器资源,所以 CPLD 多使用gray-code,而 FPGA 多使用one-hot 编码。另一方面,对于小型设计使用gray-code 和binary 编码更有效,而大型状态机使用one-hot更高效。

推荐在 24个状态以上会用格雷码,在 5~24个状态会用独热码,在 4 个状态以内用二进制码,肯定独热码比二进制码在实现 FSM部分会占更多资源,但是译码输出控制简单,所以如果状态不是太多,独热码较好。状态太少译码不会太复杂,二进制就可以了。状态太多,前面独热码所占资源太多,综合考虑就用格雷码了

2.编码风格: 

(1)避免生成锁存器

一个完备的状态机应该具有初始化(reset)状态和默认(default)状态

当芯片加电或者复位后,状态机应该能够自动将所有判断条件复位,并进入初始化状态。 状态机也应该有一个默认(default )状态,当转移条件不满足,或者状态发生了突变时,要能保证逻辑不会陷入“死循环”。

检查所有的状态是“并行的”(parallel),也就是说在同一时间只有一个状态能够成立。

(2)参数定义用 parameter

状态的定义用paramet er 定义,不推荐使用`defin e 宏定义的方式,因为‘defi ne 宏定义在编译时自动替换整个设计中所定义的宏,而par am et e r 仅仅定义模块内部的参数,定义的参数不会与模块外的其他状态机混淆。

(3)一定要使用“<=”非阻塞赋值方式

采用非阻塞赋值方式消除很多竞争冒险的隐患。 

最后

以上就是平常狗为你收集整理的状态机的全部内容,希望文章能够帮你解决状态机所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(79)

评论列表共有 0 条评论

立即
投稿
返回
顶部