《计算机组成与CPU设计实验》5有限状态机的Verilog HDL描述(Finite State Machine,FSM)

本篇内容来源于中国大学mooc《计算机组成与CPU设计实验》 (江苏大学)中的课程视频、PPT等相关资料。

本篇内容为《计算机组成与CPU设计实验》——状态机

参考视频:

 计算机组成与CPU设计实验_江苏大学_中国大学MOOC(慕课) (icourse163.org)

多数控制逻辑都可以用有限状态机描述

状态机

状态机是组合逻辑和时序逻辑的特殊组合

  • 时序逻辑用于存储状态
  • 组合逻辑用于产生次态和产生输出

状态的数量是有限的,故称为有限状态机(Finite State Machine,简称为FSM)

db6651c3e9d74e5a99d499bd58cdc0f6.png

状态机分类

摩尔Moore型状态机结构

输出仅取决于当前状态。

在整个状态周期内输出保持不变,即使输入信号有变化。

5b2707bea5c54811896576d64cd18caf.png

米利Mealy型状态机结构

除当前状态外,输出还直接受输入影响,变化可能出现在任何时刻。

c8efe7b5cc2443b49e730e2e2828e4a3.png

例子:玩具小车的速度档位

玩具小车汽车的速度有四个状态:停止、低速、中速、高速。

速度由刹车brake和加速器accelerator绝决定 

f72d2ac84ae64fd68055fb63c063bcaa.png

状态图

  • stop
  • stop->low speed                    刹车没有启动, 启动加速器brake=0  accelerator=1
  • low speed->medium speed   刹车没有启动, 启动加速器brake=0  accelerator=1
  • medium speed->high speed  刹车没有启动, 启动加速器brake=0  accelerator=1
  • high speed->medium speed  刹车启动       brake=1 
  • medium speed->low speed    刹车启动      brake=1 
  • low speed->stop                    刹车启动       brake=1  

7b214bf6d48145069c5e69118372dc3b.png

Verilog描述( Moore型状态机)

输出仅取决于当前状态。

module FSM(
 input Clk,Reset,
 input brake,//刹车
 input acc,//加速
 output [1:0] speed
);

reg [1:0]state; //现态
reg [1:0 ]next_state;//次态

localparam STOP = 2'b00;
localparam LOW =  2'b01;
localparam MEDI = 2'b10;
localparam HIGH = 2'b11;
//状态转换    时序逻辑
always@(posedge Clk or Reset)
   if(Reset)
      state  <= stop;
     else
       state <= next_state; 

//次态计算  组合逻辑
always@(*)
  case(state)
    STOP:
       if(acc & !brake) next_state = LOW;
       else							next_state = STOP;
    LOW:
       if(brake)        next_state = STOP;
       else	if(acc)			next_state = MEDI;
  		 else							next_state = LOW ;
  	MEDI:
       if(brake)        next_state = LOW;
       else	if(acc)			next_state = HIGH;
  		 else							next_state = MEDI ;
  	HIGH:
       if(brake)        next_state = MEDI;
  		 else							next_state = HIGH ;
  endcase
 //输出逻辑  组合逻辑
 assign speed = state;

endmodule

 Mealy型状态机的描述

假设按下easy这个按钮,玩具小车以一档(低速)行驶。 和当前是什么状态没有关系。

module FSM(
 input Clk,Reset, brake, acc,
 input easy,//输入信号
 output [1:0] speed
);

reg [1:0]state; //现态
reg [1:0 ]next_state;//次态

localparam STOP = 2'b00;
localparam LOW =  2'b01;
localparam MEDI = 2'b10;
localparam HIGH = 2'b11;
//状态转换
always@(posedge Clk or Reset)
   if(Reset)
      state  <= stop;
     else
       state <= next_state; 

