FPGA 状态机(FSM)的三段式推荐写法

用一段式建模FSM 的寄存器输出的时候,必须要综合考虑现态在何种状态转移条件下会进入哪些次态,然后在每个现态的case 分支下分别描述每个次态的输出,这显然不符合思维习惯;而三段式建模描述FSM 的状态机输出时,只需指定case 敏感表为次态寄存器,然后直接在每个次态的case 分支中描述该状态的输出即可,根本不用考虑状态转移条件。本例的FSM 很简单,如果设计的FSM 相对复杂,三段式的描述优势就会凸显出来。

另一方面,三段式描述方法与两段式描述相比,虽然代码结构复杂了一些,但是换来的优势是使FSM 做到了同步寄存器输出,消除了组合逻辑输出的不稳定与毛刺的隐患,而且更利于时序路径分组,一般来说在FPGA/CPLD 等可编程逻辑器件上的综合与布局布线效果更佳。

下面以‘101’序列检测器的FSM来说明三段式FSM的写法:

`timescale 1ns / 1ps

/

// Company: csic

// Engineer: shengyi

// Create Date:    15:24:44 09/16/2010

// Design Name:   seqcheck_fsm3 

// Module Name:    seqcheck_101

// Project Name:   seqcheck_fsm3

// Target Devices: V5 220t

// Tool versions: ise 10.1

// Description: 借'101'序列检测器程序说明FSM的三段式写法

// 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(

    clk,

     rst,

     din,

     dout

    );

     parameter IDLE=4'b0001,S1=4'b0010,S2=4'b0100,S3=4'b1000;

     input clk;

     input rst;

     input din;

     output dout;

     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

 

转载于:https://www.cnblogs.com/shengyi/archive/2010/09/16/1828491.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值