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.
做一个钟表,注意是16进制的计数
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
wire [2:0] c;
reg [3:0]msb;
reg [3:0]lsb;
assign hh = {msb, lsb};
always@ (posedge clk)
if(reset)
msb <= 4'd1;
else if(c[0]&&c[1] &&msb == 4'd1 && lsb == 4'd2)
msb <= 4'd0;
else if(c[0]&&c[1] && ena &&lsb == 4'd9)
msb <= msb + 8'd1;
always@ (posedge clk)
if(reset)
lsb <= 4'd2;
else if (c[0]&&c[1] &&msb == 4'd1 && lsb == 4'd2)
lsb <= 4'd1;
else if(c[0]&&c[1] &&lsb == 4'd9)
lsb <= 4'd0;
else if(c[0]&&c[1] && ena)
lsb <= lsb + 4'd1;
always@(posedge clk)
if(reset)
pm <= 1'b0;
else if(c[0]&& c[1] &&hh == 8'h11)
pm <= ~pm;
cnt min(
.clk(clk),
.reset(reset),
.val(c[0] &ena),
.cin(c[1]),
.count(mm)
);
cnt sec(
.clk(clk),
.reset(reset),
.val(ena),
.cin(c[0]),
.count(ss)
);
endmodule
module cnt(
input clk,
input reset,
input val,
output cin,
output [7:0] count
);
reg [3:0]msb;
reg [3:0]lsb;
assign cin = count == 8'h59 ? 1'b1 : 1'b0;
assign count = {msb, lsb};
always@(posedge clk)
if(reset)
msb <= 4'd0;
else if(msb == 4'd5 && val && lsb == 4'd9)
msb <= 4'd0;
else if(val && lsb == 4'd9 )
msb <= msb + 4'd1;
always@(posedge clk)
if(reset)
lsb <= 4'd0;
else if(lsb == 4'd9 & val)
lsb <= 4'd0;
else if(val)
lsb <= lsb + 8'd1;
endmodule