这里会显示出您选择的修订版和当前版本之间的差别。
两侧同时换到之前的修订记录 前一修订版 后一修订版 | 前一修订版 | ||
icore4tfpga_14 [2020/02/24 10:12] zgf [二、 实验设备及平台] |
icore4tfpga_14 [2024/04/10 11:08] (当前版本) zhaowenzhe [五、 实验步骤及实验结果] |
||
---|---|---|---|
行 2: | 行 2: | ||
|技术支持电话|**0379-69926675-801**||| | |技术支持电话|**0379-69926675-801**||| | ||
|技术支持邮件|Gingko@vip.163.com||| | |技术支持邮件|Gingko@vip.163.com||| | ||
- | |技术论坛|http://www.eeschool.org||| | ||
^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | ||
- | | V1.0 | 2019-02-24 | gingko | 初次建立 | | + | | V1.0 | 2020-03-02 | gingko | 初次建立 | |
- | + | ===== 实验十四:计数器实验——呼吸灯 ===== | |
- | ===== 实验十四:有限状态机实验——二段式状态机描述 ===== | + | |
==== 一、 实验目的与意义 ==== | ==== 一、 实验目的与意义 ==== | ||
- | - 掌握二段式状态机的描述方法 | + | - 掌握计数器原理及实现方法。 |
- | - 掌握宏定义、参数变量的使用方法 | + | - 掌握QuartusII的使用方法。 |
- | - 掌握QuartusII的使用方法 | + | |
==== 二、 实验设备及平台 ==== | ==== 二、 实验设备及平台 ==== | ||
- | - iCore4T 双核心板。[[https://item.taobao.com/item.htm?spm=a1z10.1-c.w137644-251734891.3.5923532fDrMDOe&id=610595120319|点击购买]] | + | - iCore4T 双核心板。 |
- | - Blaster(或相同功能)仿真器。[[https://item.taobao.com/item.htm?id=554869837940|点击购买]] | + | - iTool A(或相同功能)仿真器。 |
- | - Micro USB线缆。 | + | - USB Type C 线缆。 |
- Keil MDK 开发平台。 | - Keil MDK 开发平台。 | ||
- Quartus开发平台。 | - Quartus开发平台。 | ||
- 电脑一台。 | - 电脑一台。 | ||
==== 三、 实验原理 ==== | ==== 三、 实验原理 ==== | ||
- | + | * 计数器是实现计数的一种最基本的加法运算。在FPGA中计数器的实质其实就是驱动参考时钟进行计数,每当触发事件到来,计数器参数实现自加,到某个状态进行清零操作。FPGA中常用计数器实现时钟分频、定时器、延时、计数、控制等功能,是FPGA实现功能中常用的一种逻辑电路。 | |
- | * 状态机是一种设计思想,通常由组合逻辑和寄存器两部分组成。寄存器用于存储状态,组合逻辑完成状态译码和产生输出信号。状态机的组成有3各基本要素:状态、输入和输出。其中状态是用来划分逻辑顺序和时序规律的变量;输入指的是状态机进入每个状态的条件;输出指的是在某种状态下发生的事件。 | + | |
- | * 描述状态机关键是要描述清楚状态机的三个要素,即如何进行状态转移、每个状态的输出是什么、状态转移的条件是什么等。在Verilog硬件描述时,状态机有3种常用的描述方法:一段式、二段式和三段式。 | + | |
- | * 二段式状态机的整个功能由两个模块完成,一个always模块采用同步时序的方法描述状态转移,另一个模块采用组合逻辑的方式判断状态转移条件,描述状态转移规律,两者结合功能完成状态机功能。 | + | |
- | * 二段式与一段式状态机相比,将同步时序和组合逻辑分别放在不同的always模块中,不仅便于阅读、理解、维护,更重要的是利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线实现设计。在二段式描述中,常采用组合逻辑描述状态的输出,这种组合逻辑有产生毛刺的可能性,且不利于约束,这也是二段式描述的缺点。 | + | |
- | * 本实验的实验原理是通过硬件语言描述产生一个周期为3s的时间闸门信号,以该信号作为状态转移的触发信号来实现状态跳转,通过状态跳转改变led的亮灭。在其中一个always模块采用同步时序描述状态转移,在另一个模块中判断状态转移条件、描述状态转移的规律和输出,实现控制led的状态。 | + | |
==== 四、 代码讲解 ==== | ==== 四、 代码讲解 ==== | ||
- | * 本实验状态机的主要功能是通过状态切换实现led的闪烁,在state_idle状态,led为灭;程序开始运行后,当3s时间闸门打开,状态跳转到state_led_on状态,点亮led;当3s时间闸门打开,状态转移信号有效,状态跳转到state_led_off状态;当3s时间闸门打开,状态转移信号有效,状态跳转到state_led_on状态,以此循环实现led的闪烁。其代码如下: | + | * 本实验是通过计数器实现一个周期为1s的定时器,然后通过定时器产生的信号作为触发事件控制led电平高低切换,实现led的闪烁功能。驱动参考时钟为25MHz,也就是说时钟周期为40ns,1s的周期需要25000000个时钟周期,因此定时器的计数器需要在25000000个周期时进行清零操作。其代码如下: |
- | * <code verilog> | + | <code verilog> |
- | //控制led亮灭的状态机 | + | /*************************************************/ |
- | //状态机流程,上电复位后进入空闲状态,然后等待大约3s时间闸门打开时进入点亮led状态,当检测到时间 | + | //利用计数器实现一个定时器,定时为1s |
- | //闸门信号的高电平时,将状态切换至熄灭led状态,再次检测到时间闸门时切换至亮状态,如此循环。 | + | reg [31:0]time_cnt; |
- | reg led_r; | + | |
- | reg [2:0]led_current_state;//当前状态 | + | |
- | reg [2:0]led_next_state;//下一个状态 | + | |
| | ||
- | //状态跳转逻辑设计always块 | ||
always@(posedge clk_25m or negedge rst_n) | always@(posedge clk_25m or negedge rst_n) | ||
begin | begin | ||
if(!rst_n) | if(!rst_n) | ||
begin | begin | ||
- | led_current_state <= `state_idle; | + | time_cnt <= 32'd0; |
end | end | ||
else | else | ||
begin | begin | ||
- | led_current_state <= led_next_state; | + | if(time_cnt==32'd24999999) |
- | end | + | begin |
- | end | + | time_cnt <= 32'd0;///计数器清零 |
- | + | ||
- | //状态逻辑输出 | + | |
- | always@(led_current_state or state_sig or rst_n) | + | |
- | begin | + | |
- | if(!rst_n) | + | |
- | begin | + | |
- | led_r <= led_off; | + | |
- | 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; | + | |
- | led_r <= led_on; | + | |
- | end | + | |
- | else | + | |
- | begin | + | |
- | led_next_state <= `state_idle; | + | |
- | end | + | |
end | end | ||
- | `state_led_on:begin | + | else |
- | if(state_sig) | + | begin |
- | begin | + | time_cnt <= time_cnt + 1'd1;//计数器自加1 |
- | led_next_state <= `state_led_off; | + | |
- | led_r <= led_off; | + | |
- | end | + | |
- | else | + | |
- | begin | + | |
- | led_next_state <= `state_led_on; | + | |
- | end | + | |
end | end | ||
- | `state_led_off:begin | ||
- | if(state_sig) | ||
- | begin | ||
- | led_next_state <= `state_led_on; | ||
- | led_r <= led_on; | ||
- | end | ||
- | else | ||
- | begin | ||
- | led_next_state <= `state_led_off; | ||
- | end | ||
- | end | ||
- | endcase | ||
end | end | ||
end | end | ||
+ | |||
+ | wire time_sig = (time_cnt==32'd24999999) ? 1'd1 : 1'd0;//定时器信号 | ||
</code> | </code> | ||
==== 五、 实验步骤及实验结果 ==== | ==== 五、 实验步骤及实验结果 ==== | ||
- | 1、将硬件正确连接,如图9.1所示。 | ||
- | {{ :icore4t:icore4t_fpga_14_1.jpg?direct |图14.1}} | ||
- | 2、将编写好的代码进行编译,并下载到开发板中; | + | {{ :icore4t:icore4t_ide_1_37.jpg?600 |图14.1}} |
- | 3、观察实验现象——FPGA_LED闪烁,间隔大约为3s; | + | - 将硬件正确连接,如图14.1所示。 |
+ | - 将编写好的代码进行编译,并下载到开发板中; | ||
+ | - 观察实验现象——FPGA_LED闪烁,间隔1s。 | ||
==== 六、 拓展实验 ==== | ==== 六、 拓展实验 ==== | ||
- | - | + | |
- | - 通过Signaltap采样状态机跳转信号及状态切换,观察信号变化。 | + | - 通过Signaltap观察定时信号与定时计数器之间的关系。 |
- | - 对比一段式状态机和二段式状态机状态跳转时序有何不同。 | + | |