基于FPGA的电子万年日历verilog实现 vivado

设计任务

•      用4个七段数码管显示MM. DD日历计时

(注意:基于FPGA采用verilogHDL语言编程。测试时建议用1Hz左右时钟,但给出24hour时钟编程代码。允许日期全按30天计)。

•      完整显示YYYY.MM.DD公历日历

•      清零显示、暂停显示。

•      年月日可键控调整逐一增减。

•      按键消抖。

•      备忘。

设计环境

EGO1开发板是一款便携式的混合信号实验平台,主要面向教育用途。它基于赛灵思的Artix-7 FPGA,具体型号为XC7A35T-1CSG324C,具有高容量和高性能,适用于复杂的数字逻辑设计。EGO1支持在FPGA内实现MicroBlaze处理器系统,从而能够进行SoC(系统级芯片)设计  。

设计方案及原理分析

确定五个模块,分别是顶层模块,分频模块,按键消抖模块,数码管显示和控制模块。

如果要将所有的功能模块连接成一个完整系统,则需要一个模块将所有的子模块连接起来,这一模块被称为顶层模块。在顶层模块中,我们的输入信号为板载时钟信号clk,复位信号rst,状态选择信号select和select_clock。数码管显示信号seg,数码管位选信号an,用于闹钟的提醒的led信号,以及调时所需要的inc增信号和de减信号。我们将按钮的信号均传入按键消抖模块,时钟信号传入分频模块,inc,de,select,select_clock等信号传入控制模块,将数码管显示信号传入数码管模块。

对于分频模块,把输入的时钟作为计数脉冲,由于计数器的输出端口是按一定规律输出脉冲的,所以对不同的端口输出的信号脉冲,就可以看作是对输入信号的“分频”。这里我们的有按键消抖的时钟,数码管显示的时钟以及日历正常行进的时钟。所以针对不同的功能我们进行了不同时钟的分频。

对于按键消抖模块,我们首先介绍按键消抖原理。按键作为基本的人机输入接口,由于其机械特性,在按键按下或松开的时候,都是会有抖动的。按键消抖的方式有很多,这里我们采用的方法是将按键接受到的信号分别时移一段时间,得到3个信号,当这三个信号均相同时,我们认为按键已经按下。我们设定按键消抖的时钟频率大概为100Hz,时间大概为20ms左右。当3个信号均在稳定期时我们认定按键已经成功按下,并输出1。

为了避开状态冲突的问题,这里我设定,当日历状态不为0时,闹钟按键是无效的,即如果正在调日历时,是无法进入闹钟的状态的。当日历状态为0时,才可以使用闹钟功能,按下闹钟选择按键后,可以查看当前设置的闹钟,多次按下按键可以设置闹钟的时间。这里为了方便,无论闹钟在哪一个状态,只要按下日历状态选择键,闹钟的状态和日历的状态都会变为0,显示正常的日历。但一直按闹钟的状态选择并不会回到日历的状态,而是在闹钟的状态不断循环。

代码

top.v

module dzmb_top(
    input         clk,
    input         rst,
    input         select,   // status select
    input         inc,
    input         de,
    output [7:0]  seg_left,
    output [7:0]  seg_right,
    output [7:0]  an,    // posion select
    output led,
    input  select_clock
);


wire [31:0] disp_time; // display time
wire [3:0]  week;   // week 1~7
wire [31:0] clock; // clock


wire [7:0]  seg_data; 
wire divclk; // used to key debounce
wire [3:0] selected_item;
wire [2:0] clock_state;

wire btn_select; // select button
wire btn_inc; // inc button
wire btn_de; // dec button
wire btn_clock; // clock button

assign seg_left  = seg_data;
assign seg_right = seg_data;

divider u2(
    .clk(clk),    
    .reset(rst),    
    .clk_out(divclk) 
    ) ;

// key debounce
key_debounce u1_key_debounce (
    .btn_clk(divclk),
    .rst(rst),
    .btn_in(inc),
    .btn_out(btn_inc)
);

// key debounce
key_debounce u2_key_debounce (
    .btn_clk(divclk),
    .rst(rst),
    .btn_in(select),
    .btn_out(btn_select)
);

// key debounce
key_debounce u3_key_debounce (
    .btn_clk(divclk),
    .rst(rst),
    .btn_in(de),
    .btn_out(btn_de)
);

// key debounce
key_debounce u4_key_debounce (
    .btn_clk(divclk),
    .rst(rst),
    .btn_in(select_clock),
    .btn_out(btn_clock)
);

// count control
count_ctrl u_count_ctrl(
    .clk(clk),     
    .rst(rst),     
    .disp_time(disp_time),
    .select(btn_select),
    .inc(btn_inc),
    .selected_data(selected_item),
    .week(week),
    .clock(clock),
    .de(btn_de),
    .select_clock(btn_clock),
    .clock_state(clock_state)
);


