参考正点原子的代码
module led_twinkle(
input sys_clk,
input sys_rst,
output [1:0] led
);
reg [25:0] cnt = 26'd0;
assign led = (cnt<26'd2500_0000)?2'b01:2'b10;
always @(posedge sys_clk or negedge sys_rst)
begin
if(!sys_rst)
cnt <= 26'd0;
else if(cnt<26'd5000_0000)
cnt <= cnt +1'b1;
else
cnt <= 26'd0;
end
endmodule
此时的testbench代码如下
`timescale 1ns / 1ps
module testbench();
reg sys_clk = 0;
reg sys_rst = 0;
wire [1:0] led;
always #10 sys_clk = !sys_clk;
initial
begin
#5
sys_rst = 1;
end
led_twinkle led_twinkle_tb(
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.led(led)
);
endmodule
当进行仿真的时候,可以看出实际灯1和灯2的点亮的时间并不为500ms。
从上面的图中可以看出,led1和led2点亮的时间是不相同的,led2的多了20ns,也就是一个时钟周期。
要想灯1亮500ms、灯2亮500ms,那么总的时间为1s。
这时候假设时钟周期为20ns,那么总共需要5000_0000个这样的周期。
计数器cnt的取值应该为0-4999_9999,只需要修改一个地方就行
always @(posedge sys_clk or negedge sys_rst)
begin
if(!sys_rst)
cnt <= 26’d0;
else if(cnt<26’d5000_0000-1’d1)
cnt <= cnt +1’b1;
else
cnt <= 26’d0;
end
endmodule
修改后的Verilog代码如下
module led_twinkle(
input sys_clk,
input sys_rst,
output [1:0] led
);
reg [25:0] cnt = 26'd0;
assign led = (cnt<26'd2500_0000)?2'b01:2'b10;
always @(posedge sys_clk or negedge sys_rst)
begin
if(!sys_rst)
cnt <= 26'd0;
else if(cnt<26'd5000_0000-1'd1)
cnt <= cnt +1'b1;
else
cnt <= 26'd0;
end
endmodule
这时候在继续进行仿真。