HDLBits 12-hour clock
题目:
Create a set of counters suitable for use as a 12-hour clock (with am/pm indicator). Your counters are clocked by a fast-running clk, with a pulse on ena whenever your clock should increment (i.e., once per second).
reset resets the clock to 12:00 AM. pm is 0 for AM and 1 for PM. hh, mm, and ss are two BCD (Binary-Coded Decimal) digits each for hours (01-12), minutes (00-59), and seconds (00-59). Reset has higher priority than enable, and can occur even when not enabled.
The following timing diagram shows the rollover behaviour from 11:59:59 AM to 12:00:00 PM and the synchronous reset and enable behaviour.
题意
用一个周期1S的脉冲,来产生12小时进制的数字钟,并能够表示AM/PM,AM是从凌晨的12:00:00-11:59:59 ,PM是从中午的12:00:00-11:59:59是从凌晨。复位是从凌晨的12:00。
时序图
代码
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
reg [3:0] r_s0 ; //秒针的个位
reg [3:0] r_s1 ; //秒针的十位
//---秒计时
always @( posedge clk ) begin
if ( reset ) begin
r_s0 <= 4'd0 ;
end else if ( ena == 1'b1 ) begin
if ( r_s0 == 4'd9 ) begin
r_s0 <= 4'd0 ;
end else begin
r_s0 <= r_s0 + 1'b1 ;
end
end
end
always @( posedge clk ) begin
if ( reset ) begin
r_s1 <= 4'd0 ;
end else if ( ena == 1'b1 && r_s0 == 4'd9 ) begin
if ( r_s1 == 4'd5 ) begin
r_s1 <= 4'd0 ;
end else begin
r_s1 <= r_s1 + 1'b1 ;
end
end
end
//---分计时
reg [3:0] r_m0 ; //分针的个位
reg [3:0] r_m1 ; //分针的十位
always @( posedge clk ) begin
if ( reset ) begin
r_m0 <= 4'd0 ;
end else if ( ena == 1'b1 && r_s0 == 4'd9 && r_s1 == 4'd5 ) begin
if ( r_m0 == 4'd9 ) begin
r_m0 <= 4'd0 ;
end else begin
r_m0 <= r_m0 + 1'b1 ;
end
end
end
always @( posedge clk ) begin
if ( reset ) begin
r_m1 <= 4'd0 ;
end else if ( ena == 1'b1 && r_s0 == 4'd9 && r_s1 == 4'd5 && r_m0 == 4'd9 ) begin
if ( r_m1 == 4'd5 ) begin
r_m1 <= 4'd0 ;
end else begin
r_m1 <= r_m1 + 1'b1 ;
end
end
end
//---时计时
//---注意12:59小时的变化
reg [3:0] r_h0 ; //时的个位
reg [3:0] r_h1 ; //时的十位
always @( posedge clk ) begin
if ( reset ) begin
r_h0 <= 4'd2 ;
end else if (ena == 1'b1 && r_s0 == 4'd9 && r_s1 == 4'd5 && r_m0 == 4'd9 && r_m1 == 4'd5 && r_h0 == 4'd2 && r_h1 == 4'd1) begin
r_h0 <= 4'd1 ;
end else if ( ena == 1'b1 && r_s0 == 4'd9 && r_s1 == 4'd5 && r_m0 == 4'd9 && r_m1 == 4'd5 ) begin
if ( r_h0 == 4'd9 ) begin
r_h0 <= 4'd0 ;
end else begin
r_h0 <= r_h0 + 1'b1 ;
end
end
end
always @( posedge clk ) begin
if ( reset ) begin
r_h1 <= 4'd1 ;
end else if (ena == 1'b1 && r_s0 == 4'd9 && r_s1 == 4'd5 && r_m0 == 4'd9 && r_m1 == 4'd5 && r_h0 == 4'd2 && r_h1 == 4'd1) begin
r_h1 <= 4'd0 ;
end else if ( ena == 1'b1 && r_s0 == 4'd9 && r_s1 == 4'd5 && r_m0 == 4'd9 && r_m1 == 4'd5 && r_h0 == 4'd9 ) begin
r_h1 <= r_h1 + 1'b1 ;
end
end
reg r_pm ;
//中午下午指示位
always @( posedge clk ) begin
if ( reset ) begin
r_pm <= 1'b0 ;
end else if ( ena == 1'b1 && r_s0 == 4'd9 && r_s1 == 4'd5 && r_m0 == 4'd9 && r_m1 == 4'd5 && r_h0 == 4'd1 && r_h1 == 4'd1 ) begin
r_pm <= ~r_pm ;
end
end
assign hh = {r_h1,r_h0} ;
assign mm = {r_m1,r_m0} ;
assign ss = {r_s1,r_s0} ;
assign pm = r_pm ;
endmodule