| **银杏科技有限公司旗下技术文档发布平台** |||| |技术支持电话|**0379-69926675-801**||| |技术支持邮件|Gingko@vip.163.com||| ^ 版本 ^ 日期 ^ 作者 ^ 修改内容 ^ | V1.0 | 2020-11-20 | zgf | 初次建立 | ===== 实验八:计数器实验——LED灯闪烁 ===== ==== 一、 实验目的与意义 ==== - 掌握计数器的原理及实现方法; - 掌握HqFpga开发环境的使用方法。 ==== 二、 实验设备及平台 ==== - iCore3L 双核心板; - XiST USB Cable仿真器; - Micro USB线缆; - HqFpga开发平台; - 电脑一台; ==== 三、 实验原理 ==== * 计数器是实现计数的一种最基本的逻辑运算。在FPGA中计数器的实质其实就是对触发信号沿进行计数,每当触发事件到来,计数器参数实现累加或者减,到某个状态进行清零操作。FPGA中常用计数器实现时钟分频、定时器、延时、计数、控制等功能,是FPGA设计中常用的一种控制方法。 ==== 四、 实验步骤 ==== 1、打开HqFpga软件,新建工程,FPGA型号为SL2S-25E-8U213C。通过“工程属性”界面将例程下的源文件添加到新建立的工程,或者通过“设计管理”界面建立新的源文件并添加到工程中。 {{ :icore3l:icore3l_fpga_8_1.png?direct |图 8-1 新建工程,设置器件参数及添加源文件}} 2、本例程下包含3个源文件,分别是rst_n.v、counter_ctrl.v和counter.v文件。这三个源文件分别包含了对应的三个功能模块。 * 1)rst_n模块用于上电后产生复位信号; * 2)counter_ctrl模块实现定时器及LED状态控制功能; * 3)counter作为顶层模块调用rst_n模块和counter_ctrl模块。 3、点击“RTL综合”按钮,进行编译,如果没有报错,点击左侧栏“物理约束”按钮,绑定信号引脚。 {{ :icore3l:icore3l_fpga_8_2.png?direct |图 8-2 添加物理约束,绑定器件引脚}} 4、然后点击“保存”图标并退出物理约束界面;在主界面,点击左侧边栏的“全部运行”按钮。编译后可以看到生成了下载文件;将下载器连接到iCore3L双核心板上,将生成的比特流文件下载到FPGA中,可以看到开发板上LED每一秒钟亮灭状态切换一次。 {{ :icore3l:icore3l_fpga_8_3.png?direct |图 8-3 下载生成的bit流文件}} ==== 五、 代码讲解 ==== * 本实验是通过计数器实现一个周期为1s的定时器,然后通过定时器产生的信号作为触发条件,控制led电平的切换,实现led的闪烁功能。系统时钟为25MHz,其钟周期为40ns,即1s的时间包含25000000个时钟周期。那么,要实现计时一秒,可以通过对系统时钟进行计数的方式来实现。对于变量time_cnt,在每个时钟的上升沿,对其进行累加操作,当累加计满(25000000-1)时,进行清零,进入下一个累加循环。这里的减1是因为time_cnt变量是从0开始累加的。 * 根据time_cnt的值,可以判断持续了多少时间;只需每次在time_cnd的值为24999999时,产生一个脉冲信号,表示计时满1秒。代码如下: /*************************************************/ //利用计数器实现一个定时器,定时为1s reg [31:0]time_cnt; always@(posedge fpga_clk or negedge rst_n) begin if(!rst_n) begin time_cnt <= 32'd0; end else begin if(time_cnt==32'd24999999) begin time_cnt <= 32'd0;///计数器清零 end else begin time_cnt <= time_cnt + 1'd1;//计数器自加1 end end end wire time_sig = (time_cnt==32'd24999999) ? 1'd1 : 1'd0;//定时器信号 * 根据计数器产生的定时器信号,使控制LED状态的寄存器值发生翻转,即可控制LED亮或者灭。代码如下: /*************************************************/ //利用定时器信号触发led事件 reg [2:0] fpga_led_r; always@(posedge time_sig or negedge rst_n) begin if(!rst_n) begin fpga_led_r <= 3'b111; end else begin fpga_led_r <= ~fpga_led_r; end end assign fpga_led = fpga_led_r; //--------------------------------------------// * 向工程中添加文件的时候,添加了rst_n.v、counter.v以及counter_ctrl.v三个文件,这三个文件分别包含了三个模块。counter作为顶层模块,调用了rst_n模块,以及counter_crtl模块,并与这两个模块的信号相互连接起来。 * 这种采用层级结构,将系统功能划分成小的易实现的功能模块,通过模块之间的调用,将各个独立模块组成更大的模块或系统的方法,是FPGA工程设计中常用的一种方法。通过这种方式,将一些常用功能模块化,并在系统设计中进行重复调用,可有效提高开发效率和降低错误率。 ==== 六、 拓展实验 ==== 1、 通过HqInsght观察time_sig与time_cnt之间的关系。