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)
begin
if(!JS1)
begin
flag2 = 1;
flag3 = 0;
end
if(!JS2)
begin
flag2 = 0;
flag3 = 1;
end
end
always@(negedge JS3)
begin
flag6 = ~flag6;
end
always@(posedge clk1,negedge set1,negedge set2,negedge flag1)
begin
//
if(!flag1)
begin
if(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;
end
else if(flag3)
begin
tmp_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;
end
end
else if(!set2)
begin
set_S = {1'b0,in_S};
set_F = {1'b0,in_F};
set_M = {1'b0,in_M};
count = 6'd60;
flag = 1;
end
else if(!set1)
begin
count_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;
end
else
begin
if(flag6 == 0)
begin
if(flag5)
begin
if(flag4)
begin
if(tmp_M == 59)
begin
tmp_M = 6'd0;
if (tmp_F == 59)
begin
tmp_F = 6'd0;
if(tmp_S == 23) tmp_S = 6'd0;
else tmp_S = tmp_S + 1;
end
else tmp_F = tmp_F + 1;
end
end
else tmp_M = tmp_M + 1;
if ((tmp_S == MB_S) && (tmp_F == MB_F) &&(tmp_M == MB_M)) flag4 = 0;
end
else
begin
if(flag4)
begin
if(tmp_M == 6'd0)
begin
if(tmp_F == 6'd0)
begin
if(tmp_S == 6'd0) flag4 = 0;
else
begin
tmp_S = tmp_S - 1;
tmp_F = 6'd59;
end
end
else
begin
tmp_F = tmp_F - 1;
tmp_M = 6'd59;
end
end
else tmp_M = tmp_M - 1;
end
end
end
else
begin
if(count_M == 59)
begin
count_M = 0;
if (count_F == 59)
begin
count_F = 0;
if(count_S == 23) count_S = 0;
else count_S = count_S + 1;
end
else count_F = count_F + 1;
end
else 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;
end
else flag = 1;
tmp_S = count_S;
tmp_M = count_M;
tmp_F = count_F;
tmp_WD = count_S;
flag4 = 1;
end
end
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)
begin
if (count == 24999999)
begin
count = 0;
clk1 = ~clk1;
end
else 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)
begin
if(in) cs = s4;
else cs = ns;
end
always@(cs)
begin
case(cs)
s0:ns = s1;
s1:ns = s2;
s2:ns = s3;
s3:ns = s4;
s4:ns = s0;
endcase
end
always@(cs)
begin
case(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)
begin
case(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)
begin
if(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)
begin
if(flag5)
begin
if(flag4)
begin
if(tmp_M == 59)
begin
tmp_M = 0;
if (tmp_F == 59)
begin
tmp_F = 0;
if(tmp_S == 23) tmp_S = 0;
else tmp_S = tmp_S + 1;
end
else tmp_F = tmp_F + 1;
end
else tmp_M = tmp_M + 1;
if ((tmp_S == MB_S) && (tmp_F == MB_F) &&(tmp_M == MB_M)) flag4 = 0;
end
end
else
begin
if(flag4)
begin
if(tmp_M == 0)
begin
if(tmp_F == 0)
begin
if(tmp_S == 0) flag4 = 0;
else
begin
tmp_S = tmp_S - 1;
tmp_F = 6'd59;
end
end
else
begin
tmp_F = tmp_F - 1;
tmp_M = 6'd59;
end
end
else tmp_M = tmp_M - 1;
end
end
end
else if(!flag1)
begin
if(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;
end
else if(flag3)
begin
tmp_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;
end
end
else