当前位置:   article > 正文

Verilog万年历时钟_verilog实现万年历

verilog实现万年历

目标:设计一个能显示时间和日期的万历时钟,用六个数码管通过按键切换显示时间你和日期,还具有按键加减调节时间和日期功能,日期具有平年或者闰年显示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号

 

 时间显示

 日期显示

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/411075
推荐阅读
相关标签
  

闽ICP备14008679号