概述
前言
最近在用HDLBits开始学习verilog,做了一百道出头的题了,遇到这个12小时时钟的题比较有意思,题目地址是https://hdlbits.01xz.net/wiki/Count_clock。看了好几个答案,没有用层次化思维写的,都是一个模块大量的分支语句和always块直接堆完,菜鸡如我看答案都费劲,于是贴一个自己写的。比较高大上地用了层次化建模的思想,这样思路梳理起来个人觉得比较方便。
分析
分和秒的计数用的是同一个模块,0-59的六十进制的计数器,不过需要注意题目要求用一个8bit数的高4位表示十位,低4位表示个位。
小时单独写一个模块,1-12的十二进制计数器,需要考虑复位、进位、循环的问题。
顶层模块的部分就很简单了,例化2次六十进制计数器,例化1次十二进制计数器,然后连起来就行了。
//顶层模块
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss
);
wire [1:0] ena_t;
mod_c60 mod_ss(clk, reset, ena, ss, ena_t[0]);
mod_c60 mod_mm(clk, reset, ena_t[0], mm, ena_t[1]);
mod_c12 mod_hh(clk, reset, ena_t[1], hh, pm);
endmodule
//六十进制的计数器模块
module mod_c60 (
input clk,
input reset, // Synchronous active-high reset
input en,
output [7:0] q,
output cout
);
wire d_temp;
assign d_temp = (q[3:0] == 4'd9) && en;
assign cout = (q == 8'h59) && d_temp;
//十进制,0-9
always @ (posedge clk)begin
if(reset)
q[3:0] <= '0;
else if(en)begin
if(q[3:0] < 4'd9)
q[3:0] <= q[3:0] + 1'd1;
else
q[3:0] <= '0;
end
end
//六进制,0-5
always @ (posedge clk)begin
if(reset)
q[7:4] <= '0;
else if(d_temp)begin
if(q[7:4] < 4'd5)
q[7:4] <= q[7:4] + 1'b1;
else
q[7:4] <= '0;
end
end
endmodule
//十二进制的计数器模块
module mod_c12 (
input clk,
input reset, // Synchronous active-high reset
input en,
output [7:0] q,
output cout
);
wire d_temp;
assign d_temp = ((q[3:0] == 4'd9) || (q == 8'h12)) && en;
//十进制,0-9,且当q=12时再加为1,复位为2
always @ (posedge clk)begin
if(reset)begin
q[3:0] <= 4'd2;
cout <= 1'b0;
end
else if(en)begin
if(q[3:0] < 4'd9)begin
if(q==8'h12)
q[3:0] <= 4'd1; //12再加变1
else begin
q[3:0] <= q[3:0] + 1'd1;
//11再加am与pm变换
cout <= (q==8'h11) ? ~cout : cout;
end
end
else
q[3:0] <= '0;
end
end
//二进制,0-1,复位为1
always @(posedge clk)begin
if(reset)
q[7:4] <= 4'd1;
else if(d_temp)begin
if(q[7:4] == '0)
q[7:4] <= 4'd1;
else
q[7:4] <= '0;
end
end
endmodule
总共一百行代码,可读性不敢保证,但是长度比我找到的其他答案要短。
最后
以上就是平淡铅笔为你收集整理的HDLBits练习-12小时时钟的全部内容,希望文章能够帮你解决HDLBits练习-12小时时钟所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复