打印

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

[复制链接]
1548|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
xiao6666|  楼主 | 2012-10-9 21:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用一段式建模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

相关帖子

沙发
seaboy6| | 2012-10-29 14:35 | 只看该作者
第二段是组合逻辑,最好用阻塞赋值吧

使用特权

评论回复
板凳
wrigleymint| | 2012-11-27 17:14 | 只看该作者
:)

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

48

主题

453

帖子

1

粉丝