//次态计算
always@(*)
  case(state)
    STOP:
       if(acc & !brake) next_state = LOW;
       else							next_state = STOP;
    LOW:
       if(brake)        next_state = STOP;
       else	if(acc)			next_state = MEDI;
  		 else							next_state = LOW ;
  	MEDI:
       if(brake)        next_state = LOW;
       else	if(acc)			next_state = HIGH;
  		 else							next_state = MEDI ;
  	HIGH:
       if(brake)        next_state = MEDI;
  		 else							next_state = HIGH ;
  endcase
 //输出逻辑
 assign speed =easy? 2'b01:state;
    //输出speed除了和当前状态有关,也直接受easy输入影响。

endmodule

 状态编码

前面使用的是二进制数编码,除此之外,格雷码、约翰逊码等都可以用来状态机编码。

2cb25e6654fb40119ab424d28c7c2339.png

1、Sequential和Gray码使用的触发器最少

2、Johnson和Gray码的相邻编码只有一位不同,有利于减少电路噪声(依赖于转移状态)

3、One-hot编码

  • 所有位中只有一个1
  • 使用的触发器较多,但计算次态的组合电路较小
  • 适合于FPGA采用

 One-hot状态编码

 例子:玩具小车的速度档位(使用one hot编码)

module onehot_FSM(
 input Clk,Reset,
 input brake,//刹车
 input acc,//加速
 output [1:0] speed
);

reg [1:0]state; //现态
reg [1:0 ]next_state;//次态

localparam STOP = 4'b0001;
localparam LOW =  4'b0010;
localparam MEDI = 4'b0100;
localparam HIGH = 4'b1000;
//状态转换    时序逻辑
always@(posedge Clk or Reset)
   if(Reset)
      state  <= stop;
     else
       state <= next_state; 

//次态计算  组合逻辑
always@(*)
  case(state)
    STOP:
       if(acc & !brake) next_state = LOW;
       else							next_state = STOP;
    LOW:
       if(brake)        next_state = STOP;
       else	if(acc)			next_state = MEDI;
  		 else							next_state = LOW ;
  	MEDI:
       if(brake)        next_state = LOW;
       else	if(acc)			next_state = HIGH;
  		 else							next_state = MEDI ;
  	HIGH:
       if(brake)        next_state = MEDI;
  		 else							next_state = HIGH ;
  endcase
 //输出逻辑  组合逻辑
always@(state)
 case(state)
    STOP:  speed = 2'b00;
    LOW:   speed = 2'b01;
    MEDI:  speed = 2'b10;
    HIGH:  speed = 2'b11;
 endcase
endmodule

状态编码的定义方法 

1、用parameter或localparam语句

localparam STOP = 4'b0001;
localparam LOW =  4'b0010;
localparam MEDI = 4'b0100;
localparam HIGH = 4'b1000;

