用户工具

站点工具


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

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

一、 实验目的与意义

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

二、 实验设备及平台

  1. iCore4T 双核心板。
  2. iTool A(或相同功能)仿真器。
  3. USB Type C线缆。
  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

五、 实验步骤及实验结果

图12.1

  1. 将硬件正确连接,如图12.1所示。
  2. 将编写好的代码进行编译,并下载到开发板中;
  3. 观察实验现象——FPGA_LED闪烁,间隔大约为3s;

六、 拓展实验

  1. 通过Signaltap采样状态机跳转信号及状态切换,观察信号变化。
  2. 通过Signaltap采样对比一段式状态机、二段式状态机和三段式状态机状态跳转时序有何不同。
icore4tfpga_12.txt · 最后更改: 2024/04/10 11:07 由 zhaowenzhe