Title:Count 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.
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:2] ena1;
bcdcount u_ss(.clk(clk),.reset(reset),.ena_in(ena),.start_state(8'h00),.change_state(8'h00),.end_state(8'h59),.out(ss),.ena_out(ena1[2]));
bcdcount u_mm(.clk(clk),.reset(reset),.ena_in(ena1[2]),.start_state(8'h00),.change_state(8'h00),.end_state(8'h59),.out(mm),.ena_out(ena1[3]));
bcdcount u_hh(.clk(clk),.reset(reset),.ena_in(&ena1),.start_state(8'h12),.change_state(8'h01),.end_state(8'h12),.out(hh),.pm(pm));
endmodule
module bcdcount(
input clk,
input reset,
input ena_in,
input [7:0] start_state,
input [7:0] change_state,
input [7:0] end_state,
output [7:0] out,
output ena_out,
output pm);
always @(posedge clk) begin
if (reset)
out <= start_state;
else begin
if(ena_in) begin
ena_out <= (out==(end_state-1'b1));
if(out==end_state)begin
out <= change_state;
end
else begin
if(out[3:0]==4'h9) begin
out[3:0] <= 4'h0;
out[7:4] <= out[7:4] +1'b1;
end
else begin
out <= out+1'b1;
pm <= (out==8'b00010001) ? ~pm : pm;
end
end
end
else
out <= out;
end
end
endmodule