赞
踩
目标:设计一个能显示时间和日期的万历时钟,用六个数码管通过按键切换显示时间你和日期,还具有按键加减调节时间和日期功能,日期具有平年或者闰年显示2月到底是28天还是29天,1,3,5,7,8,10,12月时有31天,4,6,9,11月时有30天。
本次设计用的是altera DE10-Lite FPGA开发板(用其他板子原理一样,只需要修改显示部分代码即可,因为altera DE10-Lite FPGA开发板管脚多,数码管的每一段都有一个管脚,不需要位选,只需把数据输到对应数码管即可)。
顶层RTL视图如下:
1、按键消抖模块
module key_filter
(
input wire sys_clk, input wire rst_n, input wire key_in,
output reg key_flag
);
parameter CNT_MAX=20'd99999;
reg [19:0] cnt_20ms;
always @(posedge sys_clk or negedge rst_n)
if (!rst_n)
cnt_20ms <= 20'd0;
else if (key_in)
cnt_20ms <= 20'd0;
else if (cnt_20ms==CNT_MAX)
cnt_20ms <= CNT_MAX;//保持
else
cnt_20ms <= cnt_20ms+20'd1;
always @(posedge sys_clk or negedge rst_n)
if (!rst_n)
key_flag <= 1'b0;
else if (cnt_20ms==(CNT_MAX-20'd1))
key_flag <= 1'b1;
else
key_flag <= 1'b0;
endmodule
2、时间和日期产生模块
3、数码管显示模块
因为本次用的开发板max10系列芯片的数码管每一段都会有一个管脚,所以不需要进行位选。
module seg_dynamic(
input wire key_en,
input wire sys_clk,
input wire rst_n,
input wire[7:0]hour ,
input wire[7:0]minute,
input wire[7:0]second,
input wire[13:0]year ,
input wire[7:0]mon,
input wire[7:0]day,
output reg[7:0] seg0,
output reg[7:0] seg1,
output reg[7:0] seg2,
output reg[7:0] seg3,
output reg[7:0] seg4,
output reg[7:0] seg5
);
wire [3:0] hour_h ,hour_l ;
wire [3:0] minute_h,minute_l;
wire [3:0] second_h,second_l;
assign hour_h = hour/10;
assign minute_h = minute/10;
assign second_h = second/10;
assign hour_l = hour%10;
assign minute_l = minute%10;
assign second_l = second%10;
wire [3:0] year_h ,year_l ;
wire [3:0] mon_h,mon_l;
wire [3:0] day_h,day_l;
assign year_h = (year%100)/10;
assign mon_h = mon/10;
assign day_h = day/10;
assign year_l = (year%100)%10;
assign mon_l = mon%10;
assign day_l = day%10;
always @(*)
if(!key_en)
begin
case(second_l)
4'd0 : seg0<=8'b1100_0000;
4'd1 : seg0<=8'b1111_1001;
4'd2 : seg0<=8'b1010_0100;
4'd3 : seg0<=8'b1011_0000;
4'd4 : seg0<=8'b1001_1001;
4'd5 : seg0<=8'b1001_0010;
4'd6 : seg0<=8'b1000_0010;
4'd7 : seg0<=8'b1111_1000;
4'd8 : seg0<=8'b1000_0000;
4'd9 : seg0<=8'b1001_0000;
4'd10 : seg0<=8'b1011_0111;
default :seg0<= 8'b1111_1111;
endcase
end
else
begin
case(day_l)
4'd0 : seg0<=8'b1100_0000;
4'd1 : seg0<=8'b1111_1001;
4'd2 : seg0<=8'b1010_0100;
4'd3 : seg0<=8'b1011_0000;
4'd4 : seg0<=8'b1001_1001;
4'd5 : seg0<=8'b1001_0010;
4'd6 : seg0<=8'b1000_0010;
4'd7 : seg0<=8'b1111_1000;
4'd8 : seg0<=8'b1000_0000;
4'd9 : seg0<=8'b1001_0000;
4'd10 : seg0<=8'b1011_0111;
default :seg0<= 8'b1111_1111;
endcase
end
always @(*)
if(!key_en)
begin
case(second_h)
4'd0 : seg1<=8'b1100_0000;
4'd1 : seg1<=8'b1111_1001;
4'd2 : seg1<=8'b1010_0100;
4'd3 : seg1<=8'b1011_0000;
4'd4 : seg1<=8'b1001_1001;
4'd5 : seg1<=8'b1001_0010;
4'd6 : seg1<=8'b1000_0010;
4'd7 : seg1<=8'b1111_1000;
4'd8 : seg1<=8'b1000_0000;
4'd9 : seg1<=8'b1001_0000;
4'd10 : seg1<=8'b1011_0111;
default :seg1<= 8'b1111_1111;
endcase
end
else
begin
case(day_h)
4'd0 : seg1<=8'b1100_0000;
4'd1 : seg1<=8'b1111_1001;
4'd2 : seg1<=8'b1010_0100;
4'd3 : seg1<=8'b1011_0000;
4'd4 : seg1<=8'b1001_1001;
4'd5 : seg1<=8'b1001_0010;
4'd6 : seg1<=8'b1000_0010;
4'd7 : seg1<=8'b1111_1000;
4'd8 : seg1<=8'b1000_0000;
4'd9 : seg1<=8'b1001_0000;
4'd10 : seg1<=8'b1011_0111;
default :seg1<= 8'b1111_1111;
endcase
end
always @(*)
if(!key_en)
begin
case(minute_l)
4'd0 : seg2<=8'b1100_0000;
4'd1 : seg2<=8'b1111_1001;
4'd2 : seg2<=8'b1010_0100;
4'd3 : seg2<=8'b1011_0000;
4'd4 : seg2<=8'b1001_1001;
4'd5 : seg2<=8'b1001_0010;
4'd6 : seg2<=8'b1000_0010;
4'd7 : seg2<=8'b1111_1000;
4'd8 : seg2<=8'b1000_0000;
4'd9 : seg2<=8'b1001_0000;
4'd10 : seg2<=8'b1011_0111;
default :seg2<= 8'b1111_1111;
endcase
end
else
begin
case(mon_l)
4'd0 : seg2<=8'b1100_0000;
4'd1 : seg2<=8'b1111_1001;
4'd2 : seg2<=8'b1010_0100;
4'd3 : seg2<=8'b1011_0000;
4'd4 : seg2<=8'b1001_1001;
4'd5 : seg2<=8'b1001_0010;
4'd6 : seg2<=8'b1000_0010;
4'd7 : seg2<=8'b1111_1000;
4'd8 : seg2<=8'b1000_0000;
4'd9 : seg2<=8'b1001_0000;
4'd10 : seg2<=8'b1011_0111;
default :seg2<= 8'b1111_1111;
endcase
end
always @(*)
if(!key_en)
begin
case(minute_h)
4'd0 : seg3<=8'b1100_0000;
4'd1 : seg3<=8'b1111_1001;
4'd2 : seg3<=8'b1010_0100;
4'd3 : seg3<=8'b1011_0000;
4'd4 : seg3<=8'b1001_1001;
4'd5 : seg3<=8'b1001_0010;
4'd6 : seg3<=8'b1000_0010;
4'd7 : seg3<=8'b1111_1000;
4'd8 : seg3<=8'b1000_0000;
4'd9 : seg3<=8'b1001_0000;
4'd10 : seg3<=8'b1011_0111;
default :seg3<= 8'b1111_1111;
endcase
end
else
begin
case(mon_h)
4'd0 : seg3<=8'b1100_0000;
4'd1 : seg3<=8'b1111_1001;
4'd2 : seg3<=8'b1010_0100;
4'd3 : seg3<=8'b1011_0000;
4'd4 : seg3<=8'b1001_1001;
4'd5 : seg3<=8'b1001_0010;
4'd6 : seg3<=8'b1000_0010;
4'd7 : seg3<=8'b1111_1000;
4'd8 : seg3<=8'b1000_0000;
4'd9 : seg3<=8'b1001_0000;
4'd10 : seg3<=8'b1011_0111;
default :seg3<= 8'b1111_1111;
endcase
end
always @(*)
if(!key_en)
begin
case(hour_l)
4'd0 : seg4<=8'b1100_0000;
4'd1 : seg4<=8'b1111_1001;
4'd2 : seg4<=8'b1010_0100;
4'd3 : seg4<=8'b1011_0000;
4'd4 : seg4<=8'b1001_1001;
4'd5 : seg4<=8'b1001_0010;
4'd6 : seg4<=8'b1000_0010;
4'd7 : seg4<=8'b1111_1000;
4'd8 : seg4<=8'b1000_0000;
4'd9 : seg4<=8'b1001_0000;
4'd10 : seg4<=8'b1011_0111;
default :seg4<= 8'b1111_1111;
endcase
end
else
begin
case(year_l)
4'd0 : seg4<=8'b1100_0000;
4'd1 : seg4<=8'b1111_1001;
4'd2 : seg4<=8'b1010_0100;
4'd3 : seg4<=8'b1011_0000;
4'd4 : seg4<=8'b1001_1001;
4'd5 : seg4<=8'b1001_0010;
4'd6 : seg4<=8'b1000_0010;
4'd7 : seg4<=8'b1111_1000;
4'd8 : seg4<=8'b1000_0000;
4'd9 : seg4<=8'b1001_0000;
4'd10 : seg4<=8'b1011_0111;
default :seg4<= 8'b1111_1111;
endcase
end
always @(*)
if(!key_en)
begin
case(hour_h)
4'd0 : seg5<=8'b1100_0000;
4'd1 : seg5<=8'b1111_1001;
4'd2 : seg5<=8'b1010_0100;
4'd3 : seg5<=8'b1011_0000;
4'd4 : seg5<=8'b1001_1001;
4'd5 : seg5<=8'b1001_0010;
4'd6 : seg5<=8'b1000_0010;
4'd7 : seg5<=8'b1111_1000;
4'd8 : seg5<=8'b1000_0000;
4'd9 : seg5<=8'b1001_0000;
4'd10 : seg5<=8'b1011_0111;
default :seg5<= 8'b1111_1111;
endcase
end
else
begin
case(year_h)
4'd0 : seg5<=8'b1100_0000;
4'd1 : seg5<=8'b1111_1001;
4'd2 : seg5<=8'b1010_0100;
4'd3 : seg5<=8'b1011_0000;
4'd4 : seg5<=8'b1001_1001;
4'd5 : seg5<=8'b1001_0010;
4'd6 : seg5<=8'b1000_0010;
4'd7 : seg5<=8'b1111_1000;
4'd8 : seg5<=8'b1000_0000;
4'd9 : seg5<=8'b1001_0000;
4'd10 : seg5<=8'b1011_0111;
default :seg5<= 8'b1111_1111;
endcase
end
endmodule
4、顶层模块
module time_top(
input wire sys_clk,
input wire rst_n,
input wire stop,//暂停
input wire sw,//校时模式
input wire key_en,
input wire key_add,//时钟数值加
input wire key_min,//时钟数值减
input wire key_cho,//选择
output wire[7:0] seg0,
output wire[7:0] seg1,
output wire[7:0] seg2,
output wire[7:0] seg3,
output wire[7:0] seg4,
output wire[7:0] seg5
);
//wire clk_1k;
wire key1,key2,key3;
wire [7:0] hour;
wire [7:0] minute;
wire [7:0] second;
wire [7:0] day;
wire [13:0] year;
wire [7:0] mon;
seg_dynamic seg_dynamic_inst(
.sys_clk (sys_clk),
.key_en(key_en),
.rst_n (rst_n),
.hour (hour ),
.minute (minute),
.second (second),
.day (day),
.mon (mon),
.year (year),
.seg0(seg0),
.seg1(seg1),
.seg2(seg2),
.seg3(seg3),
.seg4(seg4),
.seg5(seg5)
);
key_filter filter_add(
.sys_clk (sys_clk),
.rst_n (rst_n),
.key_in (~key_add),
.key_flag (key1)
);
key_filter filter_min(
.sys_clk (sys_clk),
.rst_n (rst_n),
.key_in (~key_min),
.key_flag (key2)
);
key_filter filter_cho(
.sys_clk (sys_clk),
.rst_n (rst_n),
.key_in (~key_cho),
.key_flag (key3)
);
data_time data_time_inst
(
.sys_clk (sys_clk),
.rst_n(rst_n),
.stop (stop),
.sw (sw),
.key_add(key1),
.key_min(key2),
.key_cho(key3),
.day (day),
.mon (mon),
.year (year),
.hour (hour ),
.minute (minute),
.second (second)
);
endmodule
5、test bench仿真
`timescale 1ns/1ns
module tb_time_top();
reg sys_clk;
reg rst_n;
reg stop;
reg sw;
wire key_add;
wire key_min;
wire key_cho;
wire [7:0]seg0;
wire [7:0]seg1;
wire [7:0]seg2;
wire [7:0]seg3;
wire [7:0]seg4;
wire [7:0]seg5;
initial
begin
stop<=1'b0;
sw<=1'b0;
sys_clk<=1'b1;
rst_n<=1'b0;
#20
rst_n<=1'b1;
end
always #10 sys_clk =~sys_clk;
defparam time_top_inst.data_time_inst.CNT_MAX=19;
time_top time_top_inst
(
.sys_clk (sys_clk),
.rst_n(rst_n),
.stop (stop),
.sw (sw),
.key_add(key_add),
.key_min(key_min),
.key_cho(key_cho),
.seg0(seg0),
.seg1(seg1),
.seg2(seg2),
.seg3(seg3),
.seg4(seg4),
.seg5(seg5)
);
endmodule
6、结果展示
2021年是平年,2月有28天,仿真图可以看出放计时满24小时时,day_flag标识位拉高,天数加一,跳到3月1号
四月只有30天,仿真图可以看出放计时满24小时时,day_flag标识位拉高,天数加一,跳到5月1号
1月有31天,仿真图可以看出放计时满24小时时,day_flag标识位拉高,天数加一,跳到2月1号
时间显示
日期显示
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。