【HDLBits学习记录】Count clock

前言

本文为学习记录,问题来自于HDLbits网站上的习题。笔者能力尚浅,如有纰漏错误欢迎指正,若有其他想法也欢迎交流。

问题描述:

Count clock-HDLbits
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 pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    
    reg [4:0] bcd_ena;
    reg [3:0] s0,s1,m0,m1;
    //设置计数条件
    assign bcd_ena[0] = ena?1:0;
    assign bcd_ena[1] = (s0 == 4'd9 && s1 <= 4'd5 && ena)?1:0;
    assign bcd_ena[2] = (s0 == 4'd9 && s1 == 4'd5 && ena)?1:0;
    assign bcd_ena[3] = (s0 == 4'd9 && s1 == 4'd5 && m0 == 4'd9 && m1 <= 4'd5 && ena)?1:0;
    assign bcd_ena[4] = (s0 == 4'd9 && s1 == 4'd5 && m0 == 4'd9 && m1 == 4'd5 && ena)?1:0;
   //实例化
    bcd_count count0(clk,reset,bcd_ena[0],4'd9,s0);
    bcd_count count1(clk,reset,bcd_ena[1],4'd5,s1);
    bcd_count count2(clk,reset,bcd_ena[2],4'd9,m0);
    bcd_count count3(clk,reset,bcd_ena[3],4'd5,m1);
    bcd_count_h count4(clk,reset,bcd_ena[4],hh,pm);

    assign mm = {m1,m0};
    assign ss = {s1,s0};

endmodule
//由于分和秒都是60进制,故其计数规则相同
module bcd_count(input clk,input reset,input ena,input [3:0]limit,output [3:0]c);
    //由于十位与各位递增的上限不同,故添加输入limit作为限制条件
    always @(posedge clk)begin
        if(reset || ena&&c == 4'd9 || ena&&c == limit)begin
            c = 4'd0;
        end
        else begin
            if(ena)
                c = c + 1;
        end
    end
endmodule
//根据问题描述,小时对应的两位的计数范围为01-12,故与分和秒技术规则不同
module bcd_count_h(input clk,input reset,input ena,output [7:0]c,output pm);
	//输出pm值为0时对应AM,值为1时对应PM
    reg [3:0]c0,c1;
    //初始化时间
    initial begin
        c0 = 4'd2;
        c1 = 4'd1;
        pm = 0;
    end
    
    always @(posedge clk)begin
        if(reset)begin
            c0 = 4'd2;
            c1 = 4'd1;
            pm = 0;
        end
        else if( ena&&c0 == 4'd9)begin
            c0 = 4'd0;
            c1 = c1 + 1;
        end
        //每当从11:59:59向12:00:00跳转时,pm信号取反
        else if(ena && c1 ==4'd1 && c0 == 4'd1)begin
            pm = ~pm;
            c0 = c0 + 1;
        end
        //计数范围为01-12,不存在00:00:00
        else if(ena && c1 == 4'd1 && c0 == 4'd2)begin
            c1 = 4'd0;
            c0 = 4'd1;
        end
        else begin
            if(ena)begin
                c0 = c0 + 1;          
            end
        end
    end
    assign c = {c1,c0};
endmodule

仿真结果:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值