目录
背景
原题复现
审题
我的设计
设计解释
欢迎加入
背景
这篇博客设计一个12小时的时钟,通过例化4bit BCD码计数器来设计,如果你给予的时钟周期是1s,则能够当做时钟来用哦。
原题复现
原题如下:
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.
用计数器设计一个带am/pm的12小时时钟。该计数器通过一个CLK进行计时,用ena使能信号来驱动时钟的递增。
reset信号将时钟复位为12:00 AM。 信号pm为0代表AM,为1代表PM。hh、mm和ss由两个BCD计数器构成hours(01~12), minutes(00~59) , second(00~59)。Reset信号比enable信号有更高的优先级,即使没有enable信号也可以进行复位操作。
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 Declaration
1
2
3
4
5
6
7
8module top_module( input clk, input reset, input ena, output pm, output [7:0] hh, output [7:0] mm, output [7:0] ss);
审题
这个题目的几个要求:
- 能够进行12小时计数,那就要求有秒,分钟,小时;
- 使用BCD计数器来实现;
- 复位有效时,复位到12点;
- 要能够区分上下午,上午pm为0,下午pm为1;
- 复位比使能优先级更高;
- 由于是时钟,所以是从1点到12点;
我的设计
好了,这里为了解决这个大问题,我先设计一个秒和分钟的计数器,也就是能从0到59的模60BCD计数器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25module count60( input clk, input reset, input en, output reg [7:0] cnt_out ); always@(posedge clk) begin if(reset) cnt_out <= 0; else if(en) begin if(cnt_out == 8'h59) begin cnt_out <= 0; end else if(cnt_out[3:0] == 9) begin cnt_out[3:0] <= 0; cnt_out[7:4] <= cnt_out[7:4] + 1; end else begin cnt_out[3:0] <= cnt_out[3:0] + 1; end end end endmodule
在设计一个从1计数到12的模12 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
26module count12 ( input clk, // Clock input reset, // Asynchronous reset active high input en, output reg [7:0] cnt_out ); always@(posedge clk) begin if(reset) cnt_out <= 8'h12; else if(en) begin if(cnt_out == 8'h12) begin cnt_out <= 1; end else if(cnt_out[3:0] == 9) begin cnt_out[3:0] <= 0; cnt_out[7:4] <= cnt_out[7:4] + 1; end else begin cnt_out[3:0] <= cnt_out[3:0] + 1; end end end endmodule
最后,通过例化得到最终的12小时时钟:
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
39module top_module( input clk, input reset, input ena, output pm, output [7:0] hh, output [7:0] mm, output [7:0] ss); count60 inst_second( .clk(clk), .reset(reset), .en(ena), .cnt_out(ss) ); count60 inst_min( .clk(clk), .reset(reset), .en(ena&(ss == 8'h59)), .cnt_out(mm) ); count12 inst_hour( .clk(clk), .reset(reset), .en(ena&(ss == 8'h59)&(mm == 8'h59)), .cnt_out(hh) ); reg p; always@(posedge clk) begin if(reset) p <= 0; else if(hh == 8'h11 && ss == 8'h59&& mm == 8'h59) p <= ~p; else ; end assign pm = p; endmodule
设计解释
上面代码的最后一部分用于产生pm指示上下午的信号:
reg p;
always@(posedge clk) begin
if(reset) p <= 0;
else if(hh == 8'h11 && ss == 8'h59&& mm == 8'h59) p <= ~p;
else ;
end
assign pm = p;
这样,设计就结束了。
通过例化模块的方式比在一个模块中写完整个设计要简洁,清晰,思路也更明朗了。
欢迎加入
在今年的秋招一开始,我就建立了一个微信群,在CSDN发布了一条博文,召集全国各地的同行朋友们共同加入,共同讨论秋招求职笔试,面试经验,目前已经有300多人加入,各位才华横溢,让我大开眼界。 到今天11月份,从西北地区最早结束到其他各地陆续结束,但是我们曾开玩笑说,本群继续召集下一届同行,作为先行者的我们也会对你们给予应有的帮助,欢迎加入,到你们晒工资的时候,会不会再次把我们倒挂呢?拭目以待。 由于人数较多,所以加我的时候务必备注:CSDN+地区或学校+职位(意向职位)+昵称。 对于后来很晚的人,也许你看到这个博客我已经工作了,也许我已经变了,不再是一个热心的博主,因此,可能我没有时间做这些事情了,还请见谅。
最后
以上就是拉长小蚂蚁最近收集整理的关于HDLBits 系列(19) 12小时时钟的Verilog设计的全部内容,更多相关HDLBits内容请搜索靠谱客的其他文章。
发表评论 取消回复