// smg
smg u_smg(
    .clk(clk),     
    .rst(rst),     
    .dispdata(disp_time),
    .point(8'b00010100),
    .seg(seg_data),     
    .an(an),
    .selected_item(selected_item),
    .week(week),
    .clock(clock),
    .led(led),
    .clock_state(clock_state)
);    

endmodule

smg.v

module smg(
    input             clk,
    input             rst,
    input      [31:0] dispdata,  //display data
    input      [ 7:0] point,     //point position
    output reg [ 7:0] seg,
    output reg [ 7:0] an,
    input [3:0] selected_item,
    input [3:0] week,
    input [31:0] clock,
    output reg led,
    output [2:0] clock_state
	);

reg [16:0] divclk_cnt;
reg        divclk;
reg [3:0]  disp_dat;    //data to display
reg [2:0]  disp_bit;    //bit to display
reg        dot_disp ;   // dot display
reg [3:0]  week_d;
parameter maxcnt = 16'd50000;

always@(posedge clk or negedge rst)
begin
    if(rst)
    begin
        divclk     <= 1'b0;
        divclk_cnt <= 17'd0;
    end
    else if(divclk_cnt == maxcnt)
    begin
        divclk     <= ~divclk;
        divclk_cnt <= 17'd0;
    end
    else
    begin
        divclk_cnt = divclk_cnt + 1'b1;
    end
end
always@(posedge divclk or negedge rst)
begin
    // judge if the led should be on
    if (dispdata == clock)
    begin
        led = 1'b1;
    end

    // judge if the led should be off
    if (dispdata == clock+1'b1)
    begin
        led = 1'b0;
    end    
    if(rst)
    begin
        an       <= 8'b00_000_000;
        disp_bit <= 3'd0;
        dot_disp <= 1'b0;  //reset dot display
        week_d   <= 4'd1;
        led     <= 1'b0;
    end
    else
    begin
        if(disp_bit > 3'd7)
            disp_bit <= 3'd0;
        else
        begin
            disp_bit <= disp_bit + 1'b1;
            case(disp_bit)
                3'h0:
                begin
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd7)
                    begin
                        disp_dat <= dispdata[3:0];
                        dot_disp <= point[0];
                    end
                    else if (selected_item == 4'd1&&clock_state==3'd0)
                    begin
                        disp_dat <= week[3:0];
                        dot_disp <= 1'b0;
                    end
                    
                    if (clock_state == 3'd1||clock_state == 3'd7)
                    begin
                        disp_dat <= clock[3:0];
                        dot_disp <= point[0];
                    end

                    // day low
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd1||selected_item == 4'd7||clock_state == 3'd1||clock_state == 3'd7)
                    begin
                        an <= 8'b00000001;
                    end
                    else
                    begin
                        an <= 8'b00000000;
                    end
                end
                3'h1:
                begin
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd7)
                    begin
                        disp_dat <= dispdata[7:4];
                        dot_disp <= point[1];
                    end
                    if ((clock_state == 3'd1||clock_state == 3'd7)&&selected_item == 4'd0)
                    begin
                        disp_dat <= clock[7:4];
                        dot_disp <= point[0];
                    end
                    // day high
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd7||clock_state == 3'd1||clock_state == 3'd7)
                    begin
                        an <= 8'b00000010;
                    end
                    else
                    begin
                        an <= 8'b00000000;
                    end

                end
                3'h2:
                begin
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd6)
                    begin
                        disp_dat <= dispdata[11:8];
                        dot_disp <= point[2];
                    end
                    if ((clock_state == 3'd6||clock_state == 3'd1)&&selected_item == 4'd0)
                    begin
                        disp_dat <= clock[11:8];
                        dot_disp <= point[0];
                    end
                    // month low
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd6||clock_state == 3'd6||clock_state == 3'd1)
                    begin
                        an <= 8'b00000100;
                    end
                    else
                    begin
                        an <= 8'b00000000;
                    end
                end
                3'h3:
                begin
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd6)
                    begin
                        disp_dat <= dispdata[15:12];
                        dot_disp <= point[3];
                    end
                    if ((clock_state == 3'd6||clock_state == 3'd1)&&selected_item == 4'd0)
                    begin
                        disp_dat <= clock[15:12];
                        dot_disp <= point[0];
                    end
                    //month high
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd6||clock_state == 3'd6||clock_state == 3'd1)    
                    begin
                        an <= 8'b00001000;
                    end
                    else
                    begin
                        an <= 8'b00000000;
                    end

                end
                3'h4:
                begin
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd5)
                    begin
                        disp_dat <= dispdata[19:16];
                        dot_disp <= point[4];
                    end
                    if ((clock_state == 3'd5||clock_state == 3'd1)&&selected_item == 4'd0)
                    begin
                        disp_dat <= clock[19:16];
                        dot_disp <= point[0];
                    end
                    //year1
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd5||clock_state == 3'd5||clock_state == 3'd1)
                    begin
                        an <= 8'b00010000;
                    end
                    else
                    begin
                        an <= 8'b00000000;
                    end
                end
                3'h5:
                begin
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd4)
                    begin
                        disp_dat <= dispdata[23:20];
                        dot_disp <= point[5];
                    end
                    if ((clock_state == 3'd4||clock_state==3'd1)&&selected_item == 4'd0)
                    begin
                        disp_dat <= clock[23:20];
                        dot_disp <= point[0];
                    end
                    //year2
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd4||clock_state == 3'd4||clock_state == 3'd1)
                    begin
                        an <= 8'b00100000;
                    end
                    else
                    begin
                        an <= 8'b00000000;
                    end
                end
                3'h6:
                begin
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd3)
                    begin
                        disp_dat <= dispdata[27:24];
                        dot_disp <= point[6];
                    end
                    if ((clock_state == 3'd1||clock_state == 3'd3)&&selected_item == 4'd0)
                    begin
                        disp_dat <= clock[27:24];
                        dot_disp <= point[0];
                    end
                    //year3
                    if ((selected_item == 4'd0&&clock_state==3'd0)|selected_item == 4'd3||clock_state == 3'd3||clock_state == 3'd1)
                    begin
                        an <= 8'b01000000;
                    end
                    else
                    begin
                        an <= 8'b00000000;
                    end
                end
                3'h7:
                begin
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd2)
                    begin
                        disp_dat <= dispdata[31:28];
                        dot_disp <= point[7];
                    end
                    if ((clock_state == 3'd1||clock_state == 3'd2)&&selected_item == 4'd0)
                    begin
                        disp_dat <= clock[31:28];
                        dot_disp <= point[0];
                    end
                    //year4
                    if ((selected_item == 4'd0&&clock_state==3'd0)||selected_item == 4'd2||clock_state == 3'd2||clock_state == 3'd1)
                    begin
                        an <= 8'b10000000;
                    end
                    else
                    begin
                        an <= 8'b00000000;
                    end
                end
                default: an <= 8'b00000_000;
            endcase
        end
    end
end
always@(disp_dat)
begin
    case(disp_dat)
        4'h0: seg = {dot_disp,7'b0111111};
        4'h1: seg = {dot_disp,7'b0000110};
        4'h2: seg = {dot_disp,7'b1011011};
        4'h3: seg = {dot_disp,7'b1001111};
        4'h4: seg = {dot_disp,7'b1100110};
        4'h5: seg = {dot_disp,7'b1101101};
        4'h6: seg = {dot_disp,7'b1111101};
        4'h7: seg = {dot_disp,7'b0000111};
        4'h8: seg = {dot_disp,7'b1111111};
        4'h9: seg = {dot_disp,7'b1101111};
        default: seg = 8'h00;
    endcase
