文章目录
前言
在前面的课程中我们学习了led灯控制、按键消抖、按键控制蜂鸣器等等。本文将引入状态机,在前期的课程之上,基于状态机进行流水灯的设计。
一、有限状态机介绍
有限状态机(Finite State Machine, FSM),又称有限状态自动机,简称状态机,是指在有限个状态之间按照一定规律转换的时序电路。
二、有限状态机应用
2.1 红绿灯
机动车道红绿灯其实就是一个有限状态机实现的流水灯,只是红绿灯闪烁的间隔不等,一般黄灯3s、红灯60s、绿灯20s。而在流水灯中,设置闪烁的间隔时间是相等的。我们将在本文的第四节中,使用有限状态机实现流水灯。
2.2 电子门锁
密码解锁的过程也是一个有限状态机,只有按正确密码的顺序输入密码,才能打开电子锁。
三、有限状态机模型
有限状态机主要包括:米利状态机和穆尔状态机。输出与输入变量直接相关的状态机称为米利状态机,输出与输入变量无直接关系的状态机称为穆尔状态机。
3.1 米利状态机
3.2 穆尔状态机
四、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 功能仿真
五、管脚分配
元件 | 管脚 |
---|---|
LED0 | G15 |
LED1 | F16 |
LED2 | F15 |
LED3 | D16 |
KEY0 | E15 |
KEY1 | E16 |
KEY2 | M16 |
KEY3 | M15 |
COLOCK(时钟) | E1 |
总结
以上就是今天要讲的内容。本文仅仅简单介绍了有限状态机,有限状态机主要的模型,以及有限状态机实现流水灯。有限状态机应用很广,包括文中的电子门锁。感兴趣的同学可以使用cyclone IV开发板上的按键和led模拟电子门解锁过程。由于最终实现的功能和流水灯类似,本文中不再上传视频演示效果。感谢你的观看!