学习目的
- 学会时间单位的转换(比如,1S需要多少个50Mhz的时钟计数)
- 学会用Verilog实现计数器的功能
- 学会用Verilog实现并行数据从低位到高位依次补0
学习内容
让8个LED灯每间隔100ms依次点亮
学习平台
- 小精灵开发板
- QuartusII 11.0
- Modelsim 10.1a
- Debussy
原理分析
为了达到想要的效果,我们先将D8点亮100ms,然后熄灭;再点亮D9,然后熄灭;再点亮D2,然后熄灭。。。。。;点亮D7,然后熄灭;再重头点亮D8,然后熄灭,如此反复循环,便能看到LED流水灯的现象了。要将D8点亮100ms,我们需要将IO32管脚置为低电平并保持100ms。开发板的晶振是50Mhz,1个时钟周期便是20ns,所以100ms需要5000000个时钟周期(注意时间单位的换算,见文末),了解了原理,我们便可以开始编写代码。
代码展示
`timescale 1ns / 1ps
module led(
input clk , //主时钟,50Mhz
input rst_n ,//复位,低电平有效
output reg [7:0] led//8个LED灯
);
parameter time_100ms=5000000;
reg [23:0] clk_cnt ;//时钟计数寄存器
assign pulse_100ms=(clk_cnt==time_100ms-1)?1'b1:1'b0;//每100ms产生一个脉冲
//时钟计数
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
clk_cnt<=0;
else if(clk_cnt==time_100ms-1)
clk_cnt<=0;
else
clk_cnt<=clk_cnt+1;
end
//LED控制,每100ms LED从低位高位依次补0,即点亮了相应的LED灯
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
led<=8'hff;
else if(pulse_100ms&&led==0)
led<=8'hff;
else if(pulse_100ms)
led<={led[6:0],1'b0};//每100ms LED从低位高位依次补0,即点亮了相应的LED灯
else
;
end
endmodule
仿真波形
从仿真波形中,我们可以看到LED0~LED7依次从高电平变为了低电平,我们在开发板上看到的现象便是LED0,LED1…LED7依次被点亮,然后又全部熄灭,再被依次点亮。
结语
通过该实验我们需要掌握频率与时间的换算关系,比如50Mhz对应多少ns,1Mhz对应多少ns。理解了这个关系就可以知道代码中time_100ms为什么会被赋值5000000,同时要明白‘ led<={led[6:0],1’b0} ’这条语句为什么能将led从低位到高位依次被0,带着这两个疑问,读者自行分析一下,若有不清楚的地方请与我联系!
视频教程链接:https://pan.baidu.com/s/1LRPfsNM0fr9wf48C5yHUBg
提取码:18ua