有限状态机


前言

  在前面的课程中我们学习了led灯控制、按键消抖、按键控制蜂鸣器等等。本文将引入状态机,在前期的课程之上,基于状态机进行流水灯的设计。


一、有限状态机介绍

  有限状态机(Finite State Machine, FSM),又称有限状态自动机,简称状态机,是指在有限个状态之间按照一定规律转换的时序电路。


二、有限状态机应用

2.1 红绿灯

  机动车道红绿灯其实就是一个有限状态机实现的流水灯,只是红绿灯闪烁的间隔不等,一般黄灯3s、红灯60s、绿灯20s。而在流水灯中,设置闪烁的间隔时间是相等的。我们将在本文的第四节中,使用有限状态机实现流水灯。
红绿灯

图1. 红绿灯

2.2 电子门锁

  密码解锁的过程也是一个有限状态机,只有按正确密码的顺序输入密码,才能打开电子锁。

电子门锁

图2. 电子门锁

三、有限状态机模型

  有限状态机主要包括:米利状态机和穆尔状态机。输出输入变量直接相关的状态机称为米利状态机,输出与输入变量无直接关系的状态机称为穆尔状态机。

3.1 米利状态机

Mealy状态机

图3. 米利状态机框图

3.2 穆尔状态机

Moore状态机

图4. 穆尔状态机框图

四、FSM实现流水灯

4.1 fsm_led 源文件代码

module 	fsm_led(
	input 					clk  ,//时钟信号,50MHz
	input 					rst_n,//复位信号,下降沿有效
	
	output 	reg [3:0]	led//4个led灯
);

parameter 	TIME = 50_000_000;//间隔1s
//状态空间
parameter 	S_LED0 = 2'd0;
parameter 	S_LED1 = 2'd1;
parameter 	S_LED2 = 2'd2;
parameter 	S_LED3 = 2'd3;
//四个led灯状态
parameter 	LED0 = 4'b0001;
parameter 	LED1 = 4'b0010;
parameter 	LED2 = 4'b0100;
parameter 	LED3 = 4'b1000;
reg [25:0]	cnt;//时钟计数器
reg [1:0]	current_stat;//当前状态寄存器

//计时模块
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin//复位
		cnt <= 26'd0;//计数器清0
	end 
	else if(cnt == TIME - 1)begin//记满1s
		cnt <= 26'd0;//计数器清0
	end 
	else begin
		cnt <= cnt + 26'd1;//其他时间加1
	end 
end 

//状态切换
always@(posedge clk or negedge rst_n)begin
	if(!rst_n)begin
		current_stat <= 2'd0;//当前状态初始化为0
	end 
	else begin
		case(current_stat)
		S_LED0:	begin//状态为0时
						if(cnt == TIME - 1)begin//记满1s
							led <= LED1;//led灯切换0010状态
							current_stat <= S_LED1;//状态寄存器切换2'd1
						end 
						else begin
							led <= LED0;//否则还是保持0001状态
							current_stat <= S_LED0;//保持原来的状态
						end 
					end 
		S_LED1:	begin
						if(cnt == TIME - 1)begin//记满1s
							led <= LED2;//led灯切换0100状态
							current_stat <= S_LED2;//状态寄存器切换2'd2
						end 
						else begin
							led <= LED1;//否则还是保持0100状态
							current_stat <= S_LED1;//状态寄存器切换2'd1
						end 
					end 
		S_LED2:	begin
						if(cnt == TIME - 1)begin//记满1s
							led <= LED3;//led灯切换1000状态
							current_stat <= S_LED3;//状态寄存器切换2'd3
						end 
						else begin
							led <= LED2;//led灯切换0100状态
							current_stat <= S_LED2;//状态寄存器切换2'd2
						end 
					end 
		S_LED3:	begin
						if(cnt == TIME - 1)begin//记满1s
							led <= LED0;//led灯切换0001状态
							current_stat <= S_LED0;//状态寄存器切换2'd0
						end 
						else begin
							led <= LED3;//led灯切换1000状态
							current_stat <= S_LED3;//状态寄存器切换2'd3
						end 
					end 
		default:;
		endcase 
	end 
end 


endmodule 

4.2 fsm_led_tb 测试文件代码

`timescale 1ns/1ns//单位/精度
module	fsm_led_tb();

parameter 	CYCLE = 5'd20;//周期为20ns
parameter 	TIME  = 4'd10;//流水灯间隔为10*20=200ns
reg 		clk		     ;//时钟
reg 		rst_n	     ;//复位信号,下降沿有效
wire [3:0]	led			 ;//四个led灯

always #(CYCLE/2) clk = ~clk;//每隔10ns翻转一次

initial begin//初始化信号
	clk 	= 1'b0     ;//时钟信号初始化为0
	rst_n   = 1'b0     ;//复位信号初始化为0
	#(CYCLE/2)         ;//等待10ns
	rst_n   = 1'b1     ;//复位信号拉高电平
	#(CYCLE * TIME * 4);//等待20*10*4ns观察流水灯四个led灯的信号
	$stop              ;//停止
	
end 

//实例化测试模块
fsm_led	#(.TIME (TIME)) u_fsm_led(//另取名字
.clk		(clk)  ,//时钟信号,50MHz
.rst_n	    (rst_n),//复位信号,下降沿有效
	       	
.led		(led)//4个led灯
);
endmodule 

4.3 功能仿真

功能仿真

图4. FSM流水灯功能仿真

五、管脚分配

元件管脚
LED0G15
LED1F16
LED2F15
LED3D16
KEY0E15
KEY1E16
KEY2M16
KEY3M15
COLOCK(时钟)E1
表1. 管脚对照表

总结

  以上就是今天要讲的内容。本文仅仅简单介绍了有限状态机,有限状态机主要的模型,以及有限状态机实现流水灯。有限状态机应用很广,包括文中的电子门锁。感兴趣的同学可以使用cyclone IV开发板上的按键和led模拟电子门解锁过程。由于最终实现的功能和流水灯类似,本文中不再上传视频演示效果。感谢你的观看!

  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值