一.模块设计图
![在这里插入图片描述](https://img-blog.csdnimg.cn/41e6203a2d07457281144998415b0d7a.png#pic_center)
二.设计思路
2.1计数器设计
- 设计四个计数器,第一个计50_000_000,表示计满1s;第二个计数器计数秒位;第三个计数器计数分钟位;第四个计数器计数小时位。
- 计数器+1标志:秒计数器当计满一秒+1,分钟计数器当秒计数器计满60时+1,小时计数器当分钟计数器计满60时+1;所有计数器当计满清零。
2.2时序图
![在这里插入图片描述](https://img-blog.csdnimg.cn/ce63b13639ae4756b52af36d1d274ba0.png#pic_center)
2.3传输数据
- time_count模块有三个输出:[4:0]hour、[5:0]min、[5:0]sec。传输给seg_dirver模块。每一位数据如下:
![在这里插入图片描述](https://img-blog.csdnimg.cn/37f7954cc4ef42da846fd28034740069.png#pic_center)
2.4余晖效应
- 计数器计1ms,数码管每隔1ms做位拼接,肉眼无法分辨1ms的数码管位选变化,在视觉上就是数码管全亮的状态。
2.5设定小数点位
- point_n可以在顶层模块例化模块是直接给它赋值,将数值位设为7位,考察data时(case(data))将小数点位和数值位拼接起来。可以实现小数点固定位亮。
![在这里插入图片描述](https://img-blog.csdnimg.cn/f6f3208153af4e678503e4b3a45a3c19.png#pic_center)
![在这里插入图片描述](https://img-blog.csdnimg.cn/6071401937c64d68893ab097cd65bfd6.png#pic_center)
三.代码
/**************************************功能介绍***********************************
Date : 2023年8月2日11:17:33
Author : Alegg xy.
Version : 1.0
Description:
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module time_count(
input clk ,
input rst_n ,
output [4:0] hour ,
output [5:0] min ,
output [5:0] sec
);
//---------<参数定义>---------------------------------------------------------
parameter MAX = 26'd50_000_000;//1s
parameter MAX_sec = 6'd59;//一分钟60秒
parameter MAX_min = 6'd59;//1小时60分钟
parameter MAX_hour = 5'd23;//1天24小时
//---------<内部信号定义>-----------------------------------------------------
reg [25:0] cnt ;
wire add_cnt ;
wire end_cnt ;
reg [5:0] cnt_sec ;
wire add_cnt_sec ;
wire end_cnt_sec ;
reg [5:0] cnt_min ;
wire add_cnt_min ;
wire end_cnt_min ;
reg [4:0] cnt_hour ;
wire add_cnt_hour;
wire end_cnt_hour;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt <= 'd0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= 'd0;
end
else begin
cnt <= cnt + 1'd1;
end
end
end
assign add_cnt = 1'b1;
assign end_cnt = add_cnt && cnt == MAX - 1'd1;
//秒计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_sec <= 'd0;
end
else if(add_cnt_sec)begin
if(end_cnt_sec)begin
cnt_sec <= 'd0;
end
else begin
cnt_sec <= cnt_sec + 1'd1;
end
end
end
assign add_cnt_sec = end_cnt;
assign end_cnt_sec = add_cnt_sec && cnt_sec == MAX_sec;
//分计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_min <= 'd0;
end
else if(add_cnt_min)begin
if(end_cnt_min)begin
cnt_min <= 'd0;
end
else begin
cnt_min <= cnt_min + 1'd1;
end
end
end
assign add_cnt_min = end_cnt_sec;
assign end_cnt_min = add_cnt_min && cnt_min == MAX_min;
//小时计数器
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_hour <= 'd0;
end
else if(add_cnt_hour)begin
if(end_cnt_hour)begin
cnt_hour <= 'd0;
end
else begin
cnt_hour <= cnt_hour + 1'd1;
end
end
end
assign add_cnt_hour = end_cnt_min;
assign end_cnt_hour = add_cnt_hour && cnt_hour == MAX_hour;
assign hour = cnt_hour;
assign min = cnt_min;
assign sec = cnt_sec;
endmodule
/**************************************功能介绍***********************************
Date : 2023年8月2日13:44:09
Author : Alegg xy.
Version : 1.0
Description:
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module seg_driver(
input clk ,
input rst_n ,
input [4:0] hour ,
input [5:0] min ,
input [5:0] sec ,
input [5:0] point_n ,
output reg [5:0] sel ,
output reg [7:0] seg
);
//---------<参数定义>---------------------------------------------------------
parameter MAX_1ms = 50_000;//1ms
//---------<内部信号定义>-----------------------------------------------------
reg [3:0] data;//存数据
reg [5:0] point_n_r;//存小数点位
reg [15:0] cnt_1ms ;
wire add_cnt_1ms ;
wire end_cnt_1ms ;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt_1ms <= 'd0;
end
else if(add_cnt_1ms)begin
if(end_cnt_1ms)begin
cnt_1ms <= 'd0;
end
else begin
cnt_1ms <= cnt_1ms + 1'b1;
end
end
end
assign add_cnt_1ms = 1'b1;
assign end_cnt_1ms = add_cnt_1ms && cnt_1ms == MAX_1ms - 1'd1;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
sel <= 6'b111_110;
end
else if (end_cnt_1ms) begin
sel <= {sel[4:0],sel[5]};
end
end
always @(*)begin
case (sel)
6'b111_110:begin data = hour / 10; point_n_r = point_n[0]; end
6'b111_101:begin data = hour % 10; point_n_r = point_n[1]; end
6'b111_011:begin data = min / 10 ; point_n_r = point_n[2]; end
6'b110_111:begin data = min % 10 ; point_n_r = point_n[3]; end
6'b101_111:begin data = sec / 10 ; point_n_r = point_n[4]; end
6'b011_111:begin data = sec % 10 ; point_n_r = point_n[5]; end
default: data = 4'd0;
endcase
end
always @(*)begin
case (data)
4'h0:seg = {point_n_r,7'b100_0000};
4'h1:seg = {point_n_r,7'b111_1001};
4'h2:seg = {point_n_r,7'b010_0100};
4'h3:seg = {point_n_r,7'b011_0000};
4'h4:seg = {point_n_r,7'b001_1001};
4'h5:seg = {point_n_r,7'b001_0010};
4'h6:seg = {point_n_r,7'b000_0010};
4'h7:seg = {point_n_r,7'b111_1000};
4'h8:seg = {point_n_r,7'b000_0000};
4'h9:seg = {point_n_r,7'b001_0000};
default: seg = 8'b1100_0000;
endcase
end
endmodule
/**************************************功能介绍***********************************
Date : 2023年8月2日13:58:10
Author : Alegg xy.
Version : 1.0
Description:
*********************************************************************************/
//---------<模块及端口声名>------------------------------------------------------
module top_clock(
input clk ,
input rst_n ,
input [5:0] point_n ,
output [5:0] sel ,
output [7:0] seg
);
//---------<参数定义>---------------------------------------------------------
wire [4:0] hour_link;
wire [5:0] min_link;
wire [5:0] sec_link;
//---------<内部信号定义>-----------------------------------------------------
time_count u_time_count(
.clk (clk),
.rst_n (rst_n),
.hour (hour_link),
.min (min_link),
.sec (sec_link)
);
seg_driver u_seg_dirver(
.clk (clk),
.rst_n (rst_n),
.hour (hour_link),
.min (min_link),
.sec (sec_link),
.point_n (6'b110101),
.sel (sel),
.seg (seg)
);
endmodule
eg_dirver(
.clk (clk),
.rst_n (rst_n),
.hour (hour_link),
.min (min_link),
.sec (sec_link),
.point_n (6'b110101),
.sel (sel),
.seg (seg)
);
endmodule