TAG
-
F
P
G
A
、
5
C
S
E
M
A
5
F
31
C
6
、电子万年历、
V
e
r
i
l
o
g
FPGA、5CSEMA5F31C6、电子万年历、Verilog
FPGA、5CSEMA5F31C6、电子万年历、Verilogmodule TOP(
input CLK,RST,inA,inB,inC,switch_alarm,
output led,beep_led,
output [41:0] dp
);
// 按键消抖模块
wire keyA_turn, keyB_turn, keyC_turn;
// 按键处理模块
wire select_sign;
wire [1:0] flag_turn;
wire [1:0] flag_switch;
wire year_add, month_add, day_add;
wire hour_add, minute_add, second_add;
wire alarm_hour_add, alarm_minute_add, alarm_second_add;
// 时钟模块
wire [6:0] year;
wire [4:0] day;
wire [3:0] month;
wire [4:0] hour;
wire [5:0] minute;
wire [5:0] second;
// 数码管显示模块
wire [32:0] digital_clock;
// 闹钟模块
wire [4:0] alarm_hour;
wire [5:0] alarm_minute;
wire [5:0] alarm_second;
//按键消抖模块
right_key rk_A(
.clk (CLK),
.rst_n (RST),
.key_in (inA),
.key_flag (keyA_turn)
);
right_key rk_B(
.clk (CLK),
.rst_n (RST),
.key_in (inB),
.key_flag (keyB_turn)
);
right_key rk_C(
.clk (CLK),
.rst_n (RST),
.key_in (inC),
.key_flag (keyC_turn)
);
//按键处理模块
sel_add eg_sel_add(
.clk (CLK),
.rst_n (RST),
.key_turn (keyA_turn),
.key_switch (keyB_turn),
.key_add (keyC_turn),
.select_sign (select_sign),
.flag_turn (flag_turn),
.flag_switch (flag_switch),
.second_add (second_add),
.minute_add (minute_add),
.hour_add (hour_add),
.day_add (day_add),
.month_add (month_add),
.year_add (year_add),
.alarm_second_add (alarm_second_add),
.alarm_minute_add (alarm_minute_add),
.alarm_hour_add (alarm_hour_add)
);
// 时钟模块
clock eg_clock(
.clk (CLK),
.rst_n (RST),
.select_sign (select_sign),
.second_add (second_add),
.minute_add (minute_add),
.hour_add (hour_add),
.day_add (day_add),
.month_add (month_add),
.year_add (year_add),
.hour (hour),
.minute (minute),
.second (second),
.day (day),
.month (month),
.year (year)
);
// 数码管显示模块
display eg_display(
.CLK (CLK),
.RST (RST),
.flag_turn (flag_turn),
.flag_switch (flag_switch),
.alarm_h (alarm_hour),
.alarm_m (alarm_minute),
.alarm_s (alarm_second),
.year (year),
.month (month),
.day (day),
.h (hour),
.m (minute),
.s (second),
.dp (dp)
);
// 闹钟模块
alarm eg_alarm(
.clk (CLK),
.rst_n (RST),
.switch_alarm (switch_alarm),
.second (second),
.minute (minute),
.hour (hour),
.alarm_second_add (alarm_second_add),
.alarm_minute_add (alarm_minute_add),
.alarm_hour_add (alarm_hour_add),
.led (led),
.beep_led (beep_led),
.alarm_second (alarm_second),
.alarm_minute (alarm_minute),
.alarm_hour (alarm_hour)
);
endmodule
// 按键消抖模块
module right_key
#(parameter WIDTH = 20'd999_999)
(
input clk,rst_n,key_in,
output reg key_flag
);
reg[19:0] CNT_20MS;
always @(posedge clk or negedge rst_n) begin
if(!rst_n) CNT_20MS<=20'd0;
else if(key_in==1'b1) CNT_20MS<=20'd0;
else if(CNT_20MS==WIDTH) CNT_20MS<=WIDTH;
else CNT_20MS<=CNT_20MS+1;
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n) key_flag<=1'b0;
else if(CNT_20MS==WIDTH-1) key_flag<=1'b1;
else key_flag<=1'b0;
end
endmodule
// 按键处理模块
module sel_add(
input clk, rst_n,
input key_turn,
input key_switch,
input key_add,
output select_sign,
output reg [1:0] flag_switch,
output reg [1:0] flag_turn,
output reg second_add, minute_add, hour_add, day_add, month_add, year_add,
output reg alarm_second_add, alarm_minute_add, alarm_hour_add
);
reg [3:0] flag_add=0;
reg [1:0] turn_state=0,turn_next_state=0; //翻页状态机(分别是输出、现态、次态)
reg [1:0] switch_state=0,switch_next_state=0;//当前选择数码管状态机
assign select_sign=(flag_add==4'b0000);
// 1
//页面切换的状态机
//次态电路
always@(negedge key_turn or negedge rst_n)
begin
if(!rst_n) turn_next_state=2'b00;
else
case(turn_state)
2'b00:turn_next_state=2'b01;
2'b01:turn_next_state=2'b10;
2'b10:turn_next_state=2'b00;
default:turn_next_state=2'b00;
endcase
end
//次态到现态转换
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) turn_state<=2'b00;
else turn_state<=turn_next_state;
end
//输出电路
always@(rst_n or turn_state)
begin
if(!rst_n) flag_turn= 2'b00;
else
case(turn_state)
2'b00:flag_turn=2'b00;
2'b01:flag_turn=2'b01;
2'b10:flag_turn=2'b10;
default:flag_turn=2'b00;
endcase
end
// 2
//数码管闪烁选择的状态机
//次态电路
always@(negedge key_switch or negedge rst_n)
begin
if(!rst_n) switch_next_state=2'b00;
else
case(switch_state)
2'b00:switch_next_state=2'b01;
2'b01:switch_next_state=2'b10;
2'b10:switch_next_state=2'b11;
2'b11:switch_next_state=2'b00;
default:switch_next_state=2'b00;
endcase
end
//次态-->现态转换
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) switch_state<=2'b00;
else switch_state<=switch_next_state;
end
//输出电路
always@(rst_n or switch_state)
begin
if(!rst_n) flag_switch= 2'b00;
else
case(switch_state)
2'b00:flag_switch=2'b00;
2'b01:flag_switch=2'b01;
2'b10:flag_switch=2'b10;
2'b11:flag_switch=2'b11;
default:switch_next_state=2'b00;
endcase
end
// 3
//增一选择项目
always@(turn_state or switch_state or rst_n)
begin
if(!rst_n) flag_add=4'b0000;//0000代表空状态(都没选)
else
case(turn_state)//当前页面
2'b00: //第一页(时分秒)
case(switch_state)//当前数码管闪烁选择
2'b00:flag_add=4'b0000;
2'b01:flag_add=4'b0001;//选中秒
2'b10:flag_add=4'b0010;//选中分
2'b11:flag_add=4'b0011;//选中时
endcase
2'b01: //第二页(年月日)
case(switch_state)
2'b00:flag_add=4'b0000;
2'b01:flag_add=4'b0101;//选中日
2'b10:flag_add=4'b0110;//选中月
2'b11:flag_add=4'b0111;//选中年
endcase
2'b10: //第三页(闹钟)
case(switch_state)
2'b00:flag_add=4'b0000;
2'b01:flag_add=4'b1001;//选中闹钟秒
2'b10:flag_add=4'b1010;//选中闹钟分
2'b11:flag_add=4'b1011;//选中闹钟时
endcase
default:flag_add=4'b0000;
endcase
end
// 4
//生成增一的专属信号
always@(key_add)
begin
case(flag_add)
4'b0001:second_add=key_add;
4'b0010:minute_add=key_add;
4'b0011:hour_add=key_add;
4'b0101:day_add=key_add;
4'b0110:month_add=key_add;
4'b0111:year_add=key_add;
4'b1001:alarm_second_add=key_add;
4'b1010:alarm_minute_add=key_add;
4'b1011:alarm_hour_add=key_add;
default:; //其它的都什么也不执行
endcase
end
endmodule
// 时钟模块
module clock(
input clk,
input rst_n,
input select_sign,
input second_add,
input minute_add,
input hour_add,
input day_add,
input month_add,
input year_add,
output reg [5:0] second,
output reg [5:0] minute,
output reg [4:0] hour,
output reg [4:0] day,
output reg [3:0] month,
output reg [6:0] year
);
parameter CNT_TIME = 50_000_000;
reg [31:0] cnt;
wire pulse_second; //秒脉冲
wire pulse_minute; //分脉冲
wire pulse_hour; //小时脉冲
wire pulse_day; //日脉冲
wire pulse_month; //月脉冲
wire pulse_year; //年脉冲
reg [5:0] second_set;
reg [5:0] minute_set;
reg [4:0] hour_set;
reg [4:0] day_set;
reg [3:0] month_set;
reg [6:0] year_set;
reg [3:0] day_month;
reg [6:0] day_year;
// cnt
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cnt<=0;
else
if(cnt==CNT_TIME-1)
cnt<=0;
else
cnt<=cnt+1;
end
// pulse
assign pulse_second=(cnt==CNT_TIME-1 && (select_sign==1'b1));
assign pulse_minute=(second==6'd59 && pulse_second==1'b1);
assign pulse_hour=(minute==6'd59 && pulse_minute==1'b1);
assign pulse_day=(hour==5'd23 && pulse_hour==1'b1);
assign pulse_month=((day==5'd28 && month==4'd2 && (year%4!=0) && pulse_day==1'b1)
||(day==5'd29 && month==4'd2 && (year%4==0) && pulse_day==1'b1)
||(day==5'd30 && (month==4'd4 || month==4'd6 ||month==4'd9 || month==4'd11) && pulse_day==1'b1)
||(day==5'd31 && (month==4'd1 || month==4'd3 ||month==4'd5 ||
month==4'd7 || month==4'd8 || month==4'd10 || month==4'd12) && pulse_day==1'b1));
assign pulse_year=(month==4'd12 && pulse_month==1'b1);
// s
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
second<=6'd00;
else
if(pulse_second) //秒脉冲
if(second>=59)
second<=0;
else
second<=second+1;
else if(second_add) //增一信号
second<=second_set;
else
second<=second;
end
// s_set
always@(posedge second_add)
begin
second_set=second; //先读取当前秒
if(second_set>=59)
second_set=0;
else
second_set=second_set+1;
end
// m
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
minute<=6'd00;
else
if(pulse_minute)
if(minute>=59)
minute<=0;
else
minute<=minute+1;
else if(minute_add)
minute<=minute_set;
else
minute<=minute;
end
// m_set
always@(posedge minute_add)
begin
minute_set=minute;
if(minute_set>=59)
minute_set=0;
else
minute_set=minute_set+1;
end
// h
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
hour<=5'd0;
else
if(pulse_hour)
if(hour>=23)
hour<=0;
else
hour<=hour+1;
else if(hour_add)
hour<=hour_set;
else
hour<=hour;
end
//h_set
always@(posedge hour_add )
begin
hour_set=hour;
if(hour_set>=23)
hour_set=0;
else
hour_set=hour_set+1;
end
// day
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
day<=1;
else
if(pulse_day) //天脉冲
if(month==1 || month==3 ||month==5 || month==7 || month==8 || month==10 || month==12)
if(day>=31)
day<=1;
else
day<=day+1;
else if(month==4 || month==6 ||month==9 || month==11)
if(day>=30)
day<=1;
else
day<=day+1;
else if(month==2 && (year%4==0))
if(day>=29)
day<=1;
else
day<=day+1;
else
if(day>=28)
day<=1;
else
day<=day+1;
else if(day_add)
day<=day_set;
else
day<=day;
end
// day_set
always@(posedge day_add)
begin
day_set=day;
day_month=month;
day_year=year;
if(day_month==1 || day_month==3 ||day_month==5 || day_month==7 || day_month==8 || day_month==10 || day_month==12)
if(day_set>=31)
day_set<=1;
else
day_set<=day_set+1;
else if(day_month==4 || day_month==6 ||day_month==9 || day_month==11)
if(day_set>=30)
day_set<=1;
else
day_set<=day_set+1;
else if(day_month==2 && (day_year%4==0)) //闰年
if(day_set>=29)
day_set<=1;
else
day_set<=day_set+1;
else
if(day_set>=28)
day_set<=1;
else
day_set<=day_set+1;
end
// month
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
month<=1;
else
if(pulse_month)
if(month>=12)
month<=1;
else
month<=month+1;
else if(month_add)
month<=month_set;
else
month<=month;
end
// month_set
always@(posedge month_add)
begin
month_set=month;
if(month_set>=12)
month_set=1;
else
month_set=month_set+1;
end
// year
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
year<=0;
else
if(pulse_year)
if(year>=99)
year<=0;
else
year<=year+1;
else if(year_add)
year<=year_set;
else
year<=year;
end
// year_set
always@(posedge year_add)
begin
year_set=year;
if(year_set>=99)
year_set=0;
else
year_set=year_set+1;
end
endmodule
// 数码管显示模块
module display(
input CLK,
input RST,
input [1:0] flag_turn,
input [1:0] flag_switch,
input [4:0] alarm_h,
input [5:0] alarm_m,
input [5:0] alarm_s,
input [6:0] year,
input [3:0] month,
input [4:0] day,
input [4:0] h,
input [5:0] m,
input [5:0] s,
output reg [41:0] dp
);
parameter per = 50_000_000;
parameter half_per = per / 2 - 1;
//
parameter NULL = 7'b 111_1111;
parameter s0 = 7'b 100_0000;
parameter s1 = 7'b 111_1001;
parameter s2 = 7'b 010_0100;
parameter s3 = 7'b 011_0000;
parameter s4 = 7'b 001_1001;
parameter s5 = 7'b 001_0010;
parameter s6 = 7'b 000_0010;
parameter s7 = 7'b 111_1000;
parameter s8 = 7'b 000_0000;
parameter s9 = 7'b 001_0000;
wire p;
assign p = (cnt == half_per);
//
reg [29:0] cnt;
reg f1,f2,f3;
always @(posedge CLK or negedge RST) begin
if(!RST) cnt = 0;
else if (cnt == half_per) cnt = 0;
else cnt = cnt + 1;
end
always @(posedge CLK or negedge RST) begin
if(!RST) begin
f1 = 1; f2 = 1; f3 = 1;
end else if (p) begin
case(flag_switch)
2'b 01: begin f1 = ~f1; f2 = 1; f3 = 1; end
2'b 10: begin f1 = 1; f2 = ~f2; f3 = 1; end
2'b 11: begin f1 = 1; f2 = 1; f3 = ~f3; end
default: begin f1 = 1; f2 = 1; f3 = 1; end
endcase
end
end
always @(posedge CLK or negedge RST) begin
if (!RST) dp = 42'hfffffff;
else if (flag_turn == 2'b 00) begin
case (s%10)
0: dp[6:0] = f1 ? s0 : NULL ;
1: dp[6:0] = f1 ? s1 : NULL ;
2: dp[6:0] = f1 ? s2 : NULL ;
3: dp[6:0] = f1 ? s3 : NULL ;
4: dp[6:0] = f1 ? s4 : NULL ;
5: dp[6:0] = f1 ? s5 : NULL ;
6: dp[6:0] = f1 ? s6 : NULL ;
7: dp[6:0] = f1 ? s7 : NULL ;
8: dp[6:0] = f1 ? s8 : NULL ;
9: dp[6:0] = f1 ? s9 : NULL ;
default: ;
endcase
case (s/10)
0: dp[13:7] = f1 ? s0 : NULL ;
1: dp[13:7] = f1 ? s1 : NULL ;
2: dp[13:7] = f1 ? s2 : NULL ;
3: dp[13:7] = f1 ? s3 : NULL ;
4: dp[13:7] = f1 ? s4 : NULL ;
5: dp[13:7] = f1 ? s5 : NULL ;
6: dp[13:7] = f1 ? s6 : NULL ;
7: dp[13:7] = f1 ? s7 : NULL ;
8: dp[13:7] = f1 ? s8 : NULL ;
9: dp[13:7] = f1 ? s9 : NULL ;
default: ;
endcase
case (m%10)
0: dp[20:14] = f2 ? s0 : NULL ;
1: dp[20:14] = f2 ? s1 : NULL ;
2: dp[20:14] = f2 ? s2 : NULL ;
3: dp[20:14] = f2 ? s3 : NULL ;
4: dp[20:14] = f2 ? s4 : NULL ;
5: dp[20:14] = f2 ? s5 : NULL ;
6: dp[20:14] = f2 ? s6 : NULL ;
7: dp[20:14] = f2 ? s7 : NULL ;
8: dp[20:14] = f2 ? s8 : NULL ;
9: dp[20:14] = f2 ? s9 : NULL ;
default: ;
endcase
case (m/10)
0: dp[27:21] = f2 ? s0 : NULL ;
1: dp[27:21] = f2 ? s1 : NULL ;
2: dp[27:21] = f2 ? s2 : NULL ;
3: dp[27:21] = f2 ? s3 : NULL ;
4: dp[27:21] = f2 ? s4 : NULL ;
5: dp[27:21] = f2 ? s5 : NULL ;
6: dp[27:21] = f2 ? s6 : NULL ;
7: dp[27:21] = f2 ? s7 : NULL ;
8: dp[27:21] = f2 ? s8 : NULL ;
9: dp[27:21] = f2 ? s9 : NULL ;
default: ;
endcase
case (h%10)
0: dp[34:28] = f3 ? s0 : NULL ;
1: dp[34:28] = f3 ? s1 : NULL ;
2: dp[34:28] = f3 ? s2 : NULL ;
3: dp[34:28] = f3 ? s3 : NULL ;
4: dp[34:28] = f3 ? s4 : NULL ;
5: dp[34:28] = f3 ? s5 : NULL ;
6: dp[34:28] = f3 ? s6 : NULL ;
7: dp[34:28] = f3 ? s7 : NULL ;
8: dp[34:28] = f3 ? s8 : NULL ;
9: dp[34:28] = f3 ? s9 : NULL ;
default: ;
endcase
case (h/10)
0: dp[41:35] = f3 ? s0 : NULL ;
1: dp[41:35] = f3 ? s1 : NULL ;
2: dp[41:35] = f3 ? s2 : NULL ;
3: dp[41:35] = f3 ? s3 : NULL ;
4: dp[41:35] = f3 ? s4 : NULL ;
5: dp[41:35] = f3 ? s5 : NULL ;
6: dp[41:35] = f3 ? s6 : NULL ;
7: dp[41:35] = f3 ? s7 : NULL ;
8: dp[41:35] = f3 ? s8 : NULL ;
9: dp[41:35] = f3 ? s9 : NULL ;
default: ;
endcase
end else if (flag_turn == 2'b 01) begin //
case (day%10)
0: dp[6:0] = f1 ? s0 : NULL ;
1: dp[6:0] = f1 ? s1 : NULL ;
2: dp[6:0] = f1 ? s2 : NULL ;
3: dp[6:0] = f1 ? s3 : NULL ;
4: dp[6:0] = f1 ? s4 : NULL ;
5: dp[6:0] = f1 ? s5 : NULL ;
6: dp[6:0] = f1 ? s6 : NULL ;
7: dp[6:0] = f1 ? s7 : NULL ;
8: dp[6:0] = f1 ? s8 : NULL ;
9: dp[6:0] = f1 ? s9 : NULL ;
default: ;
endcase
case (day/10)
0: dp[13:7] = f1 ? s0 : NULL ;
1: dp[13:7] = f1 ? s1 : NULL ;
2: dp[13:7] = f1 ? s2 : NULL ;
3: dp[13:7] = f1 ? s3 : NULL ;
4: dp[13:7] = f1 ? s4 : NULL ;
5: dp[13:7] = f1 ? s5 : NULL ;
6: dp[13:7] = f1 ? s6 : NULL ;
7: dp[13:7] = f1 ? s7 : NULL ;
8: dp[13:7] = f1 ? s8 : NULL ;
9: dp[13:7] = f1 ? s9 : NULL ;
default: ;
endcase
case (month%10)
0: dp[20:14] = f2 ? s0 : NULL ;
1: dp[20:14] = f2 ? s1 : NULL ;
2: dp[20:14] = f2 ? s2 : NULL ;
3: dp[20:14] = f2 ? s3 : NULL ;
4: dp[20:14] = f2 ? s4 : NULL ;
5: dp[20:14] = f2 ? s5 : NULL ;
6: dp[20:14] = f2 ? s6 : NULL ;
7: dp[20:14] = f2 ? s7 : NULL ;
8: dp[20:14] = f2 ? s8 : NULL ;
9: dp[20:14] = f2 ? s9 : NULL ;
default: ;
endcase
case (month/10)
0: dp[27:21] = f2 ? s0 : NULL ;
1: dp[27:21] = f2 ? s1 : NULL ;
2: dp[27:21] = f2 ? s2 : NULL ;
3: dp[27:21] = f2 ? s3 : NULL ;
4: dp[27:21] = f2 ? s4 : NULL ;
5: dp[27:21] = f2 ? s5 : NULL ;
6: dp[27:21] = f2 ? s6 : NULL ;
7: dp[27:21] = f2 ? s7 : NULL ;
8: dp[27:21] = f2 ? s8 : NULL ;
9: dp[27:21] = f2 ? s9 : NULL ;
default: ;
endcase
case (year%10)
0: dp[34:28] = f3 ? s0 : NULL ;
1: dp[34:28] = f3 ? s1 : NULL ;
2: dp[34:28] = f3 ? s2 : NULL ;
3: dp[34:28] = f3 ? s3 : NULL ;
4: dp[34:28] = f3 ? s4 : NULL ;
5: dp[34:28] = f3 ? s5 : NULL ;
6: dp[34:28] = f3 ? s6 : NULL ;
7: dp[34:28] = f3 ? s7 : NULL ;
8: dp[34:28] = f3 ? s8 : NULL ;
9: dp[34:28] = f3 ? s9 : NULL ;
default: ;
endcase
case (year/10)
0: dp[41:35] = f3 ? s0 : NULL ;
1: dp[41:35] = f3 ? s1 : NULL ;
2: dp[41:35] = f3 ? s2 : NULL ;
3: dp[41:35] = f3 ? s3 : NULL ;
4: dp[41:35] = f3 ? s4 : NULL ;
5: dp[41:35] = f3 ? s5 : NULL ;
6: dp[41:35] = f3 ? s6 : NULL ;
7: dp[41:35] = f3 ? s7 : NULL ;
8: dp[41:35] = f3 ? s8 : NULL ;
9: dp[41:35] = f3 ? s9 : NULL ;
default: ;
endcase
end else begin //
case (alarm_s%10)
0: dp[6:0] = f1 ? s0 : NULL ;
1: dp[6:0] = f1 ? s1 : NULL ;
2: dp[6:0] = f1 ? s2 : NULL ;
3: dp[6:0] = f1 ? s3 : NULL ;
4: dp[6:0] = f1 ? s4 : NULL ;
5: dp[6:0] = f1 ? s5 : NULL ;
6: dp[6:0] = f1 ? s6 : NULL ;
7: dp[6:0] = f1 ? s7 : NULL ;
8: dp[6:0] = f1 ? s8 : NULL ;
9: dp[6:0] = f1 ? s9 : NULL ;
default: ;
endcase
case (alarm_s/10)
0: dp[13:7] = f1 ? s0 : NULL ;
1: dp[13:7] = f1 ? s1 : NULL ;
2: dp[13:7] = f1 ? s2 : NULL ;
3: dp[13:7] = f1 ? s3 : NULL ;
4: dp[13:7] = f1 ? s4 : NULL ;
5: dp[13:7] = f1 ? s5 : NULL ;
6: dp[13:7] = f1 ? s6 : NULL ;
7: dp[13:7] = f1 ? s7 : NULL ;
8: dp[13:7] = f1 ? s8 : NULL ;
9: dp[13:7] = f1 ? s9 : NULL ;
default: ;
endcase
case (alarm_m%10)
0: dp[20:14] = f2 ? s0 : NULL ;
1: dp[20:14] = f2 ? s1 : NULL ;
2: dp[20:14] = f2 ? s2 : NULL ;
3: dp[20:14] = f2 ? s3 : NULL ;
4: dp[20:14] = f2 ? s4 : NULL ;
5: dp[20:14] = f2 ? s5 : NULL ;
6: dp[20:14] = f2 ? s6 : NULL ;
7: dp[20:14] = f2 ? s7 : NULL ;
8: dp[20:14] = f2 ? s8 : NULL ;
9: dp[20:14] = f2 ? s9 : NULL ;
default: ;
endcase
case (alarm_m/10)
0: dp[27:21] = f2 ? s0 : NULL ;
1: dp[27:21] = f2 ? s1 : NULL ;
2: dp[27:21] = f2 ? s2 : NULL ;
3: dp[27:21] = f2 ? s3 : NULL ;
4: dp[27:21] = f2 ? s4 : NULL ;
5: dp[27:21] = f2 ? s5 : NULL ;
6: dp[27:21] = f2 ? s6 : NULL ;
7: dp[27:21] = f2 ? s7 : NULL ;
8: dp[27:21] = f2 ? s8 : NULL ;
9: dp[27:21] = f2 ? s9 : NULL ;
default: ;
endcase
case (alarm_h%10)
0: dp[34:28] = f3 ? s0 : NULL ;
1: dp[34:28] = f3 ? s1 : NULL ;
2: dp[34:28] = f3 ? s2 : NULL ;
3: dp[34:28] = f3 ? s3 : NULL ;
4: dp[34:28] = f3 ? s4 : NULL ;
5: dp[34:28] = f3 ? s5 : NULL ;
6: dp[34:28] = f3 ? s6 : NULL ;
7: dp[34:28] = f3 ? s7 : NULL ;
8: dp[34:28] = f3 ? s8 : NULL ;
9: dp[34:28] = f3 ? s9 : NULL ;
default: ;
endcase
case (alarm_h/10)
0: dp[41:35] = f3 ? s0 : NULL ;
1: dp[41:35] = f3 ? s1 : NULL ;
2: dp[41:35] = f3 ? s2 : NULL ;
3: dp[41:35] = f3 ? s3 : NULL ;
4: dp[41:35] = f3 ? s4 : NULL ;
5: dp[41:35] = f3 ? s5 : NULL ;
6: dp[41:35] = f3 ? s6 : NULL ;
7: dp[41:35] = f3 ? s7 : NULL ;
8: dp[41:35] = f3 ? s8 : NULL ;
9: dp[41:35] = f3 ? s9 : NULL ;
default: ;
endcase
end
end
endmodule
// 闹钟模块
module alarm(
input clk,
input rst_n,
input [5:0] second,
input [5:0] minute,
input [4:0] hour,
input switch_alarm,
input alarm_second_add,
input alarm_minute_add,
input alarm_hour_add,
output led,
output beep_led,
output reg [5:0] alarm_second,
output reg [5:0] alarm_minute,
output reg [4:0] alarm_hour
);
assign led=switch_alarm;
assign beep_led=(second==alarm_second && minute==alarm_minute
&& hour==alarm_hour && switch_alarm==1'b1);
//设置秒
always@(negedge alarm_second_add or negedge rst_n)
begin
if(!rst_n)
alarm_second<=6'd5;
else
if(alarm_second>=59)
alarm_second<=0;
else
alarm_second<=alarm_second+1;
end
//设置分
always@(negedge alarm_minute_add or negedge rst_n)
begin
if(!rst_n)
alarm_minute<=6'd0;
else
if(alarm_minute>=12)
alarm_minute<=0;
else
alarm_minute<=alarm_minute+1;
end
//设置时
always@(negedge alarm_hour_add or negedge rst_n)
begin
if(!rst_n)
alarm_hour<=5'd0;
else
if(alarm_hour>=23)
alarm_hour<=0;
else
alarm_hour<=alarm_hour+1;
end
endmodule
实现细节
状态机
秒脉冲
参考示意图
参考链接
作者 | 乐意奥AI