zoukankan      html  css  js  c++  java
  • FPGA 状态机(FSM)的三段式推荐写法

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

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

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

      1 `timescale 1ns / 1ps
      2 
      3 /////////////////////////////////////////////////////////////////
      4 
      5 // Company: csic
      6 
      7 // Engineer: shengyi
      8 
      9 // Create Date:    15:24:44 09/16/2010
     10 
     11 // Design Name:   seqcheck_fsm3 
     12 
     13 // Module Name:    seqcheck_101
     14 
     15 // Project Name:   seqcheck_fsm3
     16 
     17 // Target Devices: V5 220t
     18 
     19 // Tool versions: ise 10.1
     20 
     21 // Description: 借'101'序列检测器程序说明FSM的三段式写法
     22 
     23 // Dependencies:
     24 
     25 // Revision:
     26 
     27 // Revision 0.01 - File Created
     28 
     29 // Additional Comments:
     30 
     31 /////////////////////////////////////////////////////////////////
     32 
     33 //3-paragraph method to describe FSM
     34 
     35 //Describe sequential state transition in the 1st sequential always block
     36 
     37 //State transition conditions in the 2nd combinational always block
     38 
     39 //Describe the FSM out in the 3rd sequential always block
     40 
     41 module seqcheck_101(
     42 
     43     clk,
     44 
     45      rst,
     46 
     47      din,
     48 
     49      dout
     50 
     51     );
     52 
     53      parameter IDLE=4'b0001,S1=4'b0010,S2=4'b0100,S3=4'b1000;
     54 
     55      input clk;
     56 
     57      input rst;
     58 
     59      input din;
     60 
     61      output dout;
     62 
     63      reg dout;
     64 
     65      reg [3:0] current_state,next_state;
     66 
     67     
     68 
     69      //第一部分说明初始状态,和current_state<=next_state
     70 
     71      //每一个时钟沿产生一次可能的状态变化
     72 
     73      always @(posedge clk)
     74 
     75      begin
     76 
     77        if(rst)
     78 
     79           current_state<=IDLE;
     80 
     81         else
     82 
     83           current_state<=next_state;
     84 
     85      end
     86 
     87  
     88 
     89 //第二部分,状态转移,产生下一状态的整合逻辑
     90 
     91      always @(din or current_state)
     92 
     93      begin
     94 
     95        next_state<=4'bx;
     96 
     97        case(current_state)
     98 
     99           IDLE:
    100 
    101             begin
    102 
    103                if(din==1'b1)
    104 
    105                   next_state<=S1;
    106 
    107                 else
    108 
    109                   next_state<=IDLE;
    110 
    111              end
    112 
    113           S1:
    114 
    115             begin
    116 
    117                if(din==1'b1)
    118 
    119                   next_state<=S1;
    120 
    121                 else
    122 
    123                   next_state<=S2;
    124 
    125              end
    126 
    127           S2:
    128 
    129             begin
    130 
    131                if(din==1'b1)
    132 
    133                   next_state<=S3;
    134 
    135                 else
    136 
    137                   next_state<=IDLE;
    138 
    139              end
    140 
    141           S3:
    142 
    143             begin
    144 
    145                if(din==1'b1)
    146 
    147                   next_state<=S1;
    148 
    149                 else
    150 
    151                   next_state<=S2;
    152 
    153              end
    154 
    155           default:
    156 
    157             next_state<=4'bx;
    158 
    159         endcase
    160 
    161      end
    162 
    163     
    164 
    165      //第三段,产生输出
    166 
    167      always @(posedge clk)
    168 
    169      begin
    170 
    171        if(rst)
    172 
    173           dout<=1'b0;
    174 
    175         else
    176 
    177         begin
    178 
    179             case(next_state)
    180 
    181                IDLE:dout<=1'b0;
    182 
    183                 S1:dout<=1'b0;
    184 
    185                 S2:dout<=1'b0;
    186 
    187                 S3:dout<=1'b1;
    188 
    189                 default:dout<=1'bx;
    190 
    191              endcase
    192 
    193         end        
    194 
    195 end
    196 
    197     endmodule
  • 相关阅读:
    shell之ping减少时间间隔&ping的次数&用IP1去ping IP2的技巧
    kali界面乱码解决方案记录
    win10子系统kali-linux安装图形化界面总结
    树莓派4 64bit 编译安装QT5.13.2 和 Redis Desktop Manager 2020.1-dev
    树莓派4 (8GB) RaspiOS 64 bit 入手配置流程 2020-06-10
    阿里巴巴Java开发手册(泰山版)个人阅读精简
    Java 8 新API Steam 流 学习笔记
    IDEA中maven项目部署到云服务器上(简易)
    收藏模块的设计
    js常用代码片段(更新中)
  • 原文地址:https://www.cnblogs.com/sky1991/p/2583612.html
Copyright © 2011-2022 走看看