一、实验目的:
1、利用QuartusⅡ软件编写Verilog HDL代码实现数字钟的基本功能,并进行波形仿真与电路分析。
2、利用已经实现基本功能的Verilog HDL代码下载到DE0开发板中进行功能验证。
二、实验要求:
1、要求设置的数字钟能够正常计数且具有调时、调分的基本功能。
2、数字钟为24小时制,只显示小时和分钟,不显示秒钟。
3、数字钟上共有3个按钮,分别为Button0、Button1、Button2,1个异步清零控制开 关。3个按钮的作用为:当Button0最初没有按下时,时钟正常计时,无论Button1或 Button2是否被按下,都对数字钟的计时没有影响;当按一下Button0时,进行分钟的 调整,按下Button1分钟加1,且当分钟显示为59时,按下后分钟变为0,小时不改 变;按下Button2分钟减1,且当分钟显示为0时,按下后分钟变为59,小时不改变; 当再按一下Button0时,进行小时的调整,按下Button1小时加1,且当小时显示为23 时,按下后小时变为0,分钟不改变;按下Button2小时减1,且当小时显示为0时,按 下后小时变为23,分钟不改变。
4、利用QuartusⅡ软件编写Verilog HDL代码实现上述数字钟的基本功能,并利用DE0 开发板进行功能验证。
三、实验思路
1、该实验为硬件语言编程,应该抛弃原有的软件编程的逻辑思维,首先着手电路设 计。
2、该实验利用同步时钟的方式进行调时、调分的控制。
3、分步进行电路设计,采用模块化的编程方式,使电路结构更加清晰,便于调试。 4、实验一共可分为六大模块:使能控制模块、译码模块、分钟计时模块、小时计时模 块、时钟选择模块、时钟分频模块。
5、各个模块的功能如下:① 使能控制模块:通过识别Button0被按下的次数,来得到 计数器的使能端的信号,以此来确定控制哪一个计数器,并具有调时调分的功能,故 使能端的个数应该为两个:EN1与EN2。② 时钟分频模块:根据查阅DE0开发板的使 用手册可知,DE0开发板上晶振产生的时钟频率为50MHz,而我们需要1/60 Hz的时钟 信号,故需要对其进行分频操作。③ 译码模块:将输出的四个四位二进制码转化成为 四个七位的二进制代码,控制数码管的显示。④ 时钟选择模块:本次设计是基于同步 时钟进行加减调时调分的功能,所以需要根据使能端的信号来选择相应的时钟信号。 ⑤ 分钟计时模块:进行正常的分钟计数,和根据使能端信号和按键的信号来控制调分 的加减功能。⑥ 小时计时模块:进行正常的计时功能,和根据使能端信号和按键的信 号来控制调时的加减功能。
6、通过模块化编程,将六大模块进行相应的连接,并用Verilog语言编写在顶层文件 中。
7、将Verilog语言进行综合,并设置波形,观察仿真情况和电路。
8、将功能仿真正确的文件下载至DE0开发板进行实际的功能验证。
四、实验步骤:
设计使能电路。由Button0第一次按下为调整分钟的状态,第二次按下为调整小时的状 态,第三次按下恢复到正常计数状态,以后往复循环。所以一共有3个状态,故需2个 使能端,且当(EN1^EN20)时正常计数 (!EN1&EN21)时进行调整分钟,(EN1&! EN2==1)时进行调整小时。
module EN_ctr(Button1,RE,EN1,EN2);
input Button1,RE;
output EN1,EN2;
reg [1:0] count;
reg EN1,EN2;
always @(negedge Button1,negedge RE)
begin
if(!RE) count <= 2'b00;
else
begin
if(count!=2'b10) count<=count+2'b01;
else count<=2'b00;
end
end
always @ *
begin
case(count)
2'b00:begin
EN1<=1;
EN2<=1;
end
2'b01:begin
EN1<=0;
EN2<=1;
end
2'b10:begin
EN1<=1;
EN2<=0;
end
default:
begin EN1<=1;EN2<=1;end
endcase
end
endmodule
2、设计时钟选择电路。当且仅当(EN1^EN2==0)时,进入到计数器的时钟为正常时钟,否则:(1) 当Button1或Button2按下时,时钟产生上升沿。
则此时的时钟为!(Button1&Button2)
module mux(CLK,Add,Sub,EN1,EN2,CLK_op);
input CLK,Add,Sub,EN1,EN2;
output CLK_op;
reg CLK_op;
always @ *
begin
if(~(EN1^EN2)) CLK_op = CLK;
else CLK_op = ~(Add&Sub);
end
endmodule
3、设计译码电路
module dec4_7(in,out);
input [3:0] in;
output [6:0] out;
reg [6:0] out;
always @ *
begin
case(in)
4'b0000:out=7'b0000001;
4'b0001:out=7'b1111001;
4'b0010:out=7'b0010010;
4'b0011:out=7'b0000110;
4'b0100:out=7'b1001100;
4'b0101:out=7'b0100100;
4'b0110:out=7'b0100000;
4'b0111:out=7'b0001111;
4'b1000:out=7'b0000000;
4'b1001:out=7'b0000100;
4'b1010:out=7'b0010010;
4'b1011:out=7'b0000110;
4'b1100:out=7'b1001100;
4'b1101:out=7'b0100100;
4'b1110:out=7'b0100000;
4'b1111:out=7'b0001111;
default:out=7'b1111111;
endcase
end
endmodule
4、设计时钟分频模块
module CLK_50M_to_1(CLK_in,RESET,CLK_out);
input CLK_in,RESET;
output CLK_out;
reg [37:0] c_in;
reg CLK_out_t;
always @(posedge CLK_in,negedge RESET)
begin
if(!RESET) begin c_in<=37'd0;CLK_out_t<=0;end
else if(c_in!=28'd5000_0000)
begin
c_in<=c_in+28'd0000_0001;
end
else begin c_in<=28'd0;CLK_out_t<=~CLK_out_t;end
end
assign CLK_out = CLK_out_t;
endmodule
5、设计分钟计时模块。该模块应该具有以下功能:
① 当状态,即使能端 ~(EN1^EN2) 为真时,该模块正常计数。② 当使能端 EN1^EN2 为真时,进行该模块的计时调整,且无进位功能。③ 当使能端 ~EN1&EN2 为真时,当计时+1键(Add)按下时,进行分钟加1的操作,当计时-1键(Sub)按下时,进行分钟减1的操作。④ 当使能端 EN1&~EN2 为真时,无论是否按下计时+1键或者计时-1键,分钟都保持不变,且不会正常计数。⑤ 当异步清零端有效时,时钟清零。⑥ 由于采用4个译码管,故计时设置为2个4位输出,一个表示十位,一个表示个位。由以上所描述的功能,且为同步时钟模式,故可设计代码如下:
module time_60(CLK,RE,EN1,EN2,Add,Sub,CO,op1,op2);
input CLK,RE,EN1,EN2,Add,Sub;
output reg [3:0] op1,op2;
output reg CO;
always @(posedge CLK,negedge RE)
begin
if(!RE) begin op1<=4'd0;op2<=4'd0;CO<=0;end
else if(EN1&EN2)
begin
if(op1!=4'd9) begin op1<=op1+4'd1;op2<=op2;CO<=0;end
else
begin
if(op2!=4'd5) begin op2<=op2+4'd1;op1<=4'd0;CO<=0;end
else begin op2<=4'd0;op1<=4'd0;CO<=1;end
end
end
else if(~EN1&EN2)
begin
CO<=0;
if(!Add)
begin
if(op1!=4'd9) begin op1<=op1+4'd1;op2<=op2;end
else
begin
if(op2!=4'd5) begin op2<=op2+4'd1;op1<=4'd0;end
else begin op2<=4'd0;op1<=4'd0;end
end
end
else if(!Sub)
begin
if(op1!=4'd0) begin op1<=op1-4'd1;op2<=op2;end
else
begin
if(op2!=4'b0) begin op2<=op2-4'd1;op1<=4'd9;end
else begin op2<=4'd5;op1<=4'd9;end
end
end
else begin op1<=op1;op2<=op2;end
end
else begin op1<=op1;op2<=op2;CO<=CO;end
end
endmodule
6、设计小时计时模块。该模块应该具有以下功能:① 当状态,即使能端 ~(EN1^EN2) 为真时,该模块正常计数。② 当使能端 EN1&~EN2 为真时,当计时+1键(Add)按下时,进行分钟加1的操作,当计时-1键(Sub)按下时,进行分钟减1的操作。③ 当使能端 ~EN1&EN2 为真时,无论是否按下计时+1键或者计时-1键,分钟都保持不变,且不会正常计数。④ 当异步清零端有效时,时钟清零。⑤ 由于采用4个译码管,故计时设置为2个4位输出,一个表示十位,一个表示个位。⑥ 由以上所描述的功能,且为同步时钟模式,故可设计代码如下:
module time_24(CLK,RE,EN1,EN2,Add,Sub,op1,op2);
input CLK,RE,EN1,EN2,Add,Sub;
output reg [3:0] op1,op2;
always @(posedge CLK,negedge RE)
begin
if(!RE) begin op1<=4'd0;op2<=4'd0;end
else if((EN1&EN2)|(EN1&~Add))
begin
if(op2!=4'd2)
begin
if(op1!=4'd9) begin op1<=op1+4'd1;op2<=op2;end
else begin op1<=4'd0;op2<=op2+4'd1;end
end
else
begin
if(op1!=4'd3) begin op2<=op2;op1<=op1+4'd1;end
else begin op2<=4'd0;op1<=4'd0;end
end
end
else if(~EN2&EN1)
begin
if(!Sub)
begin
if(op1!=4'd0) begin op1<=op1-4'd1;op2<=op2;end
else
begin
if(op2!=4'b0) begin op2<=op2-4'd1;op1<=4'd9;end
else begin op2<=4'd2;op1<=4'd3;end
end
end
else if(!Add)
begin
if(op2!=4'd2)
begin
if(op1!=4'd9) begin op1<=op1+4'd1;op2<=op2;end
else begin op1<=4'd0;op2<=op2+4'd1;end
end
else
begin
if(op1!=4'd3) begin op2<=op2;op1<=op1+4'd1;end
else begin op2<=4'd0;op1<=4'd0;end
end
end
else begin op1<=op1;op2<=op2;end
end
else begin op1<=op1;op2<=op2;end
end
endmodule
7、顶层文件模块。该模块完成整个电路的连接。
module Clock(CLK_in,RE,Button1,Button2,Button3,min_1,min_2,hour_1,hour_2);
input CLK_in,RE,Button1,Button2,Button3;
output [6:0] min_1,min_2,hour_1,hour_2;
wire EN1,EN2;
wire clk_in1,clk_in2,CO;
wire [3:0] min_low,min_high,hour_low,hour_high;
CLK_50M_to_1(CLK_in,RE,CLK);
EN_ctr(Button1,RE,EN1,EN2);
mux(CLK,Button2,Button3,EN1,EN2,clk_in1);
time_60(clk_in1,RE,EN1,EN2,Button2,Button3,CO,min_low,min_high);
mux(CO,Button2,Button3,EN1,EN2,clk_in2);
time_24(clk_in2,RE,EN1,EN2,Button2,Button3,hour_low,hour_high);
dec4_7(min_low,min_1);
dec4_7(min_high,min_2);
dec4_7(hour_low,hour_1);
dec4_7(hour_high,hour_2);
endmodule
9、对DE0开发板器件CycloneⅢ系列的EP3C16F484C6 配置管脚并将程序下载至开发板中,经试验验证可知方案正确。