end
endmodule

key.v

module key_debounce (
input btn_clk, //50Hz clock
input rst,
input btn_in,
output btn_out
);
reg btn0;
reg btn1;
reg btn2;
assign btn_out = (~btn0 & btn1 & btn2)|(btn0 & btn1 & btn2)|(btn0 & btn1 & ~btn2);
always@ (posedge btn_clk or negedge rst)
begin
    if(rst)
    begin
        btn0 <= 1'b0;
        btn1 <= 1'b0;
        btn2 <= 1'b0;
    end
    else
    begin
        btn0 <= btn_in;
        btn1 <= btn0;
        btn2 <= btn1;
    end
end
endmodule

divide.v

module divider (
    input wire clk,     // orginal clock(100MHz)
    input wire reset,   // reset signal
    output reg clk_out  // ouput clock(50Hz)
);

reg [24:0] counter; // 27 bits register
localparam DIVISOR = 500_000; // 500,000 = 50,000,000 / 100 -> 100Hz

always @(posedge clk or posedge reset) begin
    if (reset) begin
        counter <= 25'b0;
        clk_out <= 1'b0;
    end else begin
        if (counter == DIVISOR - 1) begin
            clk_out <= ~clk_out;
            counter <= 25'b0;
        end else begin
            counter <= counter + 1'b1;
        end
    end
end

endmodule

control.v

module count_ctrl(
    input         clk,
    input         rst,
    input         select,      // select signal
    input         inc,         // increase signal
    input         de,          // decrease signal
    output [31:0] disp_time,    // display time
    output [3:0]  selected_data,     // segment data
    output [3:0]  week,
    output [31:0] clock,
    input   select_clock,      // select clock
    output  [2:0] clock_state         // clock state
);
// divider
reg [25:0] divclk_cnt;
// 24 hours
// reg [31:0] divclk;
reg        divclk;
// time
reg [3:0]  day_l;
reg [3:0]  day_h;    
reg [3:0]  month_l;
reg [3:0]  month_h;
reg [3:0]  year_1;
reg [3:0]  year_2;
reg [3:0]  year_3;
reg [3:0]  year_4;

reg prev_select;
reg perv_clock;
reg [3:0] selected_item;
reg [2:0] clock_s;

reg [3:0] week_c;
// clock
reg [3:0] clock_day_l;
reg [3:0] clock_day_h;
reg [3:0] clock_month_l;
reg [3:0] clock_month_h;
reg [3:0] clock_year_1;
reg [3:0] clock_year_2;
reg [3:0] clock_year_3;
reg [3:0] clock_year_4;


assign week = week_c;
assign clock = {clock_year_4,clock_year_3,clock_year_2,clock_year_1,clock_month_h,clock_month_l,clock_day_h,clock_day_l};

assign disp_time = {year_4,year_3,year_2,year_1,month_h,month_l,day_h,day_l};
assign selected_data = selected_item;
assign clock_state = clock_s;

// BCD to binary conversion using shift and add
wire [15:0] year = (year_4 << 12) + (year_3 << 8) + (year_2 << 4) + year_1;
wire [31:0] days = (year_4<<28) + (year_3<<24) + (year_2<<20) + (year_1<<16) + (month_h<<12) + (month_l<<8) + (day_h<<4) + day_l;

// is leap year
wire leap_year = (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);

