1 功能:
实现LED闪烁10次后熄灭
2 实现方法
在原来定时计数器的基础上加入记录定时脉冲的计数器,每个定时脉冲加1,因此定时脉冲的计数器每计数两次LED闪烁一次,若需要使LED闪烁20次,则需要定时脉冲的计数器计数20次(0~19)。加入停止位stopFlag,当定时脉冲的计数器计数满后置为1,以后LED输出保持不变,这本程序为熄灭LED,也可以开启LED。
3 实现程序
module ledon_10times
#(
parameter COUNTER_MAX = 25'd24_999_999,
parameter LEDON_COUNTER = 5'd19
)
(
input wire sys_clk,
input wire sys_rst_n,
output reg led_out
);
reg [24:0] counter;
reg [4:0] ledOnCounter;
reg stopFlag = 1'b0;
reg counter_flag;
// 设置counter
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0)
counter <= 25'd0;
else if(counter == COUNTER_MAX)
counter <= 25'd0;
else
counter <= counter + 25'd1;
end
// 设置counter_flag
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0)
counter_flag <= 1'b0;
else if(counter == COUNTER_MAX - 25'd1)
counter_flag <= 1'b1;
else if(ledOnCounter == LEDON_COUNTER)
counter_flag <= 1'b0;
else
counter_flag <= 1'b0;
end
// 设置ledout,前10s灯闪烁,10次后熄灭
// 不能在不同always块中对同一个信号进行赋值
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0)
led_out <= 1'b0;
else if(counter_flag == 1'b1 && stopFlag == 1'b0)
led_out <= ~ led_out;
else if(stopFlag == 1'b1) // 10次后让灯熄灭
led_out <= 1'b1;
else
led_out <= led_out;
end
// 设置ledOnCounter
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0)
ledOnCounter <= 5'b0;
else if(ledOnCounter == LEDON_COUNTER && counter_flag == 1'b1)
ledOnCounter <= 5'b0;
else if( counter_flag == 1'b1)
ledOnCounter <= ledOnCounter + 5'b1;
else
ledOnCounter <= ledOnCounter;
end
// 置位标志位
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n == 1'b0)
stopFlag <= 1'b0;
else if(ledOnCounter == LEDON_COUNTER-1 && counter_flag == 1'b1)
stopFlag <= 1'b1;
else
stopFlag <= stopFlag;
end
endmodule
- 板载FPGA 50MHz晶振,故一个时钟周期为 20 ns
- 要实现0.5s LED翻转一次则需计数25 x 10^6次(即:0~24_999_999)
3 仿真程序
`timescale 1 ns/ 1 ps
module tb_ledon_10times();
// test vector input registers
reg sys_clk;
reg sys_rst_n;
// wires
wire led_out;
initial begin
sys_clk = 1'b0;
sys_rst_n = 1'b0;
#20
sys_rst_n = 1'b1;
end
always #20 sys_clk = ~sys_clk;
// assign statements (if any)
ledon_10times
#(
.COUNTER_MAX (25'd24),
.LEDON_COUNTER (5'd19)
)
ledon_10times_init1
(
// port map - connection between master ports and signals/registers
.led_out(led_out),
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n)
);
endmodule
仿真波形
波形与设计的一致,仿真成功!