FPGA的设计中通常使用计数器来计时,对于采用200Mhz的系统时钟,一个时钟周期是5ns,那么表示一秒需要200000000个时钟周期,如果一个时钟周期计数器累加一次,那么计数器从0到199999999正好是200000000个周期,就是1秒的时钟。(时间仅供参考,具体可以根据所需要的时间来修改参数,~~虽然我改的时候发现很困难,并且需要大量的时间~~ )
首先需要定义一个32位的定时器,最大可以表示4294967295,十六进制就是FFFFFFFF,如果计数器到最大值,可以表示21.474836475秒。程序设计中是每隔0.25秒LED变化一次,一共消耗1秒做一个循环。(所有时间数据以代码为准)
在0.25秒、0.5秒、0.75秒、1秒到来的时刻分别改变LED的状态,其他时候都保持原来的值不变。(只有在LED动的那一个时刻改变LED的状态,其他时间保持不变,具体可以参考我的仿真结果)
~~话不多说上代码~~
~~分割线~~
`timescale 1ns / 1ps
module Led_test(
clk_p, // Differentia system clock 200Mhz input on board
clk_n,
rst_n, // reset ,low active
led, // LED,use for control the LED signal on board
fan_pwm //fan control
);
input clk_p,clk_n;
input rst_n;
output [3:0] led;
output fan_pwm;
reg [31:0] timer;
reg [3:0] led;
assign fan_pwm =1'b0;
//Differentia system clock to single end clock
wire sys_clk;
IBUFGDS u_ibufg_sys_clk (
.I (clk_p ),
.IB (clk_n ),
.O (sys_clk ) );
always @(posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
timer <= 32'd0;
else if(timer == 32'd59_999_999)
timer <= 32'd0;
else
timer <= timer + 1'b1;
end
//Led control
always @(posedge clk_n or negedge rst_n) //为了加快时间进度,这里我修改了参数,仅供参考
begin
if(!rst_n)
led <= 4'b0000;
else if(timer == 32'd19_999_999)
led <= 4'b0001;
else if(timer == 32'd29_999_999)
led <= 4'b0010;
else if(timer == 32'd39_999_999)
led <= 4'b0100;
else if(timer == 32'd49_999_999)
led <= 4'b1000;
end
endmodule
测试代码
`timescale 100ns / 1ps
module sim_led_test;
reg clk_p;
wire clk_n;
reg rst_n;
wire [3:0]led;
Led_test uut(
.clk_p ( clk_p ), // Differentia system clock 200Mhz input on board
.clk_n ( clk_n ),
.rst_n ( rst_n ), // reset ,low active
.led ( led )); // LED,use for control the LED signal on board
initial begin
clk_p = 0;
rst_n = 0;
#100;
rst_n = 1;
#20000;
end
always #25 clk_p = ! clk_p;
assign clk_n = ! clk_p;
endmodule
仿真结果