FPGA数字电子钟
将时间拆分为6个参数:
second_1 -> 秒个位
second_10 -> 秒十位
minute_1 -> 分个位
minute_10 -> 分十位
hour_1; -> 时个位
hour_10; -> 时十位
在异步复位的时候为上述六个参数赋初始值。
然后对50Mhz系统时钟进行计数,计数50M次(即为1s)。然后对六个参数的当前值做出判断,并在下一个clk做出改变。
当计满一秒,且秒的个位大于0时,——》秒的个位减1
当计满一秒,且秒的个位等于0,秒的十位大于0时,——》秒的十位减1,秒的个位变9
当计满一秒,且秒为00,并且分的个位大于0时,——》分的个位减1,秒由00变为59
当计满一秒,且秒为00,并且分的个位等于0,分的十位大于0时,——》分的十位减1,个位变为9,秒由00变为59
当计满一秒,且秒为00,分也为00,时的个位大于0时,——》时的个位减1,分由00变为59,秒也由00变为59
当计满一秒,且秒为00,分也为00,时的个位等于0,时的十位大于0时,——》时的十位减1,个位变9,分由00变为59,秒也由00变为59
当计满一秒,且时分秒为:00 00 00时,——》还原为预设值
仅当【suspend】状态值为1的时候才会对50Mhz系统时钟进行计数,为0时暂停计数,这样就实现了计数器的暂停。
CODE
module down_cnt(
clk,
rst,
suspend,
second_1,
second_10,
minute_1,
minute_10,
hour_1,
hour_10
);
input clk;
input rst;
input suspend; //当suspend为状态量,为0时计时暂停,为1时计时继续。
output reg [3:0] second_1; //秒个位
output reg [2:0] second_10;//秒十位
output reg [3:0] minute_1; //分个位
output reg [2:0] minute_10;//分十位
output reg [3:0] hour_1; //时个位
output reg [1:0] hour_10; //时十位
reg [31:0] cnt;//50M -> 1s (50M时钟进行50M次计数得到一秒,)
always@(posedge clk or negedge rst)
begin
if(!rst)//复位时设置倒计时初始值
begin
cnt <= 32'd0;
second_1 <= 4'd0;
second_10 <= 3'd0;
minute_1 <= 4'd1;
minute_10 <= 3'd0;
hour_1 <= 4'd0;
hour_10 <= 2'd0;
end
//当计满一秒,且秒的个位大于0时,——》秒的个位减1
else if(cnt == 32'd5000_0000 && second_1>4'd0)
begin
second_1 <= second_1 - 4'd1;
cnt <= 32'd0;
end
//当计满一秒,且秒的个位等于0,秒的十位大于0时,——》秒的十位减1,秒的个位变9
else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10>3'd0 )
begin
second_10 <= second_10 - 3'd1;
second_1 <= 4'd9;
cnt <= 32'd0;
end
//当计满一秒,且秒为00,并且分的个位大于0时,——》分的个位减1,秒由00变为59
else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1>4'd0 )
begin
minute_1 <= minute_1 - 4'd1;
second_10 <= 3'd5;
second_1 <= 4'd9;
cnt <= 32'd0;
end
//当计满一秒,且秒为00,并且分的个位等于0,分的十位大于0时,——》分的十位减1,个位变为9,秒由00变为59
else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1==4'd0 && minute_10 > 3'd0)
begin
minute_10 <= minute_10 - 3'd1;
minute_1 <= 4'd9;
second_10 <= 3'd5;
second_1 <= 4'd9;
cnt <= 32'd0;
end
//当计满一秒,且秒为00,分也为00,时的个位大于0时,——》时的个位减1,分由00变为59,秒也由00变为59
else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1==4'd0 && minute_10 ==3'd0 && hour_1 >4'd0)
begin
hour_1 <= hour_1 - 4'd1;
minute_10 <= 3'd5;
minute_1 <= 4'd9;
second_10 <= 3'd5;
second_1 <= 4'd9;
cnt <= 32'd0;
end
//当计满一秒,且秒为00,分也为00,时的个位等于0,时的十位大于0时,——》时的十位减1,个位变9,分由00变为59,秒也由00变为59
else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0&& minute_1==4'd0 && minute_10 ==3'd0 && hour_1 == 4'd0 && hour_10 > 2'd0 && hour_10< 2'd2 )
begin
hour_10 <= hour_10 - 2'd1;
hour_1 <= 4'd9;
minute_10 <= 3'd5;
minute_1 <= 4'd9;
second_10 <= 3'd5;
second_1 <= 4'd9;
cnt <= 32'd0;
end
//当计满一秒,且时分秒为:00 00 00时,——》还原为预设值
else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1==4'd0 && minute_10 ==3'd0 && hour_1 == 4'd0 && hour_10 == 2'd0 )
begin
hour_10 <= 2'd0;
hour_1 <= 4'd0;
minute_10 <= 3'd0;
minute_1 <= 4'd0;
second_10 <= 3'd0;
second_1 <= 4'd0;
cnt <= 32'd0;
end
else if(suspend == 1'b1)
begin
cnt <= cnt + 32'd1;
end
else
begin
cnt <= cnt;
end
end
endmodule
顶层CODE
使用六个数码管来显示六个时间参数,下为顶层文件。(数码管的驱动见:链接)
module top(
clk,
rst,
dig,
suspend,
dict
);
input clk;
input rst;
input suspend;
output [5:0] dig; //六个数码管片选
output [7:0] dict; //动态数码管段选
wire [23:0] set_data;//数码管显示的内容:4bit*6
down_cnt f1(
.clk(clk),
.rst(rst),
.suspend(suspend),
.second_1(set_data[3:0]),
.second_10(set_data[7:4]),
.minute_1(set_data[11:8]),
.minute_10(set_data[15:12]),
.hour_1(set_data[19:16]),
.hour_10(set_data[23:20])
);
dig8_6 f2(
.clk(clk),
.rst(rst),
.set_data(set_data),
.dig(dig),
.dict(dict)
);
endmodule
- 点赞
- 收藏
- 关注作者
评论(0)