module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
//将时分秒以及PM分为四个部分
//秒
always@(posedge clk) begin
if(reset)//复位,将秒置0
ss <=0;
else if(ena) begin //若使能为高电平,则开始计数
if(ss==8'h59)//判断是否进位
ss<=0;
else begin
if(ss[3:0]<4'h9)
ss[3:0] <= ss[3:0]+1;
else begin
ss[7:4] <= ss[7:4]+1;
ss[3:0] <= 0;
end
end
end
end
//分
always@(posedge clk) begin
if(reset)//复位,将分置0
mm <=0;
else if(ena) begin
if(ss==8'h59)
if(mm==8'h59)//59分且59秒时,进位
mm<=0;
else begin
if(mm[3:0]<4'h9)
mm[3:0] <= mm[3:0]+1;
else begin
mm[7:4] <= mm[7:4]+1;
mm[3:0] <=0;
end
end
end
end
//时
always@(posedge clk) begin
if(reset)//复位,将时置12
hh<=8'h12;
else if(ena) begin
if(ss==8'h59&&mm==8'h59)
if(hh==8'h12)
hh<=1;
else begin
if(hh[3:0]<4'h9)
hh[3:0] <= hh[3:0]+1;
else begin
hh[7:4] <=1;
hh[3:0] <=0;
end
end
end
end
//PM
always@(posedge clk) begin
if(reset) pm<=0;
else if(hh==8'h11&&mm==8'h59&&ss==8'h59)//只有在11点59分59秒到12点0分0秒时昼夜切换,PM取反
pm=~pm;
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);
reg carry_ss,carry_mm,carry_hh;
reg ena_ss,ena_mm,ena_hh;
reg [7:0] bin_ss,bin_mm,bin_hh,bcd_ss,bcd_mm,bcd_hh;
count60 second(.clk(clk),.reset(reset),.ena(ena),.carry(carry_ss),.out(bin_ss));//second
count60 minute(.clk(clk),.reset(reset),.ena(carry_ss),.carry(carry_mm),.out(bin_mm));//minute
count12 hour (.clk(clk),.reset(reset),.ena(carry_mm & carry_ss),.carry(carry_hh),.out(bin_hh));//hour
assign pm= pm_reg;
reg pm_reg;
always @(posedge clk) begin
if(reset) begin
pm_reg <= 0;
end
else begin
if(carry_hh & carry_ss & carry_mm)
pm_reg <= !pm_reg;
else
pm_reg <=pm_reg;
end
end
bin2bcd bcd_second(bin_ss,bcd_ss);
bin2bcd bcd_minute(bin_mm,bcd_mm);
bin2bcd bcd_hour (bin_hh,bcd_hh);
assign hh=bcd_hh;
assign ss=bcd_ss;
assign mm=bcd_mm;
endmodule
module count12(input clk,reset,ena,output reg carry, output [7:0] out);
reg [7:0] out_reg;
always @(posedge clk) begin
if(reset) begin
out_reg <= 8'b00001100;
carry<=0;
end
else begin
if(out_reg[3] & out_reg[2] & ena) begin
out_reg<=8'b00000001;
carry<=0;
end
else if(out_reg[3] & out_reg[1] & out_reg[0] ) begin
carry<=1;
out_reg <= out_reg+ena;
end
else begin
carry<=0 ;
out_reg<=out_reg+ena;
end
end
end
assign out = out_reg;
endmodule
module count60(input clk,reset,ena,output reg carry, output [7:0] out);
reg [7:0] out_reg;
always @(posedge clk) begin
if(reset) begin
out_reg <= 0;
carry<=0;
end
else begin
if(out_reg[5] & out_reg[4] & out_reg[3] & out_reg[1] & out_reg[0] & ena) begin
out_reg<=0;
carry<=0;
end
else if(out_reg[5] & out_reg[4] & out_reg[3] & out_reg[1] ) begin
carry<=1;
out_reg <= out_reg+ena;
end
else begin
carry<=0 ;
out_reg<=out_reg+ena;
end
end
end
assign out = out_reg;
endmodule
module bin2bcd (input [7:0] bin, output [7:0] bcd);
reg [15:0]bcd_reg;
always @(*) begin
bcd_reg = {8'b00000000,bin};
bcd_reg[15:0]={bcd_reg[12:0],3'b000};
repeat(5) begin
if(bcd_reg[11:8] >4)
bcd_reg[11:8] = bcd_reg[11:8]+2'b11;
if(bcd_reg[15:12] >4)
bcd_reg[15:12] = bcd_reg[15:12]+2'b11;
bcd_reg = {bcd_reg[14:0],1'b0};
end
end
assign bcd =bcd_reg[15:8];
endmodule