【FPGA实战篇三】状态机实现按键控灯


状态机实现按键控灯)

一、状态机

1、状态机认识

有限状态机(英语:finite-state machine,缩写:FSM)又称有限状态自动机,简称状态机,是表示有限个状态以及在这些状态之间的转移和动作等行为的数学模型。

  • 状态存储关于过去的信息,就是说:它反映从系统开始到现在时刻的输入变化。转移指示状态变更,并且用必须满足确使转移发生的条件来描述它。动作是在给定时刻要进行的活动的描述。
  • 有多种类型的动作:
  • 进入动作(entry action):在进入状态时进行退出动作:
  • 在退出状态时进行输入动作:
  • 依赖于当前状态和输入条件进行转移动作:在进行特定转移时进行
    FSM(有限状态机)可以使用上面图1那样的状态图(或状态转移图)来表示。此外可以使用多种类型的状态转移表。下面展示最常见的表示:当前状态(B)和条件(Y)的组合指示出下一个状态(C)。完整的动作信息可以只使用脚注来增加。包括完整动作信息的FSM定义可以使用状态表。
    状态转移表
    在这里插入图片描述

2、状态机分类

Moore机
只使用进入动作的FSM,就是说输出只依赖于状态。Moore模型的好处是行为的简单性。
Mealy机
只使用输入动作的FSM,就是说输出依赖于输入和状态。Mealy FSM的使用经常导致状态数目的简约。

3、相关资料参考

有限状态机.

二、按键点灯

1、功能描述

通过按键key控制led灯的状态。

2、功能实现

按键状态 LED显示状态
无按键按下 四个LED灯全灭
按下key0 自右向左的流水灯
按下key1 自左向右的流水灯
按下key2 四个LED灯同时闪烁
按下key3 四个LED灯全亮

3、系统框图

在这里插入图片描述

三、创建工程

有关quartus相关的工程创建方法,可以参考博客:

FPGA实战篇之按键消抖实现流水点灯

FPGA实战篇之蜂鸣器实现音乐播放

1、VScode创建工程项目

创建文件夹,命名为工程名称
在这里插入图片描述
在此文件夹中,再次创建三个文件夹(prj、sim(tb)、src(rtb))
在这里插入图片描述
在src文件夹内创建文本文档(鼠标右键→新建文本文档)
在这里插入图片描述
更改名称为项目模块名(点击确认更改扩展名)
在这里插入图片描述
打开VScode
在这里插入图片描述
找到你所创建的文件路径,添加进去
在这里插入图片描述
可以看到添加的文件
在这里插入图片描述
单击src,选择创建的文本,编写项目源码(这里是已经完成的项目)
在这里插入图片描述
源码编写完成后,打开quartus,选择创建新工程
在这里插入图片描述
编辑项目信息
在这里插入图片描述
添加文件到项目
在这里插入图片描述
选择型号以及芯片【EP4CE6F17C8
在这里插入图片描述
选择仿真版本(根据自己安装进行选择)
在这里插入图片描述
创建完成,信息对照
在这里插入图片描述

2、项目编译

编译
在这里插入图片描述
编译结果
在这里插入图片描述

3、查看逻辑电路图

图示
在这里插入图片描述
电路原理图
在这里插入图片描述

4、引脚配置

相关元件对应引脚

元件 引脚
LED0 G15
LED1 F16
LED2 F15
LED3 D16
key0 E15
key1 E16
key2 M16
key3 M15
clk E1

点击图标配置引脚
在这里插入图片描述
配置完成图示
在这里插入图片描述
更改引脚value

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
更改后,点击OK,再点击全编译
在这里插入图片描述

5、项目源码

module key_led (
    
    input                   clk,   //50M时钟
    input                   rst_n,
    input  wire  [3:0]      key,   //按键
    output reg   [3:0]      led    //led灯

);
//0.2s计数器,10_000_000次,24位宽

     reg [23:0] cnt;

     //定义状态计数器,4个状态,2个位宽
     reg [1:0] flag;

     //计数器模块
     always @(posedge clk or negedge rst_n) begin
         if (!rst_n) 
              cnt <= 24'b0;
         else if(cnt == 24'd10_000_000 -1)
              cnt <= 24'b0;
         else 
              cnt <= cnt + 1'b1;
     end
     //根据0.2s计数器切换状态
     always @(posedge clk or negedge rst_n) begin
         if (!rst_n) 
              flag <= 2'b0;
        else if(cnt == 24'd10_000_000 -1)
              flag <= flag + 1'b1;
        else
              flag <= flag;
     end
     //根据按键控制不同状态下的led
     always @(posedge clk or negedge rst_n) begin
         if (!rst_n)
               led <= 4'b0000;
             else if (!key[0] ) begin   //按下key0键,自右向左流水灯
               case (flag)

               2'd1     : led <= 4'b0001;
               2'd2     : led <= 4'b0010;
               2'd3     : led <= 4'b0100;
               2'd4     : led <= 4'b1000;
               default  : led <= 4'b0000;

               endcase
             end

             else if (!key[1]) begin   //按下key1键,自左向右流水灯
               case (flag)

               2'd1     : led <= 4'b1000;
               2'd2     : led <= 4'b0100;
               2'd3     : led <= 4'b0010;
               2'd4     : led <= 4'b0001;
               default  : led <= 4'b0000;

               endcase
             end

             else if (!key[2] ) begin   //按下key2键,闪烁
               case (flag)

               2'd1     : led <= 4'b1111;
               2'd2     : led <= 4'b0000;
               2'd3     : led <= 4'b1111;
               2'd4     : led <= 4'b0000;
               default  : led <= 4'b0000;

               endcase
             end

            else if (!key[3])      //按下key3键,全亮
               led <= 4'b1111;
            else 
               led <= 4'b0000;
             
         
     end

    
endmodule

四、开发板验证

1、程序烧录

连接开发板,打开电源
在这里插入图片描述
点击图标,烧录程序
在这里插入图片描述
程序烧录
在这里插入图片描述
点击start,烧录成功
在这里插入图片描述

2、功能验证

①无按键按下
在这里插入图片描述
②按下key0
在这里插入图片描述
③按下key1
在这里插入图片描述
④按下key2
在这里插入图片描述
⑤按下key3
在这里插入图片描述

Guess you like

Origin blog.csdn.net/QWERTYzxw/article/details/120346002