标签:
作者:MiS603开发团队
日期:20150911
公司:南京米联电子科技有限公司
论坛:www.osrc.cn
EAT博客:http://blog.chinaaet.com/whilebreak
博客园:http://www.cnblogs.com/milinker/
关于流水灯,网上有太多的例子了。其实只要掌握上面分频计数的技巧,设计流水灯是件极其简单的事情。从1.1.8可以看出,LED以每秒1次的频率进行闪烁,只要将这单个LED灯,保持1s高亮状态后,每秒移位一次,即可得到多个LED灯以流水线形式闪烁。
LED灯依次以1s的高亮状态保持进行移位显示,将单个LED灯分别映射到多个LED灯上即可。其设计总体框图如下所示。从Mis603原理图中可以看出,FPGA的IO在高电平时候,LED熄灭,低电平时,LED点亮。故设置LED初始化状态为高电平,即熄灭状态。
? 输入时钟50MHZ,为保证LED灯能够稳定1秒。定义计数器为50000000/1=50000000。在此定义一个26位位宽的div_cnt计数器。检测输入时钟上升沿,div_cnt==26’d49_999999时,LED寄存器进行右移一次,计数器清零。8个LED初始化状态为8’h01。当led_o_r==8’h00时,重置led_o_r==8’h01。由于Mis603是FPGA的IO保持低电平时,LED灯点亮,故在程序结束后,将LED存储寄存器取反即可。这样,8个LED灯依次循环点亮。
`timescale 1ns / 1ps
//-----------------------------------------------------------------------------------------------------
/*
* 文件名字:water_lights
* 程序描述:
* 作 者:
* 修改日期:
* 版 本 号:
* 版权所有:南京米联电子科技有限公司
*/
//-----------------------------------------------------------------------------------------------------
module water_lights(
input clk_i,
input rst_n_i,
output [7:0] led_o
);
parameter HOLD_1S=26‘d49_999999; //for project
//parameter HOLD_1S=26‘d49; //for simulation
reg [25:0] div_cnt;
reg [7:0] led_o_r;
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
div_cnt<=0;
else if(div_cnt==HOLD_1S)
div_cnt<=0;
else
div_cnt<=div_cnt+1‘b1;
end
always@(posedge clk_i or negedge rst_n_i)
begin
if(!rst_n_i)
led_o_r<=8‘h01;
else if(div_cnt==HOLD_1S)
led_o_r<=led_o_r<<1;
else if(led_o_r==8‘h00)
led_o_r<=8‘h01;
else
led_o_r<=led_o_r;
end
assign led_o=~led_o_r;
endmodule
源程序中,设置HOLD_1S参数,为减少仿真等待时间,模拟LED灯点亮环境。单独定义仿真的参数,在仿真完成后,只需修改此参数即可。其仿真结果如图所示。从中可以看出,led_o_r[0]至led_o_r[7]以此循环拉低。
设置好逻辑分析仪,以clk_i_BUFGP作为采样时钟,触发信号依次设置为led_o_r[0]~led_o_r[7]。抓取信号结果如下图所示。从下图可看出,led_o_r翻转后跟modelsim中led_o输出结果保持一致。
程序中的HOLD_1S参数改成for_project选项,重新编译完成,程序下载到板子上,即可看到8个流水灯,欢快地闪烁。
流水灯或许是每个开发板必备的流程之一。从上两节可以看出,这些只要懂得分频计数的原理,实现起来还是很简单的。换着不同的花样,用FPGA设计各种计数器,做一些基础的实验,有利于初步掌握verilog语法和设计逻辑。
标签:
原文地址:http://www.cnblogs.com/milinker/p/4804168.html