交综合实验之数字时钟数码管显示作业(带有复位和置位)
设计之前的模型框图:
设计源代码:
顶层:
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: Charles Wang // // Create Date: 11/3/2014 // Design Name: Digital Clock // Module Name: digital_clock // Project Name: digital_clock // Target Devices: EP4CE6E22C8 // Tool versions: Quartus II 12.0 64bit // Description: 带时/分置位按键及复位按键的数字时钟--顶层模块 // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module digital_clock(sys_clk,sys_rst_n,minu_pre,hour_pre,sel,seg); input sys_clk;//50MHz 总线时钟 input sys_rst_n;//异步复位,低有效 input minu_pre;//分预设 input hour_pre;//时预设 output [7:0]sel;//数码管位选 output [7:0]seg;//数码管段选 wire sec_clk_w; wire [6:0]second_w; wire [6:0]minute_w; wire [6:0]hour_w; freq_div Div(.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.sec_clk(sec_clk_w)); cnt_module Cnt(.sec_clk(sec_clk_w),.sys_clk(sys_clk),.sys_rst_n(sys_rst_n), .minu_pre(minu_pre),.hour_pre(hour_pre),.second(second_w),.minute(minute_w), .hour(hour_w)); sm_seg Seg(.sys_clk(sys_clk),.sys_rst_n(sys_rst_n),.second(second_w), .minute(minute_w),.hour(hour_w),.seg(seg),.sel(sel)); endmodule
分频模块:
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: Charles Wang // // Create Date: 11/3/2014 // Design Name: Digital Clock // Module Name: freq_div // Project Name: digital_clock // Target Devices: EP4CE6E22C8 // Tool versions: Quartus II 12.0 64bit // Description: 带时/分置位按键及复位按键的数字时钟--分频模块 // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module freq_div(sys_clk,sys_rst_n,sec_clk); input sys_clk;//50MHz 总线时钟 input sys_rst_n;//异步复位,低有效 output sec_clk;//输出秒时钟 reg [27:0]cnt; reg sec_clk_r; parameter T1S = 28'd2500_0000; ////////////////////////////////////////////////////////////////////////////////// //分频产生秒信号 always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) begin cnt <= 28'd0; sec_clk_r <= 1'b0; end else if(cnt == T1S - 1'b1) begin cnt <= 28'd0; sec_clk_r <= ~ sec_clk_r; end else begin cnt <= cnt + 1'b1; end end assign sec_clk = sec_clk_r; endmodule
时钟计数及置位模块:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer: Charles Wang
//
// Create Date: 11/3/2014
// Design Name: Digital Clock
// Module Name: cnt_module
// Project Name: digital_clock
// Target Devices: EP4CE6E22C8
// Tool versions: Quartus II 12.0 64bit
// Description: 带时/分置位按键及复位按键的数字时钟--时钟计时及置位模块
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module cnt_module(sec_clk,sys_clk,sys_rst_n,minu_pre,hour_pre,hour,minute,second);
input sec_clk;//秒时钟输入
input sys_clk;//50MHz总线时钟
input sys_rst_n;//异步复位,低有效
input minu_pre;//分预置信号
input hour_pre;//时预置信号
output [6:0]second;//输出秒信号
output [6:0]minute;//输出分信号
output [6:0]hour;//输出小时信号
parameter T100MS = 24'd500_0000;//100ms用于过滤按键抖动
reg M1,M2;
reg H1,H2;
reg S1,S2;
reg [6:0]second_r;
reg [6:0]minute_r;
reg [6:0]hour_r;
reg [23:0]cnt1;
reg [23:0]cnt2;
reg isMinu_Pre;
reg isHour_Pre;
reg [2:0]i;
reg [2:0]j;
reg flag1;
reg flag2;
wire isMH2L;
wire isML2H;
wire isHH2L;
wire isHL2H;
wire Sec_L2H;
//////////////////////////////////////////////////////////////////////////////////
//分别用isMinu_Pre/isHour_Pre 作为分/时预设按键的下降沿标志信号
//用Sec_L2H 作为秒时钟的上升沿信号
always@(posedge sys_clk or negedge sys_rst_n)
begin
if(!sys_rst_n)
begin
{M1,M2} <= 2'b11;
end
else
begin
{M2,M1} <= {M1,minu_pre};
end
end
assign isMH2L = (M2 == 1'b1) && (M1 == 1'b0);
assign isML2H = (M2 == 1'b0) && (M1 == 1'b1);
always@(posedge sys_clk or negedge sys_rst_n)//对minu_pre 进行按键消抖
begin
if(!sys_rst_n)
begin
i <= 3'd0;
isMinu_Pre <= 1'b0;
flag1<= 1'b0;
cnt1 <= 24'd0;
end
else
case(i)
3'd0: if(isMH2L)
begin
i <= i + 1'b1;
end
3'd1: if(cnt1 == T100MS - 1'b1)
begin
cnt1 <= 24'd0;
i <= i + 1'b1;
end
else
begin
cnt1 <= cnt1 + 1'b1;
end
3'd2: if(isML2H)
begin
i <= i + 1'b1;
end
3'd3: if(cnt1 == T100MS - 1'b1)
begin
cnt1 <= 24'd0;
i <= i + 1'b1;
flag1<= 1'b1;
end
else
begin
cnt1 <= cnt1 + 1'b1;
end
3'd4: if(flag1 == 1'b1)
begin
isMinu_Pre <= 1'b1;
i <= i + 1'b1;
end
3'd5: begin
i <= i + 1'b1;
isMinu_Pre <= 1'b0;
end
3'd6: begin
i <= 3'd0;
flag1 <= 1'b0;
end
default: i <= 3'd0;
endcase
end
always@(posedge sys_clk or negedge sys_rst_n)
begin
if(!sys_rst_n)
begin
{H1,H2} <= 2'b11;
end
else
begin
{H2,H1} <= {H1,hour_pre};
end
end
assign isHH2L = (H2 == 1'b1) && (H1 == 1'b0);
assign isHL2H = (H2 == 1'b0) && (H1 == 1'b1);
always@(posedge sys_clk or negedge sys_rst_n)//对hour_pre 进行按键消抖
begin
if(!sys_rst_n)
begin
j <= 3'd0;
isHour_Pre <= 1'b0;
flag2<= 1'b0;
cnt2 <= 24'd0;
end
else
case(j)
3'd0: if(isHH2L)
begin
j <= j + 1'b1;
end
3'd1: if(cnt2 == T100MS - 1'b1)
begin
cnt2 <= 24'd0;
j <= j + 1'b1;
end
else
begin
cnt2 <= cnt2 + 1'b1;
end
3'd2: if(isHL2H)
begin
j <= j + 1'b1;
end
3'd3: if(cnt2 == T100MS - 1'b1)
begin
cnt2 <= 24'd0;
j <= j + 1'b1;
flag2<= 1'b1;
end
else
begin
cnt2 <= cnt2 + 1'b1;
end
3'd4: if(flag2 == 1'b1)
begin
isHour_Pre <= 1'b1;
j <= j + 1'b1;
end
3'd5: begin
j <= j + 1'b1;
isHour_Pre <= 1'b0;
end
3'd6: begin
j <= 3'd0;
flag2 <= 1'b0;
end
default: j <= 3'd0;
endcase
end
always@(posedge sys_clk or negedge sys_rst_n)
begin
if(!sys_rst_n)
begin
{S1,S2} <= 2'b11;
end
else
begin
{S2,S1} <= {S1,sec_clk};
end
end
assign Sec_L2H = (S2 == 1'b0) && (S1 == 1'b1);
//////////////////////////////////////////////////////////////////////////////////
//时钟计数及预设部分
always@(posedge sys_clk or negedge sys_rst_n)
begin
if(!sys_rst_n)
begin
second_r <= 7'h0;
minute_r <= 7'h0;
hour_r <= 7'h0;
end
else if(isMinu_Pre)//对分进行预设
begin
if(minute_r[3:0] == 4'h9)
begin
if(minute_r[6:4] == 3'h5)
begin
minute_r <= 7'h0;
end
else
begin
minute_r[6:4] <= minute_r[6:4] + 1'b1;
minute_r[3:0] <= 4'h0;
end
end
else
begin
minute_r[3:0] <= minute_r[3:0] + 1'b1;
end
end
else if(isHour_Pre)//对时进行预设
begin
if(hour_r[3:0] == 4'h3 && hour_r[6:4] == 3'h2)
begin
hour_r <= 7'h0;
end
else if(hour_r[6:4] < 3'h2 && hour_r[3:0] == 4'h9)
begin
hour_r[3:0] <= 4'h0;
hour_r[6:4] <= hour_r[6:4] + 1'b1;
end
else
begin
hour_r[3:0] <= hour_r[3:0] + 1'b1;
hour_r[6:4] <= hour_r[6:4];
end
end
else if(Sec_L2H)//时钟计数部分
begin
if(second_r[3:0] == 4'h9)
begin
if(second_r[6:4] == 3'h5)
begin
if(minute_r[3:0] == 4'h9)
begin
if(minute_r[6:4] == 3'h5)
begin
if(hour_r[6:4] == 4'h2 && hour_r[3:0] == 4'h3)
begin
hour_r <= 7'h0;
minute_r <= 7'h0;
second_r <= 7'h0;
end
else if(hour_r[6:4] < 3'h2 && hour_r[3:0] == 4'h9)
begin
hour_r[3:0] <= 4'h0;
hour_r[6:4] <= hour_r[6:4] + 1'b1;
minute_r <= 7'h0;
second_r <= 7'h0;
end
else
begin
hour_r[3:0] <= hour_r[3:0] + 1'b1;
hour_r[6:4] <= hour_r[6:4];
minute_r <= 7'h0;
second_r <= 7'h0;
end
end
else
begin
hour_r <= hour_r;
minute_r[6:4] <= minute_r[6:4] + 1'b1;
minute_r[3:0] <= 4'h0;
second_r <= 7'h0;
end
end
else
begin
hour_r <= hour_r;
minute_r[3:0] <= minute_r[3:0] + 1'b1;
minute_r[6:4] <= minute_r[6:4];
second_r <= 7'h0;
end
end
else
begin
hour_r <= hour_r;
minute_r <= minute_r;
second_r[6:4] <= second_r[6:4] + 1'b1;
second_r[3:0] <= 4'h0;
end
end
else
begin
hour_r <= hour_r;
minute_r <= minute_r;
second_r[6:4] <= second_r[6:4];
second_r[3:0] <= second_r[3:0] + 1'b1;
end
end
else
begin
hour_r <= hour_r;
minute_r <= minute_r;
second_r <= second_r;
end
end
assign hour = hour_r;
assign minute = minute_r;
assign second = second_r;
endmodule
数码管驱动模块:
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: Charles Wang // // Create Date: 11/4/2014 // Design Name: Digital Clock // Module Name: sm_seg // Project Name: digital_clock // Target Devices: EP4CE6E22C8 // Tool versions: Quartus II 12.0 64bit // Description: 带时/分置位按键及复位按键的数字时钟--数码管驱动模块 // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module sm_seg(sys_clk,sys_rst_n,second,minute,hour,seg,sel); input sys_clk;//总线时钟50MHz input sys_rst_n;//异步复位,低有效 input[6:0]second;//秒数据 input[6:0]minute;//分数据 input[6:0]hour;//时数据 output [7:0]seg;//输出段码驱动数据 output [7:0]sel;//输出位码驱动数据 parameter T10MS = 16'd5_0000;//用于位选扫描 reg [7:0]seg_r; reg [7:0]sel_r; reg [2:0]cnt_scan; reg [15:0]cnt; always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) begin cnt <= 16'd0; end else if(cnt == T10MS - 1'b1) begin cnt <= 16'd0; end else begin cnt <= cnt + 1'b1; end end always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) begin cnt_scan <= 3'd0; end else if(cnt == T10MS - 1'b1) begin cnt_scan <= cnt_scan + 1'b1; end end always@(posedge sys_clk or negedge sys_rst_n)//位选扫描 begin if(!sys_rst_n) begin sel_r <= 8'd0; end else case(cnt_scan) 3'd0: sel_r <= 8'b1111_1110; 3'd1: sel_r <= 8'b1111_1101; 3'd2: sel_r <= 8'b1111_1011; 3'd3: sel_r <= 8'b1111_0111; 3'd4: sel_r <= 8'b1110_1111; 3'd5: sel_r <= 8'b1101_1111; 3'd6: sel_r <= 8'b1011_1111; 3'd7: sel_r <= 8'b0111_1111; default: sel_r <= 8'b1111_1111; endcase end reg[7:0]seg_r_sec1; reg[7:0]seg_r_sec2; reg[7:0]seg_r_minu1; reg[7:0]seg_r_minu2; reg[7:0]seg_r_hour1; reg[7:0]seg_r_hour2; always@(posedge sys_clk or negedge sys_rst_n)//段选驱动 begin if(!sys_rst_n) begin seg_r_sec1 <= 8'hff; seg_r_sec2 <= 8'hff; seg_r_minu1<= 8'hff; seg_r_minu2<= 8'hff; seg_r_hour1<= 8'hff; seg_r_hour2<= 8'hff; end else case(second[3:0]) 4'h0 : seg_r_sec1 <= 8'hc0; // "0" 4'h1 : seg_r_sec1 <= 8'hf9; // "1" 4'h2 : seg_r_sec1 <= 8'ha4; // "2" 4'h3 : seg_r_sec1 <= 8'hb0; // "3" 4'h4 : seg_r_sec1 <= 8'h99; // "4" 4'h5 : seg_r_sec1 <= 8'h92; // "5" 4'h6 : seg_r_sec1 <= 8'h82; // "6" 4'h7 : seg_r_sec1 <= 8'hf8; // "7" 4'h8 : seg_r_sec1 <= 8'h80; // "8" 4'h9 : seg_r_sec1 <= 8'h90; // "9" default : seg_r_sec1 <= 8'hff; endcase case(second[6:4]) 3'h0 : seg_r_sec2 <= 8'hc0; // "0" 3'h1 : seg_r_sec2 <= 8'hf9; // "1" 3'h2 : seg_r_sec2 <= 8'ha4; // "2" 3'h3 : seg_r_sec2 <= 8'hb0; // "3" 3'h4 : seg_r_sec2 <= 8'h99; // "4" 3'h5 : seg_r_sec2 <= 8'h92; // "5" default : seg_r_sec2 <= 8'hff; endcase case(minute[3:0]) 4'h0 : seg_r_minu1 <= 8'hc0; // "0" 4'h1 : seg_r_minu1 <= 8'hf9; // "1" 4'h2 : seg_r_minu1 <= 8'ha4; // "2" 4'h3 : seg_r_minu1 <= 8'hb0; // "3" 4'h4 : seg_r_minu1 <= 8'h99; // "4" 4'h5 : seg_r_minu1 <= 8'h92; // "5" 4'h6 : seg_r_minu1 <= 8'h82; // "6" 4'h7 : seg_r_minu1 <= 8'hf8; // "7" 4'h8 : seg_r_minu1 <= 8'h80; // "8" 4'h9 : seg_r_minu1 <= 8'h90; // "9" default : seg_r_minu1<= 8'hff; endcase case(minute[6:4]) 3'h0 : seg_r_minu2 <= 8'hc0; // "0" 3'h1 : seg_r_minu2 <= 8'hf9; // "1" 3'h2 : seg_r_minu2 <= 8'ha4; // "2" 3'h3 : seg_r_minu2 <= 8'hb0; // "3" 3'h4 : seg_r_minu2 <= 8'h99; // "4" 3'h5 : seg_r_minu2 <= 8'h92; // "5" default : seg_r_minu2 <= 8'hff; endcase case(hour[3:0]) 4'h0 : seg_r_hour1 <= 8'hc0; // "0" 4'h1 : seg_r_hour1 <= 8'hf9; // "1" 4'h2 : seg_r_hour1 <= 8'ha4; // "2" 4'h3 : seg_r_hour1 <= 8'hb0; // "3" 4'h4 : seg_r_hour1 <= 8'h99; // "4" 4'h5 : seg_r_hour1 <= 8'h92; // "5" 4'h6 : seg_r_hour1 <= 8'h82; // "6" 4'h7 : seg_r_hour1 <= 8'hf8; // "7" 4'h8 : seg_r_hour1 <= 8'h80; // "8" 4'h9 : seg_r_hour1 <= 8'h90; // "9" default : seg_r_hour1<= 8'hff; endcase case(hour[6:4]) 3'h0 : seg_r_hour2 <= 8'hc0; // "0" 3'h1 : seg_r_hour2 <= 8'hf9; // "1" 3'h2 : seg_r_hour2 <= 8'ha4; // "2" default : seg_r_hour2 <= 8'hff; endcase end always@(posedge sys_clk or negedge sys_rst_n) begin if(!sys_rst_n) begin seg_r <= 8'hff; end else case(sel_r) 8'b1111_1110: seg_r <= seg_r_sec1; 8'b1111_1101: seg_r <= seg_r_sec2; 8'b1111_1011: seg_r <= seg_r_sec1[0] ? 8'hbf:8'hff; 8'b1111_0111: seg_r <= seg_r_minu1; 8'b1110_1111: seg_r <= seg_r_minu2; 8'b1101_1111: seg_r <= seg_r_sec1[0] ? 8'hbf:8'hff; 8'b1011_1111: seg_r <= seg_r_hour1; 8'b0111_1111: seg_r <= seg_r_hour2; default : seg_r <= 8'hff; endcase end assign sel = sel_r; assign seg = seg_r; endmodule
以上就是源代码,实验视频:v.youku.com/v_show/id_XODIxNzM3NjI4.html
我要赚赏金
