传送门:Count clock - HDLBits (01xz.net)https://hdlbits.01xz.net/wiki/Count_clock
要求:
用计数器设计一个带am/pm的12小时时钟。该计数器通过一个CLK进行计时,每当时钟增加(即每秒一次)时,ena 就会有一个脉冲。
reset信号将时钟复位为12:00 AM。
信号pm为0表示AM,为1表示PM。hh、mm和ss由两个BCD计数器(二进制编码十进制)构成,分别表示 小时(01~12),分钟(00~59) , 秒(00~59)。
Reset信号比enable信号有更高的优先级,即使没有enable信号也可以进行复位操作。
下图所示的时序图给出了从11:59:59 AM 到12 :00 : 00 PM的翻转行为以及同步复位和启用行为。
以下是我的代码:
module top_module(
input clk,
input reset,
input ena,
output pm,
output [7:0] hh,
output [7:0] mm,
output [7:0] ss);
always @(posedge clk)begin
if(reset)
pm<= 1'b0;
else if (hh[7:0]==8'h11&&mm[7:0]==8'h59&&ss[7:0]==8'h59)
pm <= ~pm;
else pm <= pm;
end
bcd bcdss0(clk,reset,ena,ena,4'h0,4'h9,ss[3:0]);
bcd bcdss1(clk,reset,ena,ss[3:0]==4'h9,4'h0,4'h5,ss[7:4]);
bcd bcdmm0(clk,reset,ena,ss[7:0]==8'h59,4'h0,4'h9,mm[3:0]);
bcd bcdmm1(clk,reset,ena,mm[3:0]==4'h9&&ss[7:0]==8'h59,4'h0,4'h5,mm[7:4]);
hour hour1(clk,reset,ena,ss[7:0]==8'h59&&mm[7:0]==8'h59,hh[7:0]);
endmodule
module bcd(
input clk,
input reset,
input ena,
input en,
input [3:0]data0,
input [3:0]max,
output [3:0]data
);
always@(posedge clk)begin
if(reset)
data<= data0;
else if(ena)begin
if(en)begin
if(data==max)data<= 4'h0;
else data<=data +1'h1;
end
else data <=data;
end
else data<=data;
end
endmodule
module hour(
input clk,
input reset,
input ena,
input en,
output [7:0]data);
always@(posedge clk)begin
if(reset)
data[7:0]<= 8'h12;
else if(ena)begin
if((data[7:0]==8'h12)&&en)
data[7:0]<= 8'h01;
else if(en)begin
if(data[7:0]<8'h9)
data[3:0]<=data[3:0] +1'h1;
else
if (data[7:0]==8'h9)
data[7:0]<=8'h10;
else begin
data[7:4]<= 4'h1;
data[3:0] <= data[3:0]+1'h1;
end
end
else data <=data;
end
else data<=data;
end
endmodule