我是靠谱客的博主 如意长颈鹿,这篇文章主要介绍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计数器实现。

代码如下:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
```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内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部