HBLbits_Verilog Basic_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 reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
always@(posedge clk) begin
if (reset) begin
hh <= 8'h12;
mm <= 0;
ss <= 0;
pm <= 0;
end
else begin
if (ena) begin
pm <= (hh == 8'h11 && mm == 8'h59 && ss == 8'h59)? ~pm : pm;
if (ss == 8'h59) begin // ss = 59
ss <= 0;
if (mm == 8'h59) begin // mm = 59
mm <= 0;
if (hh == 8'h12) begin
hh <= 8'h01;
end
else begin
if (hh[3:0] == 4'd9) begin
hh[3:0] <= 0;
hh[7:4] <= hh[7:4] + 4'd1;
end
else
hh[3:0] <= hh[3:0] + 4'd1;
end
end
else begin
if (mm[3:0] == 4'd9) begin
mm[3:0] <= 0;
mm[7:4] <= mm[7:4] + 4'd1;
end
else
mm[3:0] <= mm[3:0] + 4'd1;
end
end
else begin
if (ss[3:0] == 4'd9) begin
ss[3:0] <= 0;
ss[7:4] <= ss[7:4] + 4'd1;
end
else
ss[3:0] <= ss[3:0] + 4'd1;
end
end
end
end
endmodule
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
//例化计数器表示秒
wire ssl_2_ssh,ssh_2_mml; //地位向高位进位
cnt cnt_ssl(.clk(clk),.reset(reset),.count_start(ena),.count_end(4'd9),.end_cnt(ssl_2_ssh),.count(ss[3:0]));
cnt cnt_ssh(.clk(clk),.reset(reset),.count_start(ssl_2_ssh),.count_end(4'd5),.end_cnt(ssh_2_mml),.count(ss[7:4]));
//例化计数器表示分钟
wire mml_2_mmh, mmh_2_hh;
cnt cnt_mml(.clk(clk),.reset(reset),.count_start(ssh_2_mml),.count_end(4'd9),.end_cnt(mml_2_mmh),.count(mm[3:0]));
cnt cnt_mmh(.clk(clk),.reset(reset),.count_start(mml_2_mmh),.count_end(4'd5),.end_cnt(mmh_2_hh),.count(mm[7:4]));
//小时计数
reg a_2_p;
always @(posedge clk)begin
if(reset)begin
a_2_p <= 0;
hh <= 8'h12; // 初始条件 12:00:00 AM
end
else if(mmh_2_hh)begin
if(hh == 8'h12)
hh <= 8'h01;
else begin
hh <= hh + 1'b1;
if(hh == 8'h09)
hh <= 8'h10;
if(hh == 8'h11)
a_2_p <= ~ a_2_p;
end
end
end
assign pm = a_2_p;
endmodule
//计数器子模块,可以设置开始和结束条件
module cnt(
input clk,
input reset,
input count_start, //开始计数输入
input [3:0] count_end, //计数到多少停止计数
output end_cnt, //一次计数完成标志
output [3:0] count);
wire add_cnt;
always @(posedge clk)begin
if(reset)begin
count <= 4'd0;
end
else if(add_cnt)begin
if(end_cnt)
count <= 4'd0;
else
count <= count + 1'b1;
end
end
assign add_cnt = count_start; //计数开始条件,当满足了开始计数
assign end_cnt = add_cnt && count == count_end; //计数结束产生一个标志
endmodule
沒有留言:
張貼留言