概述
要求:
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.
思路:
1. ss、mm、hh都是由两个bcd码组成的,所以要分成十位和个位,否则会显示成16进制;
2. 分成十位和分位后,就不能使用模60和模12计数器,也可以不用计数器,但是这样代码中重复太多,还是选用计数器并引用模块更简洁明了。ss和mm个位改用模10计数器(0-9),十位改用模6计数器(0-5)。因为时十位只有1、0两个状态,所以hh采用if语句直接置数比较方便;
3. 首先写两个计数器并引用模块,注意每位的使能端都是与上一位的输出有关,这是这部分的重点,搞清这个基本就能解决;
4. pm注意都是在11时59分59秒状态发生转换,注意不能直接令pm为!pm,会报错,要先赋成另一个值。
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
reg [3:0] ss_one;
reg [3:0] ss_ten;
reg [3:0] mm_one;
reg [3:0] mm_ten;
reg [3:0] hh_one;
reg [3:0] hh_ten;
//秒
wire ena_ss_ten; //秒十位的使能端
assign ena_ss_ten=ena&&(ss_one==4'd9); //9秒且ena高电平时秒十位开始计数
counter10 counter_ss_one(clk, ena, reset, ss_one);
counter6 counter_ss_ten(clk, ena_ss_ten, reset, ss_ten);
assign ss={ss_ten, ss_one};//输出秒
//分
wire ena_mm_one;
wire ena_mm_ten;
assign ena_mm_one=(ss_ten==4'd5)&&(ss_one==4'd9); //59秒时分个位开始计数
assign ena_mm_ten=ena_mm_one&&(mm_one==4'd9); //9分59秒分十位开始计数
counter10 counter_mm_one(clk, ena_mm_one, reset, mm_one);
counter6 counter_mm_ten(clk, ena_mm_ten, reset, mm_ten);
assign mm={mm_ten, mm_one};//输出分
//时
wire ena_hh;
assign ena_hh=ena_mm_ten&&(mm_ten==4'd5);//59分59秒时时个位开始计数
always@(posedge clk)begin
if(reset)begin
hh_one<=4'd2;//重置时为12
hh_ten<=4'd1;
end
else if(ena_hh)begin
if(hh_one==4'd9&&(hh_ten==4'd0))begin
hh_one<=4'd0;
hh_ten<=4'd1;//时为09时,置数为10
end
else if(hh_one==4'd2&&(hh_ten==4'd1))begin
hh_one<=4'd1;
hh_ten<=4'd0;//时为12时,置数为01
end
else begin
hh_one<=hh_one+1'b1;
end
end
else if(!ena_hh)begin
hh_one<=hh_one;
hh_ten<=hh_ten;
end
end
assign hh={hh_ten, hh_one};//输出时
//pm的设置
wire pm_temp;
wire ena_pm;
assign pm_temp=pm;
assign ena_pm=ena_hh&&(hh_ten==4'd1)&&(hh_one==4'd1);//11时59分59秒时翻转
always@(posedge clk)begin
if(reset)begin
pm<=1'b0;
end
else if(ena_pm)begin
pm<=~pm_temp;//转置
end
else if(!ena_pm)begin
pm<=pm;
end
end
endmodule
module counter10(
input clk,
input enable,
input reset,
output [3:0] q);//模10计数器
always@(posedge clk)begin
if(reset)begin
q<=4'd0;
end
else if(enable)begin
if(q>=4'd9)begin
q<=4'd0;
end
else begin q<=q+1'b1;
end
end
else if(!enable)begin
q<=q;
end
end
endmodule
module counter6(
input clk,
input enable,
input reset,
output [3:0] q);//模6计数器
always@(posedge clk)begin
if(reset)begin
q<=4'd0;
end
else if(enable)begin
if(q>=4'd5)begin
q<=4'd0;
end
else begin q<=q+1'b1;
end
end
else if(!enable)begin
q<=q;
end
end
endmodule
一些基础语法复习:
assign后面只能用阻塞性语句;
if语句都要带begin end,之前写代码习惯不好,要改掉。
最后
以上就是小巧小松鼠为你收集整理的HDLBits/Counters/12-hour clock 记录一下个人思路/自用的全部内容,希望文章能够帮你解决HDLBits/Counters/12-hour clock 记录一下个人思路/自用所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复