always @(posedge clk or negedge rst)
begin
    prev_select <= select;
    if (select && !prev_select) // detect rising edge of select
    begin
        if (selected_item == 4'd7)
            selected_item <= 4'd0;
        else
            selected_item <= selected_item + 1'b1;

        if (clock_s!=3'd0)
        begin
            clock_s <= 3'd0;
            selected_item <= 4'd0;
        end
    end

    perv_clock<= select_clock;
    if (select_clock && !perv_clock && selected_item==0) // detect rising edge of select
    begin
        if (clock_s == 3'd7)
            clock_s <= 3'd1;
        else
            clock_s <= clock_s + 1'b1;
    end


    if (rst)
    begin
        divclk     <= 1'b0;
        divclk_cnt <= 24'd0;
        selected_item <= 4'd0; 
        clock_s <= 3'd0;
    end
    else if (divclk_cnt == 26'd50_000_000 - 1'b1)
    //use 24 hours
    //else if (divclk_cnt == 32'd4320_000_000_000 - 1'b1) 
    begin 
        divclk     <= ~divclk;
        divclk_cnt <= 24'd0;
    end
    else
    begin
        divclk_cnt <= divclk_cnt + 1'b1;
    end
end

always @(posedge divclk or negedge rst)
begin
    if (rst)
    begin
        day_l <= 4'd1;
        day_h <= 4'd0;
        month_l  <= 4'd1;
        month_h  <= 4'd0;
        year_1  <= 4'd0;
        year_2  <= 4'd0;
        year_3  <= 4'd0;
        year_4  <= 4'd0;
        clock_day_l <= 4'd1;
        clock_day_h <= 4'd0;
        clock_month_l  <= 4'd2;
        clock_month_h  <= 4'd0;
        clock_year_1  <= 4'd0;
        clock_year_2  <= 4'd0;
        clock_year_3  <= 4'd0;
        clock_year_4  <= 4'd0;
        week_c <= 4'd1;
    end
    else if(clock_s==0)
    begin
        case (selected_item)
                4'd0://runing - look year-month-day
                begin
                    if (day_l == 4'd9)
                    begin
                        day_l <= 4'd0;
                        day_h <= day_h + 1'b1;
                    end
                    else
                    begin
                        day_l <= day_l + 1'b1;
                    end

                    // 31-days
                    if (day_h == 4'd3 && day_l == 4'd1 && (({month_h, month_l} == 8'd1) || ({month_h, month_l} == 8'd3) || ({month_h, month_l} == 8'd5) || ({month_h, month_l} == 8'd7) || ({month_h, month_l} == 8'd8) || (month_h == 4'd1 && month_l == 4'd0) || (month_h == 4'd1 && month_l == 4'd2)))
                    begin
                        day_h <= 4'd0;
                        day_l <= 4'd1;
                        month_l <= month_l + 1'b1;
                    end
                    else if (day_h == 4'd2 && day_l == 4'd8 && ({month_h, month_l} == 8'd2) && !leap_year)//28-days
                    begin
                        day_h <= 4'd0;
                        day_l <= 4'd1;
                        month_l <= month_l + 1'b1;
                    end
                    else if (day_h == 4'd2 && day_l == 4'd9 && ({month_h, month_l} == 8'd2) && leap_year)//29-days
                    begin
                        day_h <= 4'd0;
                        day_l <= 4'd1;
                        month_l <= month_l + 1'b1;
                    end
                    else if (day_h == 4'd3 && day_l == 4'd0 && (({month_h, month_l} == 8'd2) || ({month_h, month_l} == 8'd4) || ({month_h, month_l} == 8'd6) || ({month_h, month_l} == 8'd9) || (month_h == 4'd1 && month_l == 4'd1)))//30-days
                    begin
                        day_h <= 4'd0;
                        day_l <= 4'd1;
                        month_l <= month_l + 1'b1;
                    end
                    // month overflow
                    if (month_l == 4'd9 && day_h == 4'd3 && day_l == 4'd0)
                    begin
                        month_l <= 4'd0;
                        month_h <= month_h + 1'b1;
                    end
                    // 12-month 
                    if (month_h == 4'd1 && month_l == 4'd2)
                    begin
                        month_l <= 4'd1;
                        month_h <= 4'd0;
                        year_1 <= year_1 + 1'b1;
                    end

                    // year overflow
                    if (year_1 == 4'd9)
                    begin
                        year_1 <= 4'd0;
                        year_2 <= year_2 + 1'b1;
                    end

                    if (year_2 == 4'd9 && year_1 == 4'd9)
                    begin
                        year_2 <= 4'd0;
                        year_1 <= 4'd0;
                        year_3 <= year_3 + 1'b1;
                    end

                    if (year_3 == 4'd9 && year_2 == 4'd9 && year_1 == 4'd9)
                    begin
                        year_3 <= 4'd0;
                        year_2 <= 4'd0;
                        year_1 <= 4'd0;
                        year_4 <= year_4 + 1'b1;
                    end

                    if (year_4 == 4'd9 && year_3 == 4'd9 && year_2 == 4'd9 && year_1 == 4'd9)
                    begin
                        year_4 <= 4'd0;
                        year_3 <= 4'd0;
                        year_2 <= 4'd0;
                        year_1 <= 4'd0;
                    end
                end
                4'd1:// runing -look week
                begin
                    if (day_l == 4'd9)
                    begin
                        day_l <= 4'd0;
                        day_h <= day_h + 1'b1;
                    end
                    else
                    begin
                        day_l <= day_l + 1'b1;
                    end

                    // 31-days
                    if (day_h == 4'd3 && day_l == 4'd1 && (({month_h, month_l} == 8'd1) || ({month_h, month_l} == 8'd3) || ({month_h, month_l} == 8'd5) || ({month_h, month_l} == 8'd7) || ({month_h, month_l} == 8'd8) || (month_h == 4'd1 && month_l == 4'd0) || (month_h == 4'd1 && month_l == 4'd2)))
                    begin
                        day_h <= 4'd0;
                        day_l <= 4'd1;
                        month_l <= month_l + 1'b1;
                    end
                    else if (day_h == 4'd2 && day_l == 4'd8 && ({month_h, month_l} == 8'd2) && !leap_year)//28-days
                    begin
                        day_h <= 4'd0;
                        day_l <= 4'd1;
                        month_l <= month_l + 1'b1;
                    end
                    else if (day_h == 4'd2 && day_l == 4'd9 && ({month_h, month_l} == 8'd2) && leap_year)//29-days
                    begin
                        day_h <= 4'd0;
                        day_l <= 4'd1;
                        month_l <= month_l + 1'b1;
                    end
                    else if (day_h == 4'd3 && day_l == 4'd0 && (({month_h, month_l} == 8'd2) || ({month_h, month_l} == 8'd4) || ({month_h, month_l} == 8'd6) || ({month_h, month_l} == 8'd9) || (month_h == 4'd1 && month_l == 4'd1)))//30-days
                    begin
                        day_h <= 4'd0;
                        day_l <= 4'd1;
                        month_l <= month_l + 1'b1;
                    end
                    // month overflow
                    if (month_l == 4'd9 && day_h == 4'd3 && day_l == 4'd0)
                    begin
                        month_l <= 4'd0;
                        month_h <= month_h + 1'b1;
                    end
                    // 12-month 
                    if (month_h == 4'd1 && month_l == 4'd2)
                    begin
                        month_l <= 4'd1;
                        month_h <= 4'd0;
                        year_1 <= year_1 + 1'b1;
                    end

                    // year overflow
                    if (year_1 == 4'd9)
                    begin
                        year_1 <= 4'd0;
                        year_2 <= year_2 + 1'b1;
                    end

                    if (year_2 == 4'd9 && year_1 == 4'd9)
                    begin
                        year_2 <= 4'd0;
                        year_1 <= 4'd0;
                        year_3 <= year_3 + 1'b1;
                    end

                    if (year_3 == 4'd9 && year_2 == 4'd9 && year_1 == 4'd9)
                    begin
                        year_3 <= 4'd0;
                        year_2 <= 4'd0;
                        year_1 <= 4'd0;
                        year_4 <= year_4 + 1'b1;
                    end

                    if (year_4 == 4'd9 && year_3 == 4'd9 && year_2 == 4'd9 && year_1 == 4'd9)
                    begin
                        year_4 <= 4'd0;
                        year_3 <= 4'd0;
                        year_2 <= 4'd0;
                        year_1 <= 4'd0;
                    end
                    // week
                    week_c <=  days % 7 + 1;
                end
                4'd2: // change year4
                begin
                    if (inc) // inc punch -> year4
                    begin
                        if (year_4 == 4'd9)
                        begin
                            year_4 <= 4'd0;
                        end
                        else
                        begin
                            year_4 <= year_4 + 1'b1;
                        end
                        if (de)
                        begin
                            if (year_4 == 4'd0)
                            begin
                                year_4 <= 4'd9;
                            end
                            else
                            begin
                                year_4 <= year_4 - 1'b1;
                            end
                        end
                    end    
                    if (de) 
                    begin
                        if (year_4 == 4'd0)
                        begin
                            year_4 <= 4'd9;
                        end
                        else
                        begin
                            year_4 <= year_4 - 1'b1;
                        end
                    end  
                end
                4'd3: // change year3
                begin
                    if (inc) // inc punch -> year3
                    begin
                        if (year_3 == 4'd9)
                        begin
                            year_3 <= 4'd0;
                        end
                        else
                        begin
                            year_3 <= year_3 + 1'b1;
                        end
                        if (de)
                        begin
                            if (year_3 == 4'd0)
                            begin
                                year_3 <= 4'd9;
                            end
                            else
                            begin
                                year_3 <= year_3 - 1'b1;
                            end
                        end
                    end
                    if (de)
                    begin
                        if (year_3 == 4'd0)
                        begin
                            year_3 <= 4'd9;
                        end
                        else
                        begin
                            year_3 <= year_3 - 1'b1;
                        end
                    end
                end
                4'd4: // change year2
                begin
                    if (inc) // inc punch -> year2
                    begin
                        if (year_2 == 4'd9)
                        begin
                            year_2 <= 4'd0;
                        end
                        else
                        begin
                            year_2 <= year_2 + 1'b1;
                        end
                    end
                    if (de)
                    begin
                        if (year_2 == 4'd0)
                        begin
                            year_2 <= 4'd9;
                        end
                        else
                        begin
                            year_2 <= year_2 - 1'b1;
                        end
                    end
                end
                4'd5: // change year1
                begin
                    if (inc) // inc punch -> year1
                    begin
                        if (year_1 == 4'd9)
                        begin
                            year_1 <= 4'd0;
                        end
                        else
                        begin
                            year_1 <= year_1 + 1'b1;
                        end
                    end
                    if (de)
                    begin
                        if (year_1 == 4'd0)
                        begin
                            year_1 <= 4'd9;
                        end
                        else
                        begin
                            year_1 <= year_1 - 1'b1;
                        end
                    end
                end
                4'd6: // change month
                begin
                    if (inc) // inc punch -> month
                    begin
                        if (month_l == 4'd9)
                        begin
                            month_l <= 4'd0;
                            month_h <= month_h + 1'b1;
                        end 
                        else if (month_h == 4'd1 && month_l == 4'd2)
                        begin
                            month_l <= 4'd1;
                            month_h <= 4'd0;
                        end
                        else
                        begin
                             month_l <=  month_l + 4'd1;
                        end
                    end
                    if (de)
                    begin
                        if (month_l == 4'd0)
                        begin
                            month_l <= 4'd9;
                            month_h <= month_h - 1'b1;
                        end 
                        else if (month_h == 4'd0 && month_l == 4'd1)
                        begin
                            month_l <= 4'd2;
                            month_h <= 4'd1;
                        end
                        else
                        begin
                             month_l <=  month_l - 4'd1;
                        end
                    end
                end 
                4'd7: // change day
                begin
                    if (inc) // inc punch -> day
                    begin
                        if (day_l == 4'd9)
                        begin
                            day_l <= 4'd0;
                            day_h <= day_h + 1'b1;
                        end
                        else
                        begin
                            day_l <= day_l + 1'b1;
                        end
                        if (day_h == 4'd3 && day_l == 4'd1 && (({month_h, month_l} == 8'd1) || ({month_h, month_l} == 8'd3) || ({month_h, month_l} == 8'd5) || ({month_h, month_l} == 8'd7) || ({month_h, month_l} == 8'd8) || (month_h == 4'd1 && month_l == 4'd0) || (month_h == 4'd1 && month_l == 4'd2)))
                        begin
                            day_h <= 4'd0;
                            day_l <= 4'd1;
                        end
                        else if (day_h == 4'd2 && day_l == 4'd8 && ({month_h, month_l} == 8'd2) && !leap_year)
                        begin
                            day_h <= 4'd0;
                            day_l <= 4'd1;
                        end
                        else if (day_h == 4'd2 && day_l == 4'd9 && ({month_h, month_l} == 8'd2) && leap_year)
                        begin
                            day_h <= 4'd0;
                            day_l <= 4'd1;
                        end
                        else if (day_h == 4'd3 && day_l == 4'd0 && (({month_h, month_l} == 8'd2) || ({month_h, month_l} == 8'd4) || ({month_h, month_l} == 8'd6) || ({month_h, month_l} == 8'd9) || (month_h == 4'd1 && month_l == 4'd1)))
                        begin
                            day_h <= 4'd0;
                            day_l <= 4'd1;
                        end
                    end
                    if (de)
                    begin
                        if (day_l == 4'd0)
                        begin
                            day_l <= 4'd9;
                            day_h <= day_h - 1'b1;
                        end
                        else
                        begin
                            day_l <= day_l - 1'b1;
                        end
                        if (day_h == 4'd0 && day_l == 4'd1 && (({month_h, month_l} == 8'd1) || ({month_h, month_l} == 8'd3) || ({month_h, month_l} == 8'd5) || ({month_h, month_l} == 8'd7) || ({month_h, month_l} == 8'd8) || (month_h == 4'd1 && month_l == 4'd0) || (month_h == 4'd1 && month_l == 4'd2)))
                        begin
                            day_h <= 4'd3;
                            day_l <= 4'd0;
                        end
                        else if (day_h == 4'd0 && day_l == 4'd1 && (({month_h, month_l} == 8'd2) || ({month_h, month_l} == 8'd4) || ({month_h, month_l} == 8'd6) || ({month_h, month_l} == 8'd9) || (month_h == 4'd1 && month_l == 4'd1)))
                        begin
                            day_h <= 4'd2;
                            day_l <= 4'd9;
                        end
                        else if (day_h == 4'd0 && day_l == 4'd1 && ({month_h, month_l} == 8'd2) && !leap_year)
                        begin
                            day_h <= 4'd2;
                            day_l <= 4'd8;
                        end
                        else if (day_h == 4'd0 && day_l == 4'd1 && ({month_h, month_l} == 8'd2) && leap_year)
                        begin
                            day_h <= 4'd2;
                            day_l <= 4'd9;
                        end
                    end
                end
        endcase
    end
    else
    begin
                case(clock_s)
                3'd0:
                begin
                    ;
                end
                3'd1:// runing - look clock
                begin
                    ;
                end
                3'd2:// change clock-year4
                begin
                    if (inc) // inc punch -> year4
                    begin
                        if (clock_year_4 == 4'd9)
                        begin
                            clock_year_4 <= 4'd0;
                        end
                        else
                        begin
                            clock_year_4 <= clock_year_4 + 1'b1;
                        end
                    end
                    if (de)
                    begin
                        if (clock_year_4 == 4'd0)
                        begin
                            clock_year_4 <= 4'd9;
                        end
                        else
                        begin
                            clock_year_4 <= clock_year_4 - 1'b1;
                        end
                    end
                end
                3'd3:// change clock-year3
                begin
                    if (inc) // inc punch -> year3
                    begin
                        if (clock_year_3 == 4'd9)
                        begin
                            clock_year_3 <= 4'd0;
                        end
                        else
                        begin
                            clock_year_3 <= clock_year_3 + 1'b1;
                        end
                    end
                    if (de)
                    begin
                        if (clock_year_3 == 4'd0)
                        begin
                            clock_year_3 <= 4'd9;
                        end
                        else
                        begin
                            clock_year_3 <= clock_year_3 - 1'b1;
                        end
                    end
                end
                3'd4:// change clock-year2
                begin
                    if (inc) // inc punch -> year2
                    begin
                        if (clock_year_2 == 4'd9)
                        begin
                            clock_year_2 <= 4'd0;
                        end
                        else
                        begin
                            clock_year_2 <= clock_year_2 + 1'b1;
                        end
                    end
                    if (de)
                    begin
                        if (clock_year_2 == 4'd0)
                        begin
                            clock_year_2 <= 4'd9;
                        end
                        else
                        begin
                            clock_year_2 <= clock_year_2 - 1'b1;
                        end
                    end
                end
                3'd5:// change clock-year1
                begin
                    if (inc) // inc punch -> year1
                    begin
                        if (clock_year_1 == 4'd9)
                        begin
                            clock_year_1 <= 4'd0;
                        end
                        else
                        begin
                            clock_year_1 <= clock_year_1 + 1'b1;
                        end
                    end
                    if (de)
                    begin
                        if (clock_year_1 == 4'd0)
                        begin
                            clock_year_1 <= 4'd9;
                        end
                        else
                        begin
                            clock_year_1 <= clock_year_1 - 1'b1;
                        end
                    end
                end
                3'd6:// change clock-month
                begin
                    if (inc) // inc punch -> month
                    begin
                        if (clock_month_l == 4'd9)
                        begin
                            clock_month_l <= 4'd0;
                            clock_month_h <= clock_month_h + 1'b1;
                        end 
                        else if (clock_month_h == 4'd1 && clock_month_l == 4'd2)
                        begin
                            clock_month_l <= 4'd1;
                            clock_month_h <= 4'd0;
                        end
                        else
                        begin
                             clock_month_l <=  clock_month_l + 4'd1;
                        end
                    end
                    if (de) // dec punch -> month
                    begin
                        if (clock_month_l == 4'd0)
                        begin
                            clock_month_l <= 4'd9;
                            clock_month_h <= clock_month_h - 1'b1;
                        end 
                        else if (clock_month_h == 4'd0 && clock_month_l == 4'd1)
                        begin
                            clock_month_l <= 4'd2;
                            clock_month_h <= 4'd1;
                        end
                        else
                        begin
                             clock_month_l <=  clock_month_l - 4'd1;
                        end
                    end
                end
                3'd7:// change clock-day
                begin
                    if (inc) // inc punch -> day
                    begin
                        if (clock_day_l == 4'd9)
                        begin
                            clock_day_l <= 4'd0;
                            clock_day_h <= clock_day_h + 1'b1;
                        end
                        else
                        begin
                            clock_day_l <= clock_day_l + 1'b1;
                        end
                        if (clock_day_h == 4'd3 && clock_day_l == 4'd1 && (({clock_month_h, clock_month_l} == 8'd1) || ({clock_month_h, clock_month_l} == 8'd3) || ({clock_month_h, clock_month_l} == 8'd5) || ({clock_month_h, clock_month_l} == 8'd7) || ({clock_month_h, clock_month_l} == 8'd8) || (clock_month_h == 4'd1 && clock_month_l == 4'd0) || (clock_month_h == 4'd1 && clock_month_l == 4'd2)))
                        begin
                            clock_day_h <= 4'd0;
                            clock_day_l <= 4'd1;
                        end
                        else if (clock_day_h == 4'd2 && clock_day_l == 4'd8 && ({clock_month_h, clock_month_l} == 8'd2) && !leap_year)
                        begin
                            clock_day_h <= 4'd0;
                            clock_day_l <= 4'd1;
                        end
                        else if (clock_day_h == 4'd2 && clock_day_l == 4'd9 && ({clock_month_h, clock_month_l} == 8'd2) && leap_year)
                        begin
                            clock_day_h <= 4'd0;
                            clock_day_l <= 4'd1;
                        end
                        else if (clock_day_h == 4'd3 && clock_day_l == 4'd0 && (({clock_month_h, clock_month_l} == 8'd2) || ({clock_month_h, clock_month_l} == 8'd4) || ({clock_month_h, clock_month_l} == 8'd6) || ({clock_month_h, clock_month_l} == 8'd9) || (clock_month_h == 4'd1 && clock_month_l == 4'd1)))
                        begin
                            clock_day_h <= 4'd1;
                        end
                    end    
                    if (de)
                    begin
                        if (clock_day_l == 4'd0)
                        begin
                            clock_day_l <= 4'd9;
                            clock_day_h <= clock_day_h - 1'b1;
                        end
                        else
                        begin
                            clock_day_l <= clock_day_l - 1'b1;
                        end
                        if (clock_day_h == 4'd0 && clock_day_l == 4'd1 && (({clock_month_h, clock_month_l} == 8'd1) || ({clock_month_h, clock_month_l} == 8'd3) || ({clock_month_h, clock_month_l} == 8'd5) || ({clock_month_h, clock_month_l} == 8'd7) || ({clock_month_h, clock_month_l} == 8'd8) || (clock_month_h == 4'd1 && clock_month_l == 4'd0) || (clock_month_h == 4'd1 && clock_month_l == 4'd2)))
                        begin
                            clock_day_h <= 4'd3;
                            clock_day_l <= 4'd0;
                        end
                        else if (clock_day_h == 4'd0 && clock_day_l == 4'd1 && (({clock_month_h, clock_month_l} == 8'd2) || ({clock_month_h, clock_month_l} == 8'd4) || ({clock_month_h, clock_month_l} == 8'd6) || ({clock_month_h, clock_month_l} == 8'd9) || (clock_month_h == 4'd1 && clock_month_l == 4'd1)))
                        begin
                            clock_day_h <= 4'd2;
                            clock_day_l <= 4'd9;
                        end
                        else if (clock_day_h == 4'd0 && clock_day_l == 4'd1 && ({clock_month_h, clock_month_l} == 8'd2) && !leap_year)
                        begin
                            clock_day_h <= 4'd2;
                            clock_day_l <= 4'd8;
                        end
                        else if (clock_day_h == 4'd0 && clock_day_l == 4'd1 && ({clock_month_h, clock_month_l} == 8'd2) && leap_year)
                        begin
                            clock_day_h <= 4'd2;
                            clock_day_l <= 4'd9;
                        end
                    end        
                end
        endcase
    end
end
endmodule

约束文件

############## NET - IOSTANDARD ##################
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
#############SPI Configurate Setting##################
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] 
set_property CONFIG_MODE SPIx4 [current_design] 
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design] 

set_property IOSTANDARD LVCMOS33 [get_ports {an[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {an[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_left[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_left[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_left[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_left[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_left[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_left[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_left[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_left[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_right[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_right[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_right[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_right[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_right[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_right[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_right[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {seg_right[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports clk]
set_property IOSTANDARD LVCMOS33 [get_ports rst]
set_property IOSTANDARD LVCMOS33 [get_ports select]
set_property IOSTANDARD LVCMOS33 [get_ports inc]
set_property IOSTANDARD LVCMOS33 [get_ports led]
set_property IOSTANDARD LVCMOS33 [get_ports de]
set_property IOSTANDARD LVCMOS33 [get_ports select_clock]

set_property PACKAGE_PIN R11 [get_ports select_clock]
set_property PACKAGE_PIN R17 [get_ports de]
set_property PACKAGE_PIN K2 [get_ports led]
set_property PACKAGE_PIN R15 [get_ports select]
set_property PACKAGE_PIN U4 [get_ports inc]
set_property PACKAGE_PIN P17 [get_ports clk]
set_property PACKAGE_PIN V1 [get_ports rst]
set_property PACKAGE_PIN B4 [get_ports {seg_left[0]}]
set_property PACKAGE_PIN A4 [get_ports {seg_left[1]}]
set_property PACKAGE_PIN A3 [get_ports {seg_left[2]}]
set_property PACKAGE_PIN B1 [get_ports {seg_left[3]}]
set_property PACKAGE_PIN A1 [get_ports {seg_left[4]}]
set_property PACKAGE_PIN B3 [get_ports {seg_left[5]}]
set_property PACKAGE_PIN B2 [get_ports {seg_left[6]}]
set_property PACKAGE_PIN D5 [get_ports {seg_left[7]}]
set_property PACKAGE_PIN D4 [get_ports {seg_right[0]}]
set_property PACKAGE_PIN E3 [get_ports {seg_right[1]}]
set_property PACKAGE_PIN D3 [get_ports {seg_right[2]}]
set_property PACKAGE_PIN F4 [get_ports {seg_right[3]}]
set_property PACKAGE_PIN F3 [get_ports {seg_right[4]}]
set_property PACKAGE_PIN E2 [get_ports {seg_right[5]}]
set_property PACKAGE_PIN D2 [get_ports {seg_right[6]}]
set_property PACKAGE_PIN H2 [get_ports {seg_right[7]}]
set_property PACKAGE_PIN G2 [get_ports {an[7]}]
set_property PACKAGE_PIN C2 [get_ports {an[6]}]
set_property PACKAGE_PIN C1 [get_ports {an[5]}]
set_property PACKAGE_PIN H1 [get_ports {an[4]}]
set_property PACKAGE_PIN G1 [get_ports {an[3]}]
set_property PACKAGE_PIN F1 [get_ports {an[2]}]
set_property PACKAGE_PIN E1 [get_ports {an[1]}]
set_property PACKAGE_PIN G6 [get_ports {an[0]}]

运行效果

我们以小数点区分年月日,前面四位是年,中间两位是月份,后面两位是日。然后图中箭头指的位置是我们控制这个日历的按钮。这五个按钮我们均设置了功能。左边的按钮是复位键,当按钮按下时,时钟会回到设置的初始值。中间的按钮是切换日历的状态,通过这个按钮我们可以查看星期,以及日历的调时。右边的按钮是闹钟状态的切换,通过这个按钮,我们可以进入闹钟的状态,设置闹钟。上面和下面的按钮,是在调时或者在闹钟设置时,对时间进行加减,上面是加,下面是减。 

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值