1、需求
若在FPGA上实现LED灯一秒闪烁一次,先进行计算,1秒闪烁一次,即周期为1秒,开发板XC7A35TFFG-2的基本时钟输入由板载 50MHz 有源晶振提供,即频率为f = 50MHz 。
则一个周期为
T
=
1
f
=
1
50
M
H
z
=
20
n
s
T=\frac{1}{f} = \frac{1}{50MHz}=20ns
T=f1=50MHz1=20ns
将一秒钟一分为二,即前0.5秒灯灭,后0.5秒灯亮。即亮和灭的周期数为
0.5
×
1
0
9
÷
20
=
25000000
T
0.5\times 10^9 \div20=25000000T
0.5×109÷20=25000000T。假设时钟从0开始,设置一个计数器,如果我们想设计
n
n
n个时钟周期长度的计数器,一般计数到
n
−
1
n-1
n−1即可。
例如设置一个计数为
4
4
4个时钟周期的计数器,时钟从
1
1
1开始,则计数器到
3
3
3即可,执行顺序如下
0
−
1
−
2
−
3
−
1
0-1-2-3-1
0−1−2−3−1.
2、设计定义
该实验有两个输入(复位信号和时钟信号),一个输出(led灯亮灭情况),复位信号低电平有效,时钟是上升沿触发。当复位信号来临时,led灯灭,计数器归0,当计数到24999999时,led灯翻转(即状态和原来相反),计数器归0。
3、编写代码
(1)创建工程,命名为led_flash_test,编写设计文件,其对应的verilog代码如下:
// 让led灯每秒闪烁一次 时序电路设计
module led_flash_test(
clk,reset_n,led //信号声明
);
input clk;
input reset_n;
output reg led; // 在always模块赋值的语句,设为reg型
reg [24:0] counter; // 时钟计数单元
always @(posedge clk or negedge reset_n)
if (!reset_n)
counter<=1'd0;
else if(counter == 24999999)
counter<=1'd0;
else
counter<=counter+1'd1;
always @(posedge clk or negedge reset_n)
if(!reset_n)
led <= 0;
else if(counter == 24999999)
led <= !led;
endmodule
编写测试文件,命名为led_flash_test_tb,其对应的verilog代码如下:
`timescale 1ns/1ps
module led_flash_test_tb();
reg clk;
reg reset_n;
wire led;
led_flash_test led_flash_test_inst0(
.clk(clk),
.reset_n(reset_n),
.led(led)
);
initial clk=1;
always #10 clk = !clk; # 每10ns翻转一次
initial begin
reset_n=0;
#201; # 避免和时钟上升沿重合
reset_n=1;
#1000000000;
end
endmodule
4、仿真&板级调试
点击run simulation,即可查看仿真结果,如下所示
接下来进行引脚分配,根据开发手册提供的引脚分配表,
将Y18分配给clk,M22(led0)分配给led,F15(按键S0)分配给reset_n,按下表示低电平,进行复位。具体设置如下:
生成比特流文件并写入开发板,效果如下:
一秒闪烁一次
按下复位按钮,灯灭。