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