博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
FPGA 状态机设计
阅读量:7028 次
发布时间:2019-06-28

本文共 9256 字,大约阅读时间需要 30 分钟。

数字系统有两大类有限状态机(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

转载地址:http://dnrxl.baihongyu.com/

你可能感兴趣的文章
虚拟机Visualbox安装Ubuntu Server
查看>>
用带余除法可以解决一切部分分式的题目
查看>>
vs 生成事件
查看>>
jmeter 实战项目总结2——微信端
查看>>
php.ini 中文版
查看>>
即时通信客户端流程,
查看>>
布隆过滤器redis缓存
查看>>
01-数据仓库之数据建模
查看>>
Nginx 安装
查看>>
hidesBottomBarWhenPushed 设置为NO的问题
查看>>
cisco常用命令详解
查看>>
谁在追踪谁?
查看>>
HTTP请求返回状态码详解
查看>>
句柄类
查看>>
GitLab
查看>>
【常用配置】Spring框架web.xml通用配置
查看>>
[leetcode 240]Search a 2D Matrix II
查看>>
域名指的是这一级目录
查看>>
[Angular] Creating an Observable Store with Rx
查看>>
[转]Porting to Oracle with Entity Framework NLog
查看>>