交综合实验之数字时钟数码管显示作业(带有复位和置位)
设计之前的模型框图:
设计源代码:
顶层:
`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