我是靠谱客的博主 如意长颈鹿,最近开发中收集的这篇文章主要介绍HDLBits刷题counter前言一、count clock二、代码实现总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

HLD Bits刷题记录

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、count clock
  • 二、代码实现
    • 第一次写的时候,忽略了十进制这个问题,下意识按照满59返回,导致最后答案是不对的。后面仔细看题目发现是用BCD计数器实现。
  • 总结


前言

之前刷题都没有记录,从今天开始稍微记录一下,这个过程中遇到的一些问题,也是方便自己以后查看。


一、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.
在这里插入图片描述
题目意思很简单,实现一个时钟功能就行,同时用pm的高低区分上午和下午。
主要问题在于,要求使用二进制编码的十进制计数器实现。那计数器范围为0-9,计满9就得返回0.

二、代码实现

第一次写的时候,忽略了十进制这个问题,下意识按照满59返回,导致最后答案是不对的。后面仔细看题目发现是用BCD计数器实现。

代码如下:


```java
module top_module(
    input clk,
    input reset,    //高电平复位(同步)
    input ena,      //1:计数;0:保持
    output pm,
    output [7:0] hh,//时针
    output [7:0] mm,//分针
    output [7:0] ss); //秒针
    //用BCD计数器,最高到9,那就得把小时、分钟、秒钟都按照个位和十位来写
    reg [3:0] s_1;   //秒钟个位
    reg [3:0] s_10;  //秒钟十位
    reg [3:0] m_1;
    reg [3:0] m_10;
    reg [3:0] h_1;
    reg [3:0] h_10;
    //计数器状态跳转
    //秒钟
    wire s_1_end;
    assign s_1_end = ena && s_1==4'd9;  //9s
    always@(posedge clk)
        begin
            if(reset)
                s_1 <= 4'd0;
            else 
                s_1 <= ena ? (s_1_end ? 4'd0 : s_1+4'b1) : s_1;
        end
    //十位为5,个位为9,即59返回0.为了方便表示,可以新定义变量,所以十位不能超过5,要注意这一点
    wire s_end;
    assign s_end = s_1_end && s_10==4'd5; //59s
    always@(posedge clk)
        begin
            if(reset)
                s_10 <= 4'd0;
            else 
                s_10 <= s_1_end ? (s_end ? 4'd0 :  s_10+4'b1) : s_10;
        end
    //分钟的跳转,以秒钟为前提,满59秒分钟加一。
    //同样,为了方便表示,再定义变量
    wire m_1_end;
    assign m_1_end = s_end && m_1==4'd9;   //9分59秒
     always@(posedge clk)
        begin
            if(reset)
                m_1 <= 4'd0;
            else 
                m_1 <= s_end ? (m_1_end ? 4'd0 : m_1+4'b1) : m_1;
        end
    wire m_10_end;
    assign m_10_end = m_1_end && m_10==4'd5; //59分59秒
    always@(posedge clk)
        begin
            if(reset)
                m_10 <= 4'd0;
            else //分针最大为5
                m_10 <= m_1_end ? (m_10_end  ? 4'd0 : m_10+4'b1) : m_10;
        end
    //时钟,分钟59为转变界限,但是要注意时针只有1-12。个位和十位数字有变化
    wire h_1_end0;
    assign h_1_end0 = m_10_end && h_1==4'd9;  //09:59:59
    wire h_1_end1;
    assign h_1_end1 = m_10_end && h_10==4'd1 && h_1==4'd2; //12:59:59
    always@(posedge clk)
        begin
            if(reset)
                h_1 <= 4'd2; //注意,时针复位是复位到12点,个位为2
            else
                h_1 <= m_10_end ? (h_1_end0 ? 4'd0 : (h_1_end1 ? 4'd1 : h_1+4'b1)) : h_1;
        end
    wire h_10_end0;
    assign h_10_end0 = m_10_end && h_1_end1;
    wire h_10_end1;
    assign h_10_end1 = m_10_end && h_1_end0;
    always@(posedge clk)
        begin
            if(reset)
                h_10 <= 4'd1;
            else if(m_10_end)
                begin
                	if(h_10_end0)
                    	h_10 <= 4'd0;
                    else if(h_10_end1)
                        h_10 <= h_10+4'b1;
                end
            else
                h_10 <= h_10; 
        end
    reg p_m;
    //11:59:59下一周期发生变化
    wire pm_change;
    assign pm_change = h_10==4'd1 && h_1==4'd1 && m_10_end;
    always@(posedge clk)
        begin
            if(reset)
                p_m <= 1'b0;
            else
                p_m <= pm_change ? ~p_m : p_m;
        end
    assign ss = {s_10,s_1};
    assign mm = {m_10,m_1};
    assign hh = {h_10,h_1};
    assign pm = p_m;
                

endmodule



在这里插入图片描述

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

总结

以上就是对这个题的解答了,这个题是做到目前我错的次数最多的,所以记录一下,主要问题是使能信号没有加好,之前一直是11,22,33…的计数,来回检查,发现是使能的问题,没有做好保持,另外需要注意的就是在对指针进行定义的时候,和分针和秒针是不太一样的。

最后

以上就是如意长颈鹿为你收集整理的HDLBits刷题counter前言一、count clock二、代码实现总结的全部内容,希望文章能够帮你解决HDLBits刷题counter前言一、count clock二、代码实现总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部