2、用`define语句(不推荐)

3、用枚举类型(SystemVerilog)

(1)默认情况下,枚举类型里元素的类型为int型,第一个元素的值为0,第二个为1,... 

enum {STOP, LOW, MEDIUM, HIGH } state;

(2)显式定义枚举元素的类型和值

enum bit[3:0]{STATE0 = 4'b0001,
              STATE1=  4'b0010,
              STATE2 = 4'b0100,
              STATE3 = 4'b1000, 
} state,next_state;

用枚举类型定义状态编码 

 例子:玩具小车的速度档位(使用枚举定义编码) 

module FSM(
 input Clk,Reset,
 input brake,//刹车
 input acc,//加速
 output [1:0] speed
);

//默认情况下,枚举类型里元素的类型为int型,第一个元素的值为0,第二个为1,...
enum    {     STOP ,//0
              LOW  ,//1
              MEDI ,//2
              HIGH   //3
} state,next_state;//现态、次态

//状态转换    时序逻辑
always@(posedge Clk or Reset)
   if(Reset)
      state  <= stop;
     else
       state <= next_state; 

//次态计算  组合逻辑
always@(*)
  case(state)
    STOP:
       if(acc & !brake) next_state = LOW;
       else							next_state = STOP;
    LOW:
       if(brake)        next_state = STOP;
       else	if(acc)			next_state = MEDI;
  		 else							next_state = LOW ;
  	MEDI:
       if(brake)        next_state = LOW;
       else	if(acc)			next_state = HIGH;
  		 else							next_state = MEDI ;
  	HIGH:
       if(brake)        next_state = MEDI;
  		 else							next_state = HIGH ;
  endcase
 //输出逻辑  组合逻辑
 assign speed = state;

endmodule

 用枚举类型定义One-hot编码

 例子:玩具小车的速度档位(使用枚举定义one hot编码) 

module onehot_FSM(
 input Clk,Reset,
 input brake,//刹车
 input acc,//加速
 output [1:0] speed
);

enum bit[3:0]{STOP = 4'b0001,
              LOW  = 4'b0010,
              MEDI = 4'b0100,
              HIGH = 4'b1000, 
} state,next_state;

//状态转换    时序逻辑
always@(posedge Clk or Reset)
   if(Reset)
      state  <= stop;
     else
       state <= next_state; 

//次态计算  组合逻辑
always@(*)
  case(state)
    STOP:
       if(acc & !brake) next_state = LOW;
       else							next_state = STOP;
    LOW:
       if(brake)        next_state = STOP;
       else	if(acc)			next_state = MEDI;
  		 else							next_state = LOW ;
  	MEDI:
       if(brake)        next_state = LOW;
       else	if(acc)			next_state = HIGH;
  		 else							next_state = MEDI ;
  	HIGH:
       if(brake)        next_state = MEDI;
  		 else							next_state = HIGH ;
  endcase
 //输出逻辑  组合逻辑
always@(state)
 case(state)
    STOP:  speed = 2'b00;
    LOW:   speed = 2'b01;
    MEDI:  speed = 2'b10;
    HIGH:  speed = 2'b11;
 endcase
endmodule

 状态机的描述风格

 状态机描述的3段式结构

  • 状态转换
  • 次态计算
  • 输出逻辑 

3b6043124cea48e6b4a414fc8f59298e.png

//FSM分为4块:状态定义,状态转换,次态计算,输出计算。

//状态变量声明
reg [N-1:]state, next_state;
//状态定义
localparam S0=... , S1=... , S2=..., S3=......;

//状态转换
always@(posedge clk or posedge reset)
  if(reset) state <= ...;
  else state <= next_state;

//次态计算
always @(*)
  begin
   case (state)
    ... next_stat = ...
  end

//输出逻辑
always @(...)
   .....

状态机描述的2段式结构

合并两个组合逻辑部分 

75b7b31d257b472a9851a945b40fc3ac.png

 注意:合并后的框图不能分辨摩尔型和米利型。

bd78ca11550f46698b2f5d7fb2530993.png

 状态机描述的 2段式结构

 合并了两个组合逻辑部分,与3段式仅仅是形式不同,不易分辨摩尔型和米利型。

 例子:玩具小车的速度档位(使用状态机描述的2段式结构) 

本例输出speed只受状态影响。

module onehot_FSM(
 input Clk,Reset,
 input brake,//刹车
 input acc,//加速
 output [1:0] speed
);

enum bit[3:0]{STOP = 4'b0001,
              LOW  = 4'b0010,
              MEDI = 4'b0100,
              HIGH = 4'b1000, 
} state,next_state;

//状态转换    时序逻辑
always@(posedge Clk or Reset)
   if(Reset)
      state  <= stop;
     else
       state <= next_state; 

//次态计算  + 输出逻辑
always@(*)
  case(state)
    STOP:
       speed = 2'b00;
       if(acc & !brake)     next_state = LOW;
       else					next_state = STOP;
    LOW:
       speed = 2'b01;
       if(brake)            next_state = STOP;
       else	if(acc)			next_state = MEDI;
  		 else				next_state = LOW ;
  	MEDI:
       speed = 2'b10;
       if(brake)            next_state = LOW;
       else	if(acc)			next_state = HIGH;
  		 else				next_state = MEDI ;
  	HIGH:
       speed = 2'b11;
       if(brake)           next_state = MEDI;
  		 else			   next_state = HIGH ;
  endcase

endmodule

状态机Verilog在线编程

 练习网站:

牛客网-状态机练习

1ce4c98077c142938fe147967759bb3b.png

 c7357770dcf14cfb96516c89b428b0ef.png

39a6e97cdff848589de8bc19c929b929.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值