| **银杏科技有限公司旗下技术文档发布平台** |||| |技术支持电话|**0379-69926675-801**||| |技术支持邮件|Gingko@vip.163.com||| ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | V1.0 | 2020-05-26 | gingko | 初次建立 | \\ ===== 实验十五:有限状态机实验——三段式状态机描述 ===== ==== 一、 实验目的与意义 ==== - 掌握三段式状态机的描述方法。 - 掌握宏定义、参数变量的使用方法。 ==== 二、 实验设备及平台 ==== - iCore4TX 双核心板。[[https://item.taobao.com/item.htm?spm=a1z10.1-c-s.w4004-22598974120.3.5923532fAsAtPz&id=614919247574|点击购买]] - USB-CABLE(或相同功能)的仿真器。 - Micro USB线缆。 - ISE开发平台。 - 电脑一台。 ==== 三、 实验原理 ==== * 状态机是一种设计思想,通常由组合逻辑和寄存器两部分组成。寄存器用于存储状态,组合逻辑完成状态译码和产生输出信号。状态机的组成有3各基本要素:状态、输入和输出。其中状态是用来划分逻辑顺序和时序规律的变量;输入指的是状态机进入每个状态的条件;输出指的是在某种状态下发生的事件。 * 描述状态机关键是要描述清楚状态机的三个要素,即如何进行状态转移、每个状态的输出是什么、状态转移的条件是什么等。在Verilog硬件描述时,状态机有3种常用的描述方法:一段式、二段式和三段式。 * 整个状态机由三个always模块实现,其中一个模块采用同步时序的方式描述状态转移,另一个模块采用组合逻辑的方式判断状态转移条件、描述状态转移规律,最后一个模块描述状态输出。 * 三段式与二段式状态机相比,它能够根据状态转移规律,在上一个状态根据输入条件判断当前状态的输出,从而在不插入额外时钟节拍的前提下实现寄存器输出,弥补二段式状态机的不足。 * 本实验的实验原理是通过硬件语言描述产生一个周期为3s的时间闸门信号,以该信号作为状态转移的触发信号来实现状态跳转,通过状态跳转改变led的亮灭。在其中一个always模块采用同步时序描述状态转移,在另一个模块中判断状态转移条件、描述状态转移的规律,在最后一个模块中描述led输出状态,实现控制led。 ==== 四、 代码讲解 ==== * 本实验状态机的主要功能是通过状态切换实现led的闪烁,目的时通过对led状态跳转的控制,学习三段式状态机的原理和使用。 * 先通过计数器产生一个标志信号state_sig,在状态机中检测到该信号后进行状态跳转;跳转到不同状态, led也显示在不同状态。复位之后进入state_idle状态,led是灭的;3秒后检测到标志信号state_sig为高后,状态跳转到state_led_on状态,点亮led;当3秒后再次检测到state_sig信号为高时,状态跳转到state_led_off状态,led灭;3秒后state_sig信号再次拉高,状态跳转至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 ==== 五、 实验步骤 ==== {{ :icore4tx:icore4tx_fpga_15_1.png?direct&550 |图15.1}} - 将硬件正确连接,如图15-1所示。 - 将编写好的代码进行编译,并下载到开发板中; - 观察实验现象——FPGA_LED闪烁,间隔大约为3s; ==== 六、 拓展实验 ==== - 通过ChipScope Pro采样状态机跳转信号及状态切换,观察信号变化。 - 观察ChipScope Pro采样信号,对比一段式状态机、二段式状态机和三段式状态机状态跳转时序有何不同。