最近秋招遇到了好几次这个的笔试题,其实还是比较简单的。关键还是计数器的写法,所以做下总结,之后不论是秋招还是实习面试笔试,尽量可以把这个送分题拿到。
一、题目描述
基于f = 100Hz的Clock设计一个数字时钟,用Verilog实现,产生时、分、秒的计时。
分析:
前提,首先将100hz倍频为1hz的时钟,这样一拍就是1s了。
其实就是一个 进位操作,设置hour、minute、second三个进位标志,second计数器记满60清零,second计数器记满60时,minute计数器加1。当minute记满60且second记满60时,hour加1且minute清零。当hour计数器记满24时,且minute记满60,second记满60时,hour清零。
二、RTL级描述
module clock (
input clk,
input rst_n,
output reg[5:0]hour,
output reg[5:0]minute,
output reg[5:0]second
);
// 产生1hz时钟
reg[6:0] clk_cnt;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
clk_cnt <= 0;
else if (clk_cnt == 99)
clk_cnt <= 0;
else
clk_cnt <= clk_cnt + 1;
end
reg clk1;
always @(posedge clk or negedge rst_n) begin
if(!rst_n)
clk1 <= 0;
else if(clk_cnt < 50)
clk <= 0;
else
clk <= 1;
end
// 秒模块
always @(posedge clk1 or negedge rst_n) begin
if(!rst_n)
second <= 0;
else if(second == 59)
second <= 0;
else
second <= second + 1;
end
// 分模块
always @(posedge clk1 or negedge rst_n) begin
if(!rst_n)
minute <= 0;
else if((minute == 59)&&(second == 59))
minute <= 0;
else if(second == 59)
minute <= minute + 1;
end
// 时模块
always @(posedge clk1 or negedge rst_n) begin
if(!rst_n)
hour <= 0;
else if((minute == 59)&&(second == 59)&&(hour == 23))
hour <= 0;
else if((minute == 59)&&(second == 59))
hour <= hour + 1;
end
endmodule
三、添加设置功能
可通过3个按键来设置时、分、秒值。
module clock(
input clk,
input rst_n,
input hour_set,
input [4:0] hour_set_value,
input minute_set,
input [5:0] minute_set_value,
input second_set,
input [5:0] second_set_value,
output reg [4:0] hour,
output reg [5:0] minute,
output reg [5:0] second
)
reg clk_1;
reg [6:0] cnt;
// get 1HZ clk
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
cnt <= 0;
else if(cnt == 99)
cnt <= 0;
else
cnt <= cnt + 1;
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
clk_1 <= 0;
else if(cnt < 50)
clk_1 <= 0;
else
clk_1 <= 1;
end
always@(posedge clk_1 or negedge rst_n) begin
if(!rst_n)
second <= 0;
else begin
if(second_set)
second <= second_set_value;
else if(second == 59)
second <= 0;
else
second <= second + 1;
end
end
always@(posedge clk_1 or negedge rst_n) begin
if(!rst_n)
minute <= 0;
else begin
if(minute_set)
minute <= minute_set_value;
else if( (minute==59) && (second==59) )
minute <= 0;
else if(second==59)
minute <= minute + 1;
end
end
always@(posedge clk_1 or negedge rst_n) begin
if(!rst_n)
hour <= 0;
else begin
if(hour_set)
hour <= hour_set_value;
else if( (hour==23) && (minute==59) && (second==59) )
hour <= 0;
else if((minute==59) && (second==59))
hour <= hour + 1;
end
end
endmodule