EDA-课程设计-电子闹钟
一、实验目的
1.掌握多层电路在 QuartusII 集成开发环境中的实现;
2.熟练掌握基于 QuartusII 集成开发环境的组合逻辑电路设计流程;
3.掌握基于 QuartusII 集成开发环境的时序逻辑电路设计流程;
4.理解有限状态机设计的基本原理;
5.掌握采用有限状态机设计电路的方法;
6.掌握有限状态机的 VerilogHDL 实现;
7.熟练开发板的使用;
8.锻炼综合设计电路能力。
二、实验任务及要求
基本功能:正常时间显示,闹钟时间显示,闹钟触发。
三、实验原理和步骤
3.1 功能介绍
FPGA 实现电子闹钟。具有的功能为:
- 基础功能:
1)正常时间的显示。
2)闹钟时间的显示。
3)闹钟触发 - 设计功能:
1)手动调整当前时间。
2)手动设置闹钟时间。
3)闹钟触发时,LED会呈花式闪烁,闪烁时间为一分钟。
4)秒表功能,可以选择正向计时或者倒计时。
5)温度显示功能,可以根据时间的变化,显示不同的温度。
3.2 设计思路
- 对本次设计所需要的彩灯、七段数码管、开关、和按键进行一个汇总,并提前查阅其各自的管脚,进行分配。对于彩灯,选取8个作为闹钟触发时闪烁用;选取6个七段数码管,每两个显示时或分或秒,剩余两个表示温度;选取15个开关,每五个对应时、分、秒的设置,再用两个开关用于手动设置现在时间和闹钟时间;4个按键,一个表示计时显示按键,一个表示设置正计时,一个设置倒计时,一个用于启动计时。
- 用偶数分频的方法设计出来一个1s的时钟,用于后面的时间显示以及状态转移的持续时间。
- 设计时分秒的显示。
- 设计温度的显示。
- 用有限状态机的设计方法进行8路彩灯的显示。
- 设计正常时间运行的模块
- 设计设置闹钟时间的模块
- 设计调整现在时间的模型
- 设计正计时和倒计时模块
3.3 模块结构
- 模块一:设计1s的时钟信号。
- 模块二:正常时间显示模块。
- 模块三:设置闹钟时间与闹钟触发。
- 模块四:手动调整时间。
- 模块五:时间显示模型。
- 模块六:闹钟触发的8路彩灯显示。
- 模块七:计时模块。
- 模块八:温度显示模块。
四、代码
主模块
module syks(clk,set1,set2,JS3,JS2,JS1,JS0,in_S,in_F,in_M,out_S,out_F,out_M,out_LED,out_WD);
(*chip_pin = "Y2"*) input clk;
(*chip_pin = "AC27"*) input set1;
(*chip_pin = "AC28"*) input set2;
(*chip_pin = "R24"*) input JS3;
(*chip_pin = "N21"*) input JS2;
(*chip_pin = "M21"*) input JS1;
(*chip_pin = "M23"*) input JS0;
(*chip_pin = "Y23,Y24,AA22,AA23,AA24"*) input[4:0] in_S;
(*chip_pin = "AB23,AB24,AC24,AB25,AC25"*) input[4:0] in_F;
(*chip_pin = "AB26,AD26,AC26,AB27,AD27"*) input[4:0] in_M;
(*chip_pin = "AD17,AE17,AG17,AH17,AF17,AG18,AA14,AA17,AB16,AA16,AB17,AB15,AA15,AC17"*) output[13:0] out_S;
(*chip_pin = "AD18,AC18,AB18,AH19,AG19,AF18,AH18,AB19,AA19,AG21,AH21,AE19,AF19,AE18"*) output[13:0] out_F;
(*chip_pin = "V21,U21,AB20,AA21,AD24,AF23,Y19,AA25,AA26,Y25,W26,Y26,W27,W28"*) output[13:0] out_M;
(*chip_pin = "H15,G16,G15,F15,H17,J16,H16,J15"*) output[7:0] out_LED;
(*chip_pin = "M24,Y22,W21,W22,W25,U23,U24,G18,F22,E17,L26,L25,J22,H22"*) output[13:0] out_WD;
wire clk1;
reg[5:0] count_S = 6'd0,count_F = 6'd0,count_M = 6'd0,count = 6'd60;
reg[5:0] tmp_S = 6'd0,tmp_F = 6'd0,tmp_M = 6'd0,tmp_WD = 6'd0;
reg[5:0] set_S = 6'd10,set_F = 6'd10,set_M = 6'd10;
reg[5:0] MB_S = 6'd0,MB_F = 6'd0,MB_M = 6'd0;
reg flag = 1, flag1 = 1,flag2 = 0,flag3 = 0,flag4 = 1,flag5 = 1,flag6 = 1;
fenpin(clk,clk1);
always@(negedge JS0) flag1 = ~flag1;
always@(negedge JS1,negedge JS2)
beginif(!JS1)beginflag2 = 1;flag3 = 0;endif(!JS2)beginflag2 = 0;flag3 = 1;end
end
always@(negedge JS3)
beginflag6 = ~flag6;
end
always@(posedge clk1,negedge set1,negedge set2,negedge flag1)
begin//if(!flag1) beginif(flag2)begin tmp_S = 6'd0;tmp_F = 6'd0;tmp_M = 6'd0;tmp_WD = 6'd0;MB_S = {1'b0,in_S};MB_F = {1'b0,in_F};MB_M = {1'b0,in_M};flag5 = 1;endelse if(flag3)begintmp_S = {1'b0,in_S};tmp_F = {1'b0,in_F};tmp_M = {1'b0,in_M};tmp_WD = 6'd0;MB_S = 6'd0;MB_F = 6'd0;MB_M = 6'd0;flag5 = 0;endendelse if(!set2)beginset_S = {1'b0,in_S};set_F = {1'b0,in_F};set_M = {1'b0,in_M};count = 6'd60;flag = 1;endelse if(!set1) begincount_S = {1'b0,in_S};count_F = {1'b0,in_F};count_M = {1'b0,in_M};count = 6'd60;tmp_S = count_S;tmp_M = count_M;tmp_F = count_F;tmp_WD = count_S;flag = 1;endelsebeginif(flag6 == 0)beginif(flag5)beginif(flag4)beginif(tmp_M == 59) begintmp_M = 6'd0;if (tmp_F == 59)begintmp_F = 6'd0;if(tmp_S == 23) tmp_S = 6'd0;else tmp_S = tmp_S + 1;endelse tmp_F = tmp_F + 1;endendelse tmp_M = tmp_M + 1;if ((tmp_S == MB_S) && (tmp_F == MB_F) &&(tmp_M == MB_M)) flag4 = 0;endelse beginif(flag4)beginif(tmp_M == 6'd0) beginif(tmp_F == 6'd0) beginif(tmp_S == 6'd0) flag4 = 0;elsebegintmp_S = tmp_S - 1;tmp_F = 6'd59;endendelsebegintmp_F = tmp_F - 1;tmp_M = 6'd59;endendelse tmp_M = tmp_M - 1;endendendelse begin if(count_M == 59) begincount_M = 0;if (count_F == 59)begincount_F = 0;if(count_S == 23) count_S = 0;else count_S = count_S + 1;endelse count_F = count_F + 1;endelse count_M = count_M + 1;if ((count_S == set_S) && (count_F == set_F) &&(count_M == set_M)) count = 6'd0;if(count < 6'd60)begin count = count + 1;flag = 0;endelse flag = 1;tmp_S = count_S;tmp_M = count_M;tmp_F = count_F;tmp_WD = count_S;flag4 = 1;endend
end
show_LED(clk1,flag,out_LED);
show_SZ(clk1,tmp_S,out_S);
show_SZ(clk1,tmp_F,out_F);
show_SZ(clk1,tmp_M,out_M);
show_WD(clk,tmp_WD,out_WD);
endmodule
分频模块
module fenpin(clk,clk1);
input clk;
output reg clk1;
reg[30:0] count;
always@(posedge clk)
beginif (count == 24999999) begincount = 0;clk1 = ~clk1;endelse count = count + 1;
end
endmodule
LED显示模块
module show_LED(clk,in,out);
input in,clk;
output reg[7:0] out;
parameter s0 = 3'b000,s1 = 3'b001,s2 = 3'b010,s3 = 3'b011,s4 = 3'b100;
reg[2:0] cs,ns;always@(posedge clk)
beginif(in) cs = s4;else cs = ns;
end
always@(cs)
begincase(cs)s0:ns = s1;s1:ns = s2;s2:ns = s3;s3:ns = s4;s4:ns = s0;endcase
end
always@(cs)
begincase(cs)s0:out = 8'b10000001;s1:out = 8'b11000011;s2:out = 8'b11100111;s3:out = 8'b11111111;s4:out = 8'b00000000;endcase
end
endmodule
时钟显示模块
module show_SZ(clk,count,out);
input clk;
input[5:0] count;
output reg[13:0] out;
always @(posedge clk)
begincase(count)6'd0:out = 14'b0000001_0000001;6'd1:out = 14'b0000001_1001111;6'd2:out = 14'b0000001_0010010;6'd3:out = 14'b0000001_0000110;6'd4:out = 14'b0000001_1001100;6'd5:out = 14'b0000001_0100100;6'd6:out = 14'b0000001_0100000;6'd7:out = 14'b0000001_0001111;6'd8:out = 14'b0000001_0000000;6'd9:out = 14'b0000001_0000100;6'd10:out = 14'b1001111_0000001;6'd11:out = 14'b1001111_1001111;6'd12:out = 14'b1001111_0010010;6'd13:out = 14'b1001111_0000110;6'd14:out = 14'b1001111_1001100;6'd15:out = 14'b1001111_0100100;6'd16:out = 14'b1001111_0100000;6'd17:out = 14'b1001111_0001111;6'd18:out = 14'b1001111_0000000;6'd19:out = 14'b1001111_0000100;6'd20:out =14'b0010010_0000001;6'd21:out = 14'b0010010_1001111;6'd22:out = 14'b0010010_0010010;6'd23:out = 14'b0010010_0000110;6'd24:out = 14'b0010010_1001100;6'd25:out = 14'b0010010_0100100;6'd26:out =14'b0010010_0100000;6'd27:out = 14'b0010010_0001111;6'd28:out = 14'b0010010_0000000;6'd29:out = 14'b0010010_0000100;6'd30:out = 14'b0000110_0000001;6'd31:out = 14'b0000110_1001111;6'd32:out = 14'b0000110_0010010;6'd33:out = 14'b0000110_0000110;6'd34:out = 14'b0000110_1001100;6'd35:out = 14'b0000110_0100100;6'd36:out = 14'b0000110_0100000;6'd37:out = 14'b0000110_0001111;6'd38:out = 14'b0000110_0000000;6'd39:out = 14'b0000110_0000100;6'd40:out = 14'b1001100_0000001;6'd41:out = 14'b1001100_1001111;6'd42:out = 14'b1001100_0010010;6'd43:out = 14'b1001100_0000110;6'd44:out = 14'b1001100_1001100;6'd45:out = 14'b1001100_0100100;6'd46:out = 14'b1001100_0100000;6'd47:out = 14'b1001100_0001111;6'd48:out = 14'b1001100_0000000;6'd49:out = 14'b1001100_0000100;6'd50:out = 14'b0100100_0000001;6'd51:out = 14'b0100100_1001111;6'd52:out = 14'b0100100_0010010;6'd53:out = 14'b0100100_0000110;6'd54:out = 14'b0100100_1001100;6'd55:out = 14'b0100100_0100100;6'd56:out = 14'b0100100_0100000;6'd57:out = 14'b0100100_0001111;6'd58:out = 14'b0100100_0000000;6'd59:out = 14'b0100100_0000100;default:out = 14'b1111111_1111111;endcase
end
endmodule
show_wd.v 模块
module show_WD(clk,in_s,out);
input clk;
input[5:0] in_s;
output[13:0] out;
reg[5:0] count_WD;
always@(clk)
beginif(in_s >= 0 && in_s < 6'd8 ) count_WD = 6'd20;else if (in_s >= 6'd8 && in_s <= 6'd16) count_WD = 6'd25;else count_WD = 6'd18;
end
show_SZ(clk,count_WD,out);
endmodule
test.v 模块
if(flag6 == 0)beginif(flag5)beginif(flag4)beginif(tmp_M == 59) begintmp_M = 0;if (tmp_F == 59)begintmp_F = 0;if(tmp_S == 23) tmp_S = 0;else tmp_S = tmp_S + 1;endelse tmp_F = tmp_F + 1;endelse tmp_M = tmp_M + 1;if ((tmp_S == MB_S) && (tmp_F == MB_F) &&(tmp_M == MB_M)) flag4 = 0;endendelse beginif(flag4)beginif(tmp_M == 0) beginif(tmp_F == 0) beginif(tmp_S == 0) flag4 = 0;elsebegintmp_S = tmp_S - 1;tmp_F = 6'd59;endendelsebegintmp_F = tmp_F - 1;tmp_M = 6'd59;endendelse tmp_M = tmp_M - 1;endendendelse if(!flag1) beginif(flag2)begin tmp_S = 0;tmp_F = 0;tmp_M = 0;tmp_WD = 0;MB_S = {1'b0,in_S};MB_F = {1'b0,in_F};MB_M = {1'b0,in_M};flag5 = 1;endelse if(flag3)begintmp_S = {1'b0,in_S};tmp_F = {1'b0,in_F};tmp_M = {1'b0,in_M};tmp_WD = 0;MB_S = 0;MB_F = 0;MB_M = 0;flag5 = 0;endendelse