HDLBits --- 12-hour clock

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 reg pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    reg [3:0]s1,s0,m1,m0,h1,h0;               //另定义 reg 类型变量,再在 always 中进行赋值
    assign {hh,mm,ss}={h1,h0,m1,m0,s1,s0};    //再用组合逻辑与 hh,mm,ss 连接
    
    always@(posedge clk)begin             //s0[3:0]
        if(reset)begin
            s0<=4'b0;
        end
        else if(ena && s0==9)begin        // 三要素:reset、归 0 、+1
           s0<=4'b0; 
        end
        else if(ena)begin
           s0<=s0+1'b1; 
        end
        else
            s0<=s0;
    end
    
    always@(posedge clk)begin              //s1
        if(reset)begin
           s1<=0; 
        end
        else begin
            if(ena && s0==9 && s1==5)begin
               s1<=0; 
            end
            else if(ena && s0==9)begin
               s1<=s1+1'b1; 
            end
            else
                s1<=s1;
        end
    end
    
    always@(posedge clk)begin               //m0
        if(reset)begin
           m0<=0; 
        end
        else begin
            if(ena && m0==9 && s1==5 && s0==9)begin
               m0<=0; 
            end
            else if(ena && s1==5 && s0==9)begin
               m0<=m0+1'b1; 
            end
            else
                m0<=m0;
        end
    end
    
    always@(posedge clk)begin               //m1
        if(reset)begin
           m1<=0; 
        end
        else begin
            if(ena && m0==9 && s1==5 && s0==9 && m1==5)begin
               m1<=0; 
            end
            else if(ena && s1==5 && s0==9 && m0==9)begin
               m1<=m1+1'b1; 
            end
            else
                m1<=m1;
        end
    end
    
    always@(posedge clk)begin                  //h0
        if(reset)begin
           h0<=4'b0010; 
        end
        else begin
            if(ena && h0==9 && m1==5 && m0==9 && s1==5 && s0==9)begin
               h0<=0; 
            end
            else if(ena && h1==1 && h0==2 && m1==5 && m0==9 && s1==5 && s0==9)begin   //注意12小时制中 hh由 12 变为 01        
               h0<=4'b0001; 
            end
            else if(ena && m1==5 && m0==9 && s1==5 && s0==9)begin
               h0<=h0+1'b1; 
            end
            else
                h0<=h0;
        end
    end
    
    always@(posedge clk)begin                   //h1
        if(reset)begin
           h1<=4'b0001; 
            pm<=0;                              //pm
        end
        else begin
            if(ena && h1==1 && h0==2 && m1==5 && m0==9 && s1==5 && s0==9)begin
               h1<=0; 
            end
            else if(ena && h0==9 && m1==5 && m0==9 && s1==5 && s0==9)begin
               h1<=h1+1'b1; 
            end
            else
                h1<=h1;
        end
        
        if(ena && h1==1 && h0==1 && m1==5 && m0==9 && s1==5 && s0==9)begin      //对pm讨论
            pm<=~pm;
        end
    end

endmodule

此处 进位 条件均写入 if 条件中,也可以单独设置 变量 表示进位或者归0

如 日拱一卒_未来可期:https://blog.csdn.net/qq_42334072/article/details/109003877

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    reg pm_temp;
    reg [3:0] ss_ones;
    reg [3:0] ss_tens;
    reg [3:0] mm_ones;
    reg [3:0] mm_tens;
    reg [3:0] hh_ones;
    reg [3:0] hh_tens;
    
    wire		add_ss_ones;
    wire		end_ss_ones;
    wire		add_ss_tens;
    wire		end_ss_tens;
    wire		add_mm_ones;
    wire		end_mm_ones;
    wire		add_mm_tens;
    wire		end_mm_tens;
    wire		add_hh_ones;
    wire		end_hh_ones_0;
    wire		end_hh_ones_1;
    wire		add_hh_tens;
    wire		end_hh_tens_0;
    wire		end_hh_tens_1;
    wire		pm_ding;
    
    assign add_ss_ones = ena;
    assign end_ss_ones = add_ss_ones && (ss_ones == 4'd9);
    always @(posedge clk)begin
        if(reset)begin
            ss_ones <= 4'b0;
        end
        else if(add_ss_ones)begin
            if(end_ss_ones)begin
                ss_ones <= 4'b0;
            end
            else begin
                ss_ones <= ss_ones + 4'b1;
            end
        end
    end
    
    assign add_ss_tens = end_ss_ones;
    assign end_ss_tens = add_ss_tens && (ss_tens == 4'd5);
    always @(posedge clk)begin
        if(reset)begin
            ss_tens <= 4'b0;
        end
        else if(add_ss_tens)begin
            if(end_ss_tens)begin
                ss_tens <= 4'b0;
            end
            else begin
                ss_tens <= ss_tens + 4'b1;
            end
        end
    end
    
    assign add_mm_ones = end_ss_tens;
    assign end_mm_ones = add_mm_ones && (mm_ones == 4'd9);
    always @(posedge clk)begin
        if(reset)begin
            mm_ones <= 4'b0;
        end
        else if(add_mm_ones)begin
            if(end_mm_ones)begin
                mm_ones <= 4'b0;
            end
            else begin
                mm_ones <= mm_ones + 4'b1;
            end
        end
    end
    
    assign add_mm_tens = end_mm_ones;
    assign end_mm_tens = add_mm_tens && (mm_tens == 4'd5);
	always @(posedge clk)begin
        if(reset)begin
            mm_tens <= 4'b0;
        end
        else if(add_mm_tens)begin
            if(end_mm_tens)begin
                mm_tens <= 4'b0;
            end
            else begin
                mm_tens <= mm_tens + 4'b1;
            end
        end
    end
    
    assign add_hh_ones = end_mm_tens;
    assign end_hh_ones_0 = add_hh_ones && (hh_ones == 4'd9);
    assign end_hh_ones_1 = add_hh_ones && ((hh_ones == 4'd2) && (hh_tens == 4'd1));
    always @(posedge clk)begin
        if(reset)begin
            hh_ones <= 4'd2;
        end
        else if(add_hh_ones)begin
            if(end_hh_ones_0)begin
                hh_ones <= 4'b0;
            end
            else if(end_hh_ones_1)begin
                hh_ones <= 4'b1;
            end
            else begin
                hh_ones <= hh_ones+4'b1;
            end
        end
    end

    assign add_hh_tens = end_mm_tens;
    assign end_hh_tens_0 = add_hh_tens && end_hh_ones_1;
    assign end_hh_tens_1 = add_hh_tens && end_hh_ones_0;
    always @(posedge clk)begin
        if(reset)begin
            hh_tens <= 4'b1;
        end
        else if(add_hh_tens)begin
            if(end_hh_tens_0)begin
                hh_tens <= 4'b0;
            end
            else if(end_hh_tens_1)begin
                hh_tens <= hh_tens + 4'b1;
            end
        end
    end
    
    always@(posedge clk)begin
        if(reset)begin
            pm_temp <= 1'b0;
        end
        else if(pm_ding)begin
            pm_temp <= ~pm_temp;
        end
    end
    
    assign pm_ding = hh_tens == 4'd1 && hh_ones == 4'd1 && end_mm_tens;
    
    assign ss = {ss_tens, ss_ones};
    assign mm = {mm_tens, mm_ones};
    assign hh = {hh_tens, hh_ones};
    assign pm = pm_temp;
    
endmodule

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值