使用计数器,让板载led每0.5秒改变一次状态。
时序原理
说明:
系统时钟频率100MHz。在未分频情况下,(上升沿计数)计数一次的时间是1/100M = 0.01us = 10ns。在1s内的10ns个数记为M, M=1/10n = 1*10^8个。由于计数器从0开始计数,因此计数峰值是M-1,即一个计数周期计数M-1=9999999次。
计数器cnt模块:
module counter
#(
parameter CNT_MAX = 25'd24_999_999 //parameter定义参数(宏定义)
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg led_out
);
reg [24:0] cnt; //25位宽的计数器
/* 计数器cnt */
always@ (posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0) //复位信号有效时(复位时),cnt清零
cnt <= 25'd0;
else if (cnt == CNT_MAX) //计数到最大值,cnt清零
cnt <= 25'd0;
else
cnt <= cnt + 25'd1; //每个时钟上升沿cnt自增1
/* 由计数器控制的器件led */
always@ (posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0) //初始状态
led_out = 1'b0;
else if (cnt == CNT_MAX) //计数器cnt记满一次,led电平反转一次
led_out = ~led_out;
else //cnt未记满,led电平保持
led_out = led_out;
endmodule
模块rtl示意图:

模拟程序:
`timescale 1ns / 1ns
module tb_counter();
reg sys_clk;
reg sys_rst_n;
wire led_out;
initial
begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
always #10 sys_clk = ~sys_clk; //产生时钟信号:每10ns反转一次,T=50MHz
counter //实例化counter,实例化名称写在宏定义后
#(
.CNT_MAX(25'd24)
)counter_inst
(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.led_out(led_out)
);
endmodule
管脚绑定:
(本文使用的XILINX板子型号:xc7a35tcsg324-1,其他型号的管脚绑定请自行查看技术文档)
上电测试
生成比特流文件后上电测试。