FPGA型号:Cyclone IV EPFCE10F17C8 开发工具:Quartus13.0专业版 Modelsim 10.1d
文章目录
- 状态机
- 一、设计思路
- 二、代码设计
- 1.顶层代码
- 2.测试代码
- 三、仿真
状态机
状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。状态机的4个要素:现态、条件、动作、次态。“现态”和“条件”是因 ,“动作”和“次态”是果。
1)现态:指当前所处状态;
2)条件:又称“事件”。当条件被满足时,将会触发一个动作,或者执行一次状态的迁移。
3)动作:条件满足后执行的动作。条件满足后执行的动作。动作执行完毕后,可以迁移到新的状态,也可以仍旧保持原状态。动作不是必须的,当条件满足后,也可以不执行任何动作,迁移到新状态。
4)次态:条件满足后要迁往的新状态。“次态”是相对于“现态”而言的,“次态”一旦被激活,就变成新的“现态”了。
有限状态机简写为FSM(Finite State Machine),主要分为2大类:
第一类,若输出只和状态有关而与输入无关,则称为Moore状态机。
第二类,输出不仅和状态有关而且和输入有关系,则称为Mealy状态机
常用的三段式状态机的设计思路为:
1)一段式:利用一个进程来描述状态的转换及输出信号的定义;
2)二段式:一个为时序电路主要负责状态变量的更新,此进程为同步电路,而另一个进程语句主要是描述下次态变量和输出的更新;
3)三段式:第一个进程主要负责状态变量的更新,第二个进程语句负责描述次态变量,而最后一个则是负责输出信号的更新。
一、设计思路
FPGA实现一个按键控制三个LED灯亮灭的状态机如图所示。在初始状态下,LED灯全部处于熄灭状态。当按键被按下时,会启动消抖程序,默认按键按下时,延迟10ms,若按键仍处于低电平,则说明按键确实被按下,系统进入进入状态1,即LED_r处于低电平,红色LED灯亮起,并保持。当按键再次被按下时,继续进行消除抖动检测,若满足,则系统进入状态2,即LED_g处于低电平,绿色LED灯亮起,并保持。同理,当系统进入状态3时,LED_b处于低电平,蓝色LED灯亮起,并保持。当系统复位时,系统返回至初始状态。
时序图如图所示:
二、代码
1.顶层代码
`timescale 1ns/1ps
//模块定义
module FSM(
clk,
rst_n,
key,
led_r,
led_g,
led_b
);
//输入输出
input clk;
input rst_n;
input key;
output led_r;
output led_g;
output led_b;
//信号类型定义
parameter ms_10 = 250_000;
reg key_en;
reg [17:0] low_cnt;
reg [17:0] hig_cnt;
reg [1:0] led_cnt;
reg led_r;
reg led_g;
reg led_b;
wire key_flag;
//按键消抖
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
key_en <= 1'd0;
low_cnt <= 18'd0;
hig_cnt <= 18'd0;
end
else if (key_en) begin //检测按键为高电平时,延时10ms将状态读取
low_cnt <= 18'd0;
if (hig_cnt == ms_10) begin
key_en <= key;
hig_cnt <= hig_cnt;
end
else begin
hig_cnt <= hig_cnt +1'd1;
end
end
else begin //检测按键为低电平时,延时10ms将状态读取
hig_cnt <= 18'd0;
if (low_cnt == ms_10) begin
key_en <= key;
low_cnt <= low_cnt;
end
else begin
low_cnt <= low_cnt +1'd1;
end
end
end
assign key_flag = key_en;
//按键下降沿控制led状态切换
always @ (negedge key_flag or negedge rst_n) begin
if (!rst_n) begin
led_cnt <= 2'd0;
end
else if (led_cnt == 2'd2) begin
led_cnt <= 2'd0;
end
else begin
led_cnt <= led_cnt +2'd1;
end
end
//状态机:led状态切换
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
led_r <= 1'd1;
led_g <= 1'd1;
led_b <= 1'd1;
end
else case(led_cnt)
2'd0: begin //红灯亮
led_r <= 1'd0;
led_g <= 1'd1;
led_b <= 1'd1;
end
2'd1: begin //绿灯亮
led_r <= 1'd1;
led_g <= 1'd0;
led_b <= 1'd1;
end
2'd2: begin //蓝灯亮
led_r <= 1'd1;
led_g <= 1'd1;
led_b <= 1'd0;
end
default: begin //都不亮
led_r <= 1'd1;
led_g <= 1'd1;
led_b <= 1'd1;
end
endcase
end
endmodule
2.测试代码
`timescale 1 ps/ 1 ps
module FSM_vlg_tst();
reg clk;
reg key;
reg rst_n;
// wires
wire led_b;
wire led_g;
wire led_r;
// wires
// assign statements (if any)
FSM i1 (
// port map - connection between master ports and signals/registers
.clk(clk),
.led_b(led_b),
.led_g(led_g),
.led_r(led_r),
.rst_n(rst_n)
);
initial
begin
clk = 0;
key = 0;
forever #5 clk = ~clk;
end
initial
begin
rst_n = 1;
#30 rst_n = ~rst_n;
#10 rst_n = ~rst_n;
end
always
begin
#50 key = ~key;
end
endmodule
三、仿真
文章来源:https://www.toymoban.com/news/detail-786617.html
由图可见,仿真结果基本符合预期。 文章来源地址https://www.toymoban.com/news/detail-786617.html
到了这里,关于FPGA通过一个按键控制三个LED灯亮灭(状态机法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!