Design Spec:
- 输入信号:clk;
- 输入信号:同步复位信号:reset;
- 输入信号:使能信号:ena;//定义为1正常工作,为0时间保持静止
- 输入信号:数据加载信号:load;//定义为1加载load_data中的数据,为0不加载
- 输入信号:加载数据:load_data;//用来强制加载的数据,20位宽,前4位为小时,范围1~12,后16位中前8位为分钟的BCD码(00~59),后8位为秒的BCD码(00~59)。
- 输出信号:小时输出:hh;//0x1~0xC
- 输出信号:分钟输出:mm;//BCD码(00~59)
- 输出信号:秒输出:ss;//BCD码(00~59)
对应代码:
RTL:
`include "../rtl/Modminute.v"
module Clock12hr(
input clk,
input reset,
input ena,
input load,
input [19:0] load_data,
output reg [7:0] ss,
output reg [7:0] mm,
output reg [7:0] hh
);
reg [15:0] q;
Modminute u_Modminute(
.clk(clk),
.reset(reset),
.ena(ena),
.load(load),
.load_data(load_data[15:0]),
.ss(ss),
.mm(mm)
);
assign q = {mm, ss};
always@(posedge clk) begin
if(reset) begin
hh <= 4'b1100;
end
else if(load) begin
hh <= load_data[19:16];
end
else if(ena) begin
if(hh > 4'b1100) begin
hh <= 4'b1100;
end
else if(hh == 4'b1100 && q == 16'h5959) begin
hh <= 4'b0001;
end
else if(q == 16'h5959) begin
hh <= hh + 1'b1;
end
else begin
hh <= hh;
end
end
else begin
hh <= hh;
end
end
endmodule
`include "../rtl/Mod60.v"
module Modminute(
input clk,
input reset,
input ena,
input load,
input [15:0] load_data,
output reg [7:0] mm,
output reg [7:0] ss
);
wire ena_m;
//second part
Mod60 u_Mod60_ss(
.clk(clk),
.reset(reset),
.ena(ena),
.load(load),
.load_data(load_data[7:0]),
.q(ss)
);
//minute part
Mod60 u_Mod60_mm(
.clk(clk),
.reset(reset),
.ena(ena_m),
.load(load),
.load_data(load_data[15:8]),
.q(mm)
);
assign ena_m = (ss == 8'h59)?1'b1:1'b0;
endmodule
`include "../rtl/Mod10.v"
module Mod60(
input clk,
input reset,
input ena,
input load,
input [7:0] load_data,
output reg [7:0] q
);
Mod10 u_Mod10(
.clk(clk),
.reset(reset),
.ena(ena),
.load(load),
.load_data(load_data[3:0]),
.q(q[3:0])
);
always@(posedge clk) begin
if(reset) begin
q[7:4] <= 4'b0;
end
else if(load) begin
q[7:4] <= load_data[7:4];
end
else if(ena) begin
if(q[7:4] > 4'b0101) begin
q[7:4] <= 4'b0101;
end
else if(q[7:4] == 4'b0101 && q[3:0] == 4'b1001) begin
q[7:4] <= 4'b0;
end
else if(q[3:0] == 4'b1001) begin
q[7:4] <= q[7:4] + 1'b1;
end
end
else begin
q[7:4] <= q[7:4];
end
end
endmodule
module Mod10(
input clk,
input reset,
input ena,
input load,
input [3:0] load_data,
output reg [3:0] q
);
always@(posedge clk) begin
if(reset) begin
q <= 4'b0;
end
else if(load) begin
q <= load_data;
end
else if(ena) begin
if(q == 4'b1001) begin
q <= 4'b0;
end
else begin
q <= q + 1'b1;
end
end
else begin
q <= q;
end
end
endmodule
TB:
module Clock12hr_tb;
reg clk;
reg reset;
reg ena;
reg load;
reg [19:0] load_data;
wire [7:0] ss;
wire [7:0] mm;
wire [7:0] hh;
Clock12hr u_Clock12hr(
.clk(clk),
.reset(reset),
.ena(ena),
.load(load),
.load_data(load_data),
.ss(ss),
.mm(mm),
.hh(hh)
);
initial begin
clk = 0;
reset = 1;
ena = 1;
load = 0;
load_data = 20'h0;
#50 reset = 0;
end
always #10 clk = ~clk;
initial begin
#5000000 $finish;
end
endmodule