HDLBits—Count clock

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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值