什么是状态机:状态机通过不同的状态迁移来完成特定的逻辑操作

状态机的分类:Moore型状态机和Mealy型状态机

  1. Moore型:状态机的变化只与当前的状态有关
  2. Mealy型:状态机的变化不仅与当前的状态有关,还与输入有关

如何创建状态机:状态机的创建可以分为一段式,两段式和三段式

  1. 一段式:主要是讲所有的状态变化以及导致的输出变化都写在了一个always快中。

  2. 两段式:将一些复位信号,clk信号单独写在一个always快中,其他的状态变化,输出值得变化写在一个always快中。

  3. 三段式:将一些复位信号,clk信号单独写在一个always快中,其他的状态迁移变化写在一个always快中,对应状态的输出值得变化写在一个always快中。

举个例子:从循环输入的字母中做连续检测,当连续检测到“hello”时,将led灯进行状态的翻转,继续进行下一次的检测。

  1. 一段式的编写方式:
module  hello(
input clk,//系统时钟信号 50mHz
input rst_n,//系统复位信号,低电平有效
input [7:0] data,//连续输入的字母
output reg led//led灯
); //设置需要改变的状态
parameter checkh = 5'b0000_1,
checke = 5'b0001_0,
checkla = 5'b0010_0,
checklb = 5'b0100_0,
checko = 5'b1000_0; reg [4:0]state; always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
led <= 1'b0;
state <= checkh;
end
else
begin
case (state)
checkh:
if(data == "h") state <= checke;
else state <= checkh;
checke:
if(data == "e") state <= checkla;
else state <= checkh;
checkla:
if(data == "l") state <= checklb;
else state <= checkh;
checklb:
if(data == "l") state <= checko;
else state <= checkh;
checko:
if(data == "o")
begin
led <= ~led;
state <= checkh;
end
else state <= checkh;
default:state <= checkh;
endcase
end endmodule
  1. 两段式的编写方式:
module  hello(
input clk,
input rst_n,
input [7:0] data,
output reg led
); parameter checkh = 5'b0000_1,
checke = 5'b0001_0,
checkla = 5'b0010_0,
checklb = 5'b0100_0,
checko = 5'b1000_0; reg [4:0] cstate;
reg [4:0] nstate; always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
cstate <= checkh;
end
else
cstate <= nstate; always @(cstate or data)
case (cstate)
checkh:
if(data == "h") nstate <= checke;
else nstate <= checkh;
checke:
if(data == "e") nstate <= checkla;
else nstate <= checkh;
checkla:
if(data == "l") nstate <= checklb;
else nstate <= checkh;
checklb:
if(data == "l") nstate <= checko;
else nstate <= checkh;
checko:
if(data == "o")
begin
led <= ~led;
nstate <= checkh;
end
else nstate <= checkh;
default:nstate <= checkh;
endcase endmodule
  1. 三段式的编写方式:
module  hello(
input clk,
input rst_n,
input [7:0] data,
output reg led
); parameter checkh = 5'b0000_1,
checke = 5'b0001_0,
checkla = 5'b0010_0,
checklb = 5'b0100_0,
checko = 5'b1000_0; reg [4:0] cstate;
reg [4:0] nstate; //复位信号,clk的处理(主要是对初始状态进行赋值操作)
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
cstate <= checkh;
end
else
cstate <= nstate; //状态迁移的处理
always @(cstate or data)
case (cstate)
checkh:
if(data == "h") nstate <= checke;
else nstate <= checkh;
checke:
if(data == "e") nstate <= checkla;
else nstate <= checkh;
checkla:
if(data == "l") nstate <= checklb;
else nstate <= checkh;
checklb:
if(data == "l") nstate <= checko;
else nstate <= checkh;
checko:
if(data == "o")
begin
nstate <= checkh;
end
else nstate <= checkh;
default:nstate <= checkh;
endcase //输出数据的处理
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
led <= 1'b1;
end
else
case (cstate)
checko:
if(data == "o")
led <= ~led;
default;
endcase endmodule

注意

  1. 一般的状态机是使用Always语句和case语句组合来实现的
  2. 不可以根据Always快的个数来判断他是属于几段的状态机
  3. 一般情况下不建议使用一段式状态机,建议使用二和三段式状态机,二段式状态机使用时序逻辑处理状态变化,组合逻辑处理输入输出的变化,结构比较清晰,但容易产生毛刺
  4. 三段式从输入到输出会比一、两段式状态机延时一个时钟周期

最新文章

  1. Android 录音器
  2. Linux运维初级教程(三)文件及目录权限
  3. maven Spring获取不到配置文件
  4. sql语句查询经纬度范围
  5. hadoop2 环境的搭建(手动HA)
  6. Oracle之plsql快速入门
  7. 自动生成proto Js语句
  8. Python 学习之路2
  9. Eclipse的调试功能的10个小窍门[转]
  10. Linux安装配置Mariadb
  11. MySQL之记录相关操作
  12. 如何使用Windows防火墙禁止软件联网
  13. LeetCode - Reorganize String
  14. 你真的会Xilinx FPGA的复位吗?
  15. linux sqlplus查询数据中文乱码解决方法记录
  16. 解决 Delphi XE5 写Android程序的No resource identifier found for attribute... 错误【转】
  17. ASP.NET Core 中的框架级依赖注入
  18. SpringBoot+Mybatis-Generator自动生成
  19. 【POJ】2151:Check the difficulty of problems【概率DP】
  20. CATransaction:原子化操作、批量操作、整体设置、自动添加

热门文章

  1. Eclipse daemon not running. starting it now on port ***的
  2. 在centOS使用systemctl配置启动多个tomcat
  3. web服务端安全之SQL注入攻击
  4. Django快速创建博客,包含了整个框架使用过程,简单易懂
  5. python中%r和%s的区别
  6. bzoj hash+map+set
  7. IEEE Bigger系列题解
  8. BZOJ 1003 物流运输trans dijstra+dp
  9. nlogn 求最长上升子序列 LIS
  10. 【ButterKnife】 安卓程序猿的一大利器