• FPGA 状态机设计 分类: 硬件开发_FPGA 2014-11-17 11:50 522人阅读 评论(0) 收藏


    数字系统有两大类有限状态机(Finite State Machine,FSM):Moore状态机和Mealy状态机。

    Moore状态机

      其最大特点是输出只由当前状态确定,与输入无关。Moore状态机的状态图中的每一个状态都包含一个输出信号。这是一个典型的Moore状态机的状态跳转图,x、y、z是输入,a、b、c是输出。

        

    Mealy状态机

      它的输出不仅与当前状态有关系,而且与它的输入也有关系,因而在状态图中每条转移边需要包含输入和输出的信息。

     

    状态编码

      数字逻辑系统状态机设计中常见的编码方式有:二进制码(Binary码)、格雷码(Gray码)、独热码(One-hot码)以及二一十进制码(BCD码)。

      格雷码的特点:相邻的两个码组之间仅有一位不同。

    普通二进制码与格雷码之间可以相互转换。

      二进制码转换为格雷码:从最右边一位起,一次与左边一位“异或”,作为对应格雷码该位的值,最左边的一位不变(相当于最左边是0)。

      格雷码转换为二进制码:从左边第二位起,将每一位与左边一位解码后的值“异或”,作为该解码后的值(最左边的一位依然不变)。

      独热码又分为独热1码和独热0码,是一种特殊的二进制编码方式。当任何一种状态有且仅有一个1时,就是独热1码,相反任何一种状态有且仅有一个0时,就是独热0码。

    状态机的描述

      状态机有三种描述方式:一段式状态机、两段式状态机、三段式状态机。下面就用一个小例子来看看三种方式是如何实现的。

      (各种图片,各种坑爹啊 - -!)

     

    一段式状态机

      当把整个状态机卸载一个always模块中,并且这个模块既包含状态转移,又含有组合逻辑输入/输出时,称为一段式状态机。不推荐采用这种状态机,因为从代码风格方面来讲,一般都会要求把组合逻辑和时序逻辑分开;从代码维护和升级来说,组合逻辑和书序逻辑混合在一起不利于代码维护和修改,也不利于约束。

         

    复制代码
     1 //一段式状态机来实现:在异步复位信号的控制下,一段式状态机进入IDLE
    2 //状态,q_sig4被复位,一旦sig1或者sig2有效,状态机进入WAIT状态,如果
    3 //sig1和sig2同时有效,那么状态机进入DONE状态,
    4 //如果sig4还有效,那么q_sig4置位,同时状态机进入IDLE状态。
    5
    6 module one_seg_fsm(clk,reset,sig1,sig2,sig3,q_sig4,q_sm_state);
    7 //数据声明部分
    8 input clk,reset,sig1,sig2,sig3;
    9
    10 output reg q_sig4;
    11 output reg [1:0] q_sm_state;
    12
    13 //参数声明
    14 parameter IDLE = 2'b00;
    15 parameter WAIT = 2'b01;
    16 parameter DONE = 2'b10;
    17
    18 //状态跳转逻辑程序设计
    19 always @(posedge clk or posedge reset)
    20 begin
    21 if(reset)
    22 begin
    23 q_sig4 <= 0;
    24 q_sm_state <= IDLE;
    25 end
    26 else
    27 begin
    28 case(q_sm_state)
    29 IDLE: begin
    30 if(sig1 || sig2)
    31 begin
    32 q_sm_state <= WAIT;
    33 q_sig4 <= 1'b0;
    34 end
    35 else
    36 begin
    37 q_sm_state <= IDLE;
    38 q_sig4 <= 1'b0;
    39 end
    40 end
    41 WAIT: begin
    42 if(sig2 && sig3)
    43 begin
    44 q_sm_state <= DONE;
    45 q_sig4 <= 1'b0;
    46 end
    47 else
    48 begin
    49 q_sm_state <= WAIT;
    50 q_sig4 <= 1'b0;
    51 end
    52 end
    53
    54 DONE:begin
    55 if(sig3)
    56 begin
    57 q_sm_state <= IDLE;
    58 q_sig4 <= 1'b1;
    59 end
    60 else
    61 begin
    62 q_sm_state <= DONE;
    63 q_sig4 <= 1'b0;
    64 end
    65 end
    66
    67 default: begin
    68 q_sm_state <= IDLE;
    69 q_sig4 <= 0;
    70 end
    71 endcase
    72 end
    73 end
    74 endmodule
    复制代码

       

    两段式状态机

      所谓的两段式状态机就是采用一个always语句来实现时序逻辑,另外一个always语句来实现组合逻辑,提高了代码的可读性,易于维护。不同于一段式状态机的是,它需要定义两个状态----现态和次态,然后通过现态和次态的转换来实现时序逻辑。

       

    复制代码
     1 //本例主要采用两段式状态机:在异步复位信号的控制下,一段式状态机进入IDLE
    2 //状态,q_sig4被复位,一旦sig1或者sig2有效,状态机进入WAIT状态,如果sig1和sig2同时有效,那么
    3 //状态机进入DONE状态,如果sig4还有效,那么q_sig4置位,同时状态机进入IDLE状态。
    4
    5 module two_seg_fsm(clk,reset,sig1,sig2,sig3,q_sig4);
    6 //数据声明部分
    7 input clk,reset,sig1,sig2,sig3;
    8
    9 output reg q_sig4;
    10
    11 reg [1:0] current_state, next_state;
    12
    13 //参数声明
    14 parameter IDLE = 2'b00;
    15 parameter WAIT = 2'b01;
    16 parameter DONE = 2'b10;
    17
    18 //状态跳转程序设计
    19 always @(posedge clk or posedge reset)
    20 if(reset)
    21 current_state <= IDLE;
    22 else
    23 current_state <= next_state;
    24
    25 //状态逻辑输出
    26 always @(current_state or sig1 or sig2 or sig3)
    27 begin
    28 case(current_state)
    29 IDLE: begin
    30 if(sig1 || sig2)
    31 begin
    32 next_state = WAIT;
    33 q_sig4 = 1'b0;
    34 end
    35 else
    36 begin
    37 next_state = IDLE;
    38 q_sig4 = 1'b0;
    39 end
    40 end
    41 WAIT: begin
    42 if(sig2 && sig3)
    43 begin
    44 next_state = DONE;
    45 q_sig4 = 1'b0;
    46 end
    47 else
    48 begin
    49 next_state = WAIT;
    50 q_sig4 = 1'b0;
    51 end
    52 end
    53
    54 DONE:begin
    55 if(sig3)
    56 begin
    57 next_state = IDLE;
    58 q_sig4 = 1'b1;
    59 end
    60 else
    61 begin
    62 next_state = DONE;
    63 q_sig4 = 1'b0;
    64 end
    65 end
    66
    67 default: begin
    68 next_state = IDLE;
    69 q_sig4 = 0;
    70 end
    71 endcase
    72
    73 end
    74 endmodule
    复制代码

         

    三段式状态机

      三段式状态机与两段式状态机的区别:两段式直接采用组合逻辑输出,而三段式则通过在组合逻辑后再增加一级寄存器来实现时序逻辑输出。这样做的好处是可以有效地滤去租个逻辑输出的毛刺,同时可以有效地进行时序计算与约束,另外对于总线形式的输出信号来说,容易使总线数据对其,从而减小总线数据间的偏移,减小接收端数据采样出错的频率。

      三段式状态机的基本格式是:第一个always语句实现同步状态跳转;第二个always语句实现组合逻辑;第三个always语句实现同步输出。

        

    复制代码
     1 //本例主要采用三段式状态机:在异步复位信号的控制下,一段式状态机进入IDLE
    2 //状态,q_sig4被复位,一旦sig1或者sig2有效,状态机进入WAIT状态,如果sig1和sig2同时有效,那么
    3 //状态机进入DONE状态,如果sig4还有效,那么q_sig4置位,同时状态机进入IDLE状态。
    4
    5 module three_seg_fsm(clk,reset,sig1,sig2,sig3,q_sig4);
    6 //数据声明部分
    7 input clk,reset,sig1,sig2,sig3;
    8
    9 output reg q_sig4;
    10
    11 reg [1:0] current_state, next_state;
    12
    13 //参数声明
    14 parameter IDLE = 2'b00;
    15 parameter WAIT = 2'b01;
    16 parameter DONE = 2'b10;
    17
    18 //状态跳转程序设计
    19 always @(posedge clk or posedge reset)
    20 if(reset)
    21 current_state <= IDLE;
    22 else
    23 current_state <= next_state;
    24
    25 //状态跳转输出
    26 always @(current_state or sig1 or sig2 or sig3)
    27 begin
    28 case(current_state)
    29 IDLE: begin
    30 if(sig1 || sig2)
    31 begin
    32 next_state = WAIT;
    33 end
    34 else
    35 begin
    36 next_state = IDLE;
    37 end
    38 end
    39 WAIT: begin
    40 if(sig2 && sig3)
    41 begin
    42 next_state = DONE;
    43 end
    44 else
    45 begin
    46 next_state = WAIT;
    47 end
    48 end
    49
    50 DONE:begin
    51 if(sig3)
    52 begin
    53 next_state = IDLE;
    54 end
    55 else
    56 begin
    57 next_state = DONE;
    58 end
    59 end
    60
    61 default: begin
    62 next_state = IDLE;
    63 end
    64 endcase
    65 end
    66
    67 //逻辑输出
    68 always @(posedge clk or posedge reset)
    69 if(reset)
    70 q_sig4 <= 1'b0;
    71 else
    72 begin
    73 case(next_state)
    74 IDLE,
    75 WAIT: q_sig4 <= 1'b0;
    76 DONE: q_sig4 <= 1'b1;
    77 default: q_sig4 <= 1'b0;
    78 endcase
    79 end
    80
    81 endmodule

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    位运算与变量多状态表达
    判断点是否在多边形内
    向量旋转
    小怪受击身体变红特效代码
    字典 Key值转换为数组
    Android中的Selector的使用总结
    Android 常见的工具类
    成为Android高手必须掌握的8项基本要求
    K-means算法
    Android 5.0以上获取系统运行进程信息
  • 原文地址:https://www.cnblogs.com/mao0504/p/4706483.html
Copyright © 2020-2023  润新知