用户工具

站点工具


icore4tfpga_15

这是本文档旧的修订版!


银杏科技有限公司旗下技术文档发布平台
技术支持电话0379-69926675-801
技术支持邮件Gingko@vip.163.com
技术论坛http://www.eeschool.org
版本 日期 作者 修改内容
V1.0 2019-02-24 gingko 初次建立

实验十五:有限状态机实验——三段式状态机描述

一、 实验目的与意义

  1. 掌握三段式状态机的描述方法。
  2. 掌握宏定义、参数变量的使用方法。
  3. 掌握QuartusII的使用方法。

二、 实验设备及平台

  1. iCore4T 双核心板。点击购买
  2. Blaster(或相同功能)仿真器。点击购买
  3. Micro USB线缆。
  4. Keil MDK 开发平台。
  5. Quartus开发平台。
  6. 电脑一台。

三、 实验原理

  • 状态机是一种设计思想,通常由组合逻辑和寄存器两部分组成。寄存器用于存储状态,组合逻辑完成状态译码和产生输出信号。状态机的组成有3各基本要素:状态、输入和输出。其中状态是用来划分逻辑顺序和时序规律的变量;输入指的是状态机进入每个状态的条件;输出指的是在某种状态下发生的事件。
  • 描述状态机关键是要描述清楚状态机的三个要素,即如何进行状态转移、每个状态的输出是什么、状态转移的条件是什么等。在Verilog硬件描述时,状态机有3种常用的描述方法:一段式、二段式和三段式。
  • 整个状态机由三个always模块实现,其中一个模块采用同步时序的方式描述状态转移,另一个模块采用组合逻辑的方式判断状态转移条件、描述状态转移规律,最后一个模块描述状态输出。
  • 三段式与二段式状态机相比,它能够根据状态转移规律,在上一个状态根据输入条件判断当前状态的输出,从而在不插入额外时钟节拍的前提下实现寄存器输出,弥补二段式状态机的不足。
  • 本实验的实验原理是通过硬件语言描述产生一个周期为3s的时间闸门信号,以该信号作为状态转移的触发信号来实现状态跳转,通过状态跳转改变led的亮灭。在其中一个always模块采用同步时序描述状态转移,在另一个模块中判断状态转移条件、描述状态转移的规律,在最后一个模块中描述led输出状态,实现控制led。

四、 代码讲解

  • 本实验状态机的主要功能是通过状态切换实现led的闪烁,在state_idle状态,led为灭;程序开始运行后,当3s时间闸门打开,状态跳转到state_led_on状态,点亮led;当3s时间闸门打开,状态转移信号有效,状态跳转到state_led_off状态;当3s时间闸门打开,状态转移信号有效,状态跳转到state_led_on状态,以此循环实现led的闪烁。其代码如下:
//控制led亮灭的状态机
//状态机流程,上电复位后进入空闲状态,然后等待大约3s时间闸门打开时进入点亮led状态,当检测到时间
//闸门信号的高电平时,将状态切换至熄灭led状态,再次检测到时间闸门时切换至亮状态,如此循环。
    reg led_r;
    reg [2:0]led_current_state;//当前状态
    reg [2:0]led_next_state;//下一个状态
 
//状态跳转逻辑设计always块
    always@(posedge clk_25m or negedge rst_n)
        begin
            if(!rst_n)
                begin
                    led_current_state <= `state_idle;
                end
            else
                begin
                    led_current_state <= led_next_state;
                end
        end
 
//状态输出
    always@(led_current_state or state_sig or rst_n)
        begin
            if(!rst_n)
                begin
                    led_next_state <= `state_idle;
                end
            else
                begin
                    case(led_current_state)
                        `state_idle:begin
                            if(state_sig)
                                begin
                                    led_next_state <= `state_led_on;
                                end
                            else
                                begin
                                    led_next_state <= `state_idle;
                                end
                        end
                        `state_led_on:begin
                            if(state_sig)
                                begin
                                    led_next_state <= `state_led_off;
                                end
                            else
                                begin
                                    led_next_state <= `state_led_on;
                                end
                        end
                        `state_led_off:begin
                            if(state_sig)
                                begin
                                    led_next_state <= `state_led_on;
                                end
                            else
                                begin
                                    led_next_state <= `state_led_off;
                                end
                        end
                        default:begin
                            led_next_state <= `state_idle;
                        end
                    endcase
                end
        end
 
//逻辑输出
    always@(posedge clk_25m or negedge rst_n)
        begin
            if(!rst_n)
                begin
                    led_r <= led_off;
                end
            else
                begin
                    case(led_next_state)
                        `state_idle:begin
                            led_r <= led_off;
                        end
                        `state_led_on:begin
                            led_r <= led_on;
                        end
                        `state_led_off:begin
                            led_r <= led_off;
                        end
                        default:begin
                            led_r <= led_off;
                        end
                    endcase
                end
        end

五、 实验步骤及实验结果

1、将硬件正确连接,如图9.1所示。 图15.1

2、将编写好的代码进行编译,并下载到开发板中; 3、观察实验现象——FPGA_LED闪烁,间隔大约为3s;

六、 拓展实验

  1. 通过Signaltap采样状态机跳转信号及状态切换,观察信号变化。
  2. 通过Signaltap采样对比一段式状态机、二段式状态机和三段式状态机状态跳转时序有何不同。
icore4tfpga_15.1582549482.txt.gz · 最后更改: 2020/02/24 21:04 由 zgf