一、题目说明——HDLbits_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.
二、问题分析
分析题目可知,我们需要设计的电路应满足以下特征:
1)功能:实现时钟计数 。
2)端口:输入时钟clk和复位信号reset,输出8位宽时钟计数结果信号hh、mm、ss分别代表时、分、秒,以及上下午标识信号pm。
3)触发方式:时钟上升沿触发,reset同步且高电平有效。
4)解释说明:8位宽的hh、mm、ss分别被分为了两部分,其中低四位代表个位,高四位代表十位,每个位的范围很显然是0~9,也就是4’b0000~4‘b1001,其他的情况不能出现 。
三、实现与总结
与0~9999计数器的Verilog实现思路相似,我们依然使用casex完成行为级建模。
在casex中,因为从8’h09到8‘h10差了8’h07,所以当十位进位时,直接加上即可。
module top_module(
input clk,
input reset,
input ena,
output reg pm,
output reg [7:0] hh,
output reg [7:0] mm,
output reg [7:0] ss);
always@(posedge clk)begin
if(reset)begin //同步高电平复位,并且reset具有最高优先级(即使ena为0也可以触发)
hh<=8'h12;
mm<=0;
ss<=0;
pm<=0;
end
else if(ena)begin
ss<=ss+1; //秒钟计数
casex({hh,mm,ss})
24'h11_59_59:begin pm<=~pm;hh<=hh+1;mm<=0;ss<=0; end //pm跳变
24'h12_59_59:begin hh<=1;mm<=0;ss<=0; end //时跳变(12—>1)
24'hx9_59_59:begin hh<=hh+8'h07;mm<=0;ss<=0; end //时跳变(9—>10)
24'hxx_59_59:begin hh<=hh+1;mm<=0;ss<=0; end //分跳变(59—>0)
24'hxx_x9_59:begin mm<=mm+8'h07;ss<=0; end //分跳变(x9—>x0)
24'hxx_xx_59:begin mm<=mm+1;ss<=0; end //秒跳变(59—>0)
24'hxx_xx_x9:begin ss<=ss+8'h07; end //秒跳变(x9—>x0)
endcase
end
end
endmodule