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.
module top_module(
input clk,
input reset,
input ena,
output reg pm,
output reg [7:0] hh,
output reg [7:0] mm,
output reg [7:0] ss);
reg en_mm;
reg en_hh;
//秒计时器
always@(posedge clk)
if(reset)
ss <= 8'd0;
else begin
if(ena) begin
if(ss[3:0]== 4'd9)begin
ss[3:0] <= 4'd0;
if(ss[7:4]==4'd5)
ss[7:4] <= 4'd0;
else
ss[7:4] <= ss[7:4] + 1'b1;
end
else
ss[3:0] <= ss[3:0] + 1'b1;
end
end
//分计时器
always@(posedge clk)
if(reset)
mm <= 8'd0;
else begin
if(en_mm) begin
if(mm[3:0]==4'd9) begin
mm[3:0] <= 4'd0;
if(mm[7:4]==4'd5)
mm[7:4] <= 4'd0;
else
mm[7:4] <= mm[7:4] + 1'b1;
end
else
mm[3:0] <= mm[3:0] + 1'b1;
end
end
//小时计时器
always@(posedge clk)
if(reset) begin
hh <= 8'h12;
end
else begin
if(en_hh)begin
if(hh == 8'h12) begin
hh <= 8'h01;
end
else begin
if(hh[3:0]==4'd9)begin
hh[3:0] <= 4'd0;
hh[7:4] <= hh[7:4] + 1'b1;
end
else
hh[3:0] <= hh[3:0] + 1'b1;
end
end
end
//计时使能信号控制模块
always@(posedge clk)
if(reset) begin
en_mm <= 0;
en_hh <= 0;
end
else begin
if(ss==8'h58)begin
en_mm <= 1;
if(mm== 8'h59)
en_hh <= 1;
else
en_hh <= 0;
end
else begin
en_mm <= 0;
en_hh <= 0;
end
end
always@(posedge clk)
if(reset)
pm<=0;
else begin
if(hh==8'h11&&mm==8'h59&&ss==8'h59)
pm <= ~pm;
else
pm <= pm;
end
endmodule