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.
在这里插入图片描述

问题描述

创建一组适合作为12小时时钟使用的计数器(带上午/下午指示)。你的计数器由一个快速运行的时钟计时,当你的时钟应该增加时(例如,每秒一次),ena就会有一个脉冲。
reset将时钟重置到上午12点。pm对AM是0,对pm是1。hh、mm、ss为BCD (Binary-Coded Decimal)两位,分别代表小时(01-12)、分钟(00-59)、秒(00-59)。Reset的优先级高于enable,甚至在未启用时也会发生。
下面的计时图显示了从11:59:59 AM到12:00:00 PM的翻转行为以及同步重置和启用行为。
在这里插入图片描述


原因分析:


本题实质是一个低位向高位进位的过程,与Conter1000i相比只不过是进位的跳变条件发生了变化。由于使用的是16进制,所以个位计满到9后下一步会跳变到a而非0,因此进位的过程中不仅要考秒计满到59还要单独考虑秒的个位计数到9,以此类推分钟和小时的进位也是如此。还要注意小时位的置零和进位满跳转数值,由于使用的是上下午制,所以当小时位计数到12时,下次会跳转到1而非0。另外还应该注意组合逻辑与时序逻辑的使用。在对使能信号进行赋值操作时由于不涉及到敏感条件故要使用组合逻辑(always@(*)与assign赋值语句均可)。


解决方案:

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    reg	[2:0]	en;
    
    assign	en[0] = ena;
    assign	en[1] = (ss == 8'h59);
    assign	en[2] = (ss == 8'h59)&&(mm == 8'h59);
    
    always@(posedge	clk)
        if(reset == 1'b1)
            pm <= 1'b0;
    else	if((en[2] == 1'b1)&&(hh == 8'h11))
        	pm <= ~pm;
    	else
        	pm <= pm;
    
    S	S_inst0
    (
        .clk		(clk),
        .reset		(reset),
        .ena		(en[0]),

        .cnt		(ss)
    );
        
    S	S_inst1 //秒计数器和分钟计数器功能相同,在使用分钟计数器时再将秒计数器实例化一次即可。
    (
        .clk		(clk),
        .reset		(reset),
        .ena		(en[1]),

        .cnt		(mm)
    );
    
    H	H_inst //小时计数器和秒计数器功能相似,但是二者跳变条件不同。小时计数器的计数最大值为12,当复位信号来临时强制置12
    (
        .clk		(clk),
        .reset		(reset),
        .ena		(en[2]),

        .cnt		(hh)
    );
            
endmodule

module	S
    (
    	input	wire			clk		,
        input	wire			reset	,
        input	wire			ena		,
        
        output	reg		[7:0]	cnt		
    );
    
    always@(posedge	clk)
        if(reset == 1'b1)
            cnt <= 8'h0;
    	else	if(ena == 1'b1)
            begin
                if(cnt == 8'h59)
                    cnt <= 8'h0;
                else	if(cnt[3:0] == 4'h9)
                    begin
                        cnt[7:4] <= cnt[7:4] + 4'h1;
                        cnt[3:0] <= 4'h0;
                    end
                else
                    begin
                        cnt[7:4] <= cnt[7:4];
                        cnt[3:0] <= cnt[3:0] + 4'h1;
                    end
            end
    	else
        	cnt <= cnt;
endmodule

module	H
    (
    	input	wire			clk		,
        input	wire			reset	,
        input	wire			ena		,
        
        output	reg		[7:0]	cnt		
    );
    
    always@(posedge	clk)
        if(reset == 1'b1)
            cnt <= 8'h12;
    	else	if(ena == 1'b1)
            begin
                if(cnt == 8'h12)
                    cnt <= 8'h1;
                else	if(cnt[3:0] == 4'h9)
                    begin
                        cnt[7:4] <= cnt[7:4] + 4'h1;
                        cnt[3:0] <= 4'h0;
                    end
                else
                    begin
                        cnt[7:4] <= cnt[7:4];
                        cnt[3:0] <= cnt[3:0] + 4'h1;
                    end
            end
    	else
        	cnt <= cnt;
endmodule
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值