FPGA Verilog HDL 设计-----有限状态机

数字系统有两大类有限状态机(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模块中,并且这个模块既包含状态转移,又含有组合逻辑输入/输出时,称为一段式状态机。不推荐采用这种状态机,因为从代码风格方面来讲,一般都会要求把组合逻辑和时序逻辑分开;从代码维护和升级来说,组合逻辑和书序逻辑混合在一起不利于代码维护和修改,也不利于约束。

//一段式状态机来实现:在异步复位信号的控制下,一段式状态机进入IDLE
 //状态,q_sig4被复位,一旦sig1或者sig2有效,状态机进入WAIT状态,如果
 //sig1和sig2同时有效,那么状态机进入DONE状态,
 //如果sig4还有效,那么q_sig4置位,同时状态机进入IDLE状态。
 
 module one_seg_fsm(clk,reset,sig1,sig2,sig3,q_sig4,q_sm_state);
 //数据声明部分
 input clk,reset,sig1,sig2,sig3;
 
 output reg       q_sig4;
 output reg [1:0] q_sm_state;
 
 //参数声明
 parameter  IDLE       = 2'b00;
 parameter  WAIT       = 2'b01;
 parameter  DONE       = 2'b10;
 
 //状态跳转逻辑程序设计
 always @(posedge clk or posedge reset)
   begin
       if(reset)
       begin
           q_sig4     <= 0;
           q_sm_state <= IDLE;
       end
     else 
         begin
             case(q_sm_state) 
                   IDLE: begin
                              if(sig1 || sig2)
                                   begin
                                       q_sm_state <= WAIT;
                                       q_sig4 <= 1'b0;
                                   end
                                  else
                                      begin
                                          q_sm_state <= IDLE;
                                          q_sig4 <= 1'b0;
                                    end
                           end
                   WAIT: begin
                             if(sig2 && sig3)
                                 begin
                                     q_sm_state <= DONE;
                                     q_sig4     <= 1'b0;
                               end
                             else
                                 begin
                                     q_sm_state <= WAIT;
                                     q_sig4     <= 1'b0;
                               end
                          end       
                                     
                   DONE:begin
                            if(sig3)
                                begin
                                    q_sm_state <= IDLE;
                                    q_sig4     <= 1'b1;
                                end
                            else
                                begin
                                    q_sm_state <= DONE;
                                    q_sig4     <= 1'b0;
                                end
                           end
                    
                 default: begin
                              q_sm_state <= IDLE;
                              q_sig4     <= 0;
                            end
           endcase   
     end
   end
 endmodule

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

//本例主要采用两段式状态机:在异步复位信号的控制下,一段式状态机进入IDLE
 //状态,q_sig4被复位,一旦sig1或者sig2有效,状态机进入WAIT状态,如果sig1和sig2同时有效,那么
 //状态机进入DONE状态,如果sig4还有效,那么q_sig4置位,同时状态机进入IDLE状态。
 
 module two_seg_fsm(clk,reset,sig1,sig2,sig3,q_sig4);
 //数据声明部分
 input clk,reset,sig1,sig2,sig3;
 
 output reg       q_sig4;
 
 reg [1:0]    current_state, next_state;
 
 //参数声明
 parameter  IDLE       = 2'b00;
 parameter  WAIT       = 2'b01;
 parameter  DONE       = 2'b10;
 
 //状态跳转程序设计
 always @(posedge clk or posedge reset)
  if(reset)
      current_state <= IDLE;
  else
      current_state <= next_state;
      
 //状态逻辑输出
 always @(current_state or sig1 or sig2 or sig3)
   begin
       case(current_state)
       IDLE: begin
                              if(sig1 || sig2)
                                   begin
                                       next_state = WAIT;
                                       q_sig4    = 1'b0;
                                   end
                                  else
                                      begin
                                          next_state = IDLE;
                                          q_sig4     = 1'b0;
                                    end
                           end
                   WAIT: begin
                             if(sig2 && sig3)
                                 begin
                                     next_state = DONE;
                                     q_sig4     = 1'b0;
                               end
                             else
                                 begin
                                     next_state = WAIT;
                                     q_sig4     = 1'b0;
                               end
                          end       
                                     
                   DONE:begin
                            if(sig3)
                                begin
                                    next_state = IDLE;
                                    q_sig4     = 1'b1;
                                end
                            else
                                begin
                                    next_state = DONE;
                                    q_sig4     = 1'b0;
                                end
                           end
                    
                 default: begin
                              next_state = IDLE;
                              q_sig4     = 0;
                            end
           endcase   
     
   end
 endmodule

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

//本例主要采用三段式状态机:在异步复位信号的控制下,一段式状态机进入IDLE
 //状态,q_sig4被复位,一旦sig1或者sig2有效,状态机进入WAIT状态,如果sig1和sig2同时有效,那么
 //状态机进入DONE状态,如果sig4还有效,那么q_sig4置位,同时状态机进入IDLE状态。
 
 module three_seg_fsm(clk,reset,sig1,sig2,sig3,q_sig4);
 //数据声明部分
 input clk,reset,sig1,sig2,sig3;
 
 output reg       q_sig4;
 
 reg [1:0]    current_state, next_state;
 
 //参数声明
 parameter  IDLE       = 2'b00;
 parameter  WAIT       = 2'b01;
 parameter  DONE       = 2'b10;
 
 //状态跳转程序设计
 always @(posedge clk or posedge reset)
  if(reset)
      current_state <= IDLE;
  else
      current_state <= next_state;
      
 //状态跳转输出
 always @(current_state or sig1 or sig2 or sig3)
   begin
       case(current_state)
       IDLE: begin
                              if(sig1 || sig2)
                                   begin
                                       next_state = WAIT;                                      
                                   end
                                  else
                                      begin
                                          next_state = IDLE;                                         
                                    end
                           end
                   WAIT: begin
                             if(sig2 && sig3)
                                 begin
                                     next_state = DONE;                                    
                               end
                             else
                                 begin
                                     next_state = WAIT;                                    
                               end
                          end       
                                     
                   DONE:begin
                            if(sig3)
                                begin
                                    next_state = IDLE;                                   
                                end
                            else
                                begin
                                    next_state = DONE;                                   
                                end
                           end
                    
                 default: begin
                              next_state = IDLE;                             
                            end
           endcase       
   end
   
   //逻辑输出
   always @(posedge clk or posedge reset)
     if(reset)
         q_sig4 <= 1'b0;
     else
         begin
             case(next_state)
                 IDLE,
                 WAIT: q_sig4 <= 1'b0;
                 DONE: q_sig4 <= 1'b1;
                 default: q_sig4 <= 1'b0;
           endcase
         end
         
 endmodule
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • 其他参考:主要是区分moore状态机和mealy状态机的。[原创][FPGA]有限状态机FSM学习笔记(一)[转载...
    暗夜望月阅读 7,389评论 1 2
  • fpga规范 工作过的朋友肯定知道,公司里是很强调规范的,特别是对于大的设计(无论软件还是硬件),不按照规范走几乎...
    Michael_Johnson阅读 1,851评论 1 4
  • 学号:16010199021 姓名:李若宇 转载自 http://blog.csdn.net/sun1991011...
    承瑜阅读 800评论 0 0
  • by yang 最近准备数字IC岗时复习整理的知识点,参考了比较火的fpga面试题,和一些相关知识。主要是写着自己...
    Yuhan尽量笑不露齿阅读 2,616评论 0 2
  • 四季的手拂过远远的山川 花儿开放在山谷, 有些落了,有些藏在黑暗的泥土,也许永不能盛放。 来的人走了,也有人来了,...
    金铃子阅读 269评论 0 0