实现手表的计时功能:
1.具有start启动信号、pause暂停信号,可以自定义其触发机制。
2.具有时间更改接口,可以更改时、分、秒。
3.输出时、分、秒。
Verilog设计
模块端口定义:
module watch1(
input wire clk ,
input wire rst_n ,
input wire start , //
input wire pause , //
input wire h_add , //when it is 1, hour will add 1(when changing the time, the current time do not count)
input wire m_add , //when it is 1, minute will add 1(when changing the time, the current time do not count)
input wire s_add , //when it is 1, second will add 1(when changing the time, the current time do not count)
output reg [4:0] hour ,
output reg [5:0] minute ,
output reg [5:0] second // second+1 per period
);
手表计时使能:
always@(posedge clk or negedge rst_n)
if(!rst_n) running <= 1'b0;
else if(pause && start) //push the keys in the same time, the watch still runs
running <= 1'b1;//running;keep the state
else if(pause) //
running <= 1'b0;
else if(start) //
running <= 1'b1;
else ;
或者:
always@(posedge clk or negedge rst_n)
if(!rst_n) running <= 1'b0;
else if(start_rise) //push the key, the watch will run(higher priority)
running <= 1'b1;
else if(pause_rise) //push the key, the watch will stop
running <= 1'b0;
// else if(start_fall) //release the key, the watch will run
// running <= 1'b1;
else ;
小时:
always@(posedge clk or negedge rst_n)
if(!rst_n) hour <= 'b0;
else if(h_add) begin
if(hour == CNT_23)
hour <= 'b0;
else
hour <= hour + 1'b1;
end
else if(running & ~m_add & ~s_add ) begin //when changing the time, the current time do not count
if(second == CNT_59 && minute == CNT_59) begin
if(hour == CNT_23)
hour <= 'b0;
else
hour <= hour + 1'b1;
end
else ;
end
else ;
分钟:
always@(posedge clk or negedge rst_n)
if(!rst_n) minute <= 'b0;
else if(m_add) begin
if(minute == CNT_59)
minute <= 'b0;
else
minute <= minute + 1'b1;
end
else if(running & ~s_add & ~h_add ) begin //when changing the time, the current time do not count
if(second == CNT_59) begin
if(minute == CNT_59)
minute <= 'b0;
else
minute <= minute + 1'b1;
end
else ;
end
else ;
秒:
always@(posedge clk or negedge rst_n)
if(!rst_n) second <= 'b0;
else if(s_add) begin
if(second == CNT_59)
second <= 'b0;
else
second <= second + 1'b1;
end
else if(running & ~m_add & ~h_add ) begin //when changing the time, the current time do not count
if(second == CNT_59)
second <= 'b0;
else
second <= second + 1'b1; // second+1 per period
end
else ;
仿真波形
时钟进位:
启动&暂停:
或者:
顶层集成
//
module watch_top(
input wire clk ,
input wire rst_n ,
input wire start_key , //按键:开始计时(按下按键时均为0)
input wire pause_key , //按键:暂停计时
input wire h_key , //按键:时+1
input wire m_key , //按键:分+1
input wire s_key , //按键:秒+1
output wire [4:0] hour , //时
output wire [5:0] minute , //分
output wire [5:0] second //秒(每时钟周期+1)
);
// parameter ======================================================
// wire =============================================================
wire start;
wire pause;
wire h_add;
wire m_add;
wire s_add;
// reg =============================================================
// assign =============================================================
// always ==========================================================
// instantiation ======================================================================
//
key_filter u_start_filter(
.clk (clk ),
.rst_n (rst_n ),
.key_in (start_key),
.key_flag ( ),
.key_out (start),
.key_cont ()
);
key_filter u_pause_filter(
.clk (clk ),
.rst_n (rst_n ),
.key_in (pause_key),
.key_flag ( ),
.key_out (pause),
.key_cont ()
);
//
key_filter u_h_filter(
.clk (clk ),
.rst_n (rst_n ),
.key_in (h_key),
.key_flag ( ),
.key_out (),
.key_cont (h_add)
);
key_filter u_m_filter(
.clk (clk ),
.rst_n (rst_n ),
.key_in (m_key),
.key_flag ( ),
.key_out (),
.key_cont (m_add)
);
key_filter u_s_filter(
.clk (clk ),
.rst_n (rst_n ),
.key_in (s_key),
.key_flag ( ),
.key_out (),
.key_cont (s_add)
);
//
watch2 u_watch(
.clk (clk ),
.rst_n (rst_n ),
.start (start ), //
.pause (pause ), //
.h_add (h_add ), //when it is 1, hour will add 1
.m_add (m_add ), //when it is 1, minute will add 1
.s_add (s_add ), //when it is 1, second will add 1
.hour (hour ),
.minute (minute),
.second (second)
);
endmodule