Verilog-12-小时制电子钟
目录
Verilog - 12 小时制电子钟
Verilog实现12小时制电子钟
sec_counter.v
module sec_counter(
input i_clk,
input i_rst,
input i_ena,
output reg [7:0] o_ss,
output reg carry_out
);
always @(posedge i_clk or posedge i_rst) begin
if (i_rst) begin
o_ss <= 8'b0;
carry_out <= 1'b0;
end
else if (i_ena) begin
carry_out <= 1'b0;
if (o_ss[3:0] == 4'b1001) begin // 个位进位
o_ss[3:0] <= 4'b0;
if (o_ss[7:4] == 4'b0101) begin // 秒进位
o_ss[7:4] <= 4'b0;
carry_out <= 1'b1;
end
else begin
o_ss[7:4] <= o_ss[7:4] + 4'b1;
end
end
else begin
o_ss[3:0] <= o_ss[3:0] + 4'b1;
end
end
end
endmodule
min_counter.v
module min_counter(
input i_clk,
input i_rst,
input i_ena,
output reg [7:0] o_mm,
output reg carry_out
);
always @(posedge i_clk or posedge i_rst) begin
if (i_rst) begin
o_mm <= 8'b0;
carry_out <= 1'b0;
end
else if (i_ena) begin
carry_out <= 1'b0;
if (o_mm[3:0] == 4'b1001) begin // 个位进位
o_mm[3:0] <= 4'b0;
if (o_mm[7:4] == 4'b0101) begin // 分钟进位
o_mm[7:4] <= 4'b0;
carry_out <= 1'b1;
end
else begin
o_mm[7:4] <= o_mm[7:4] + 4'b1;
end
end
else begin
o_mm[3:0] <= o_mm[3:0] + 4'b1;
end
end
end
endmodule
hour_counter.v
module hour_counter(
input i_clk,
input i_rst,
input i_ena,
output reg [7:0] o_hh,
output reg o_pm
);
always @(posedge i_clk or posedge i_rst) begin
if (i_rst) begin
o_hh <= 8'b0;
o_pm <= 1'b0;
end
else if (i_ena) begin
if (o_hh[7:0] == 8'b00010001) begin // 半天结束
o_hh[7:0] <= 8'b0;
o_pm <= ~o_pm;
end
else if (o_hh[3:0] == 4'b1001) begin
o_hh[3:0] <= 4'b0;
o_hh[7:4] <= o_hh[7:4] + 4'b1;
end
else begin
o_hh[3:0] <= o_hh[3:0] + 4'b1;
end
end
end
endmodule
test.v
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2025/09/14 16:02:45
// Design Name:
// Module Name: test
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module test(
input i_clk,
input i_rst,
input i_ena,
output o_pm,
output [7 : 0] o_hh,
output [7 : 0] o_mm,
output [7 : 0] o_ss
);
wire sec_to_min;
wire min_to_hour;
sec_counter u_sec_counter(
.i_clk(i_clk),
.i_rst(i_rst),
.i_ena(i_ena),
.o_ss(o_ss),
.carry_out(sec_to_min)
);
min_counter u_min_counter(
.i_clk(sec_to_min),
.i_rst(i_rst),
.i_ena(i_ena),
.o_mm(o_mm),
.carry_out(min_to_hour)
);
hour_counter u_hour_counter(
.i_clk(min_to_hour),
.i_rst(i_rst),
.i_ena(i_ena),
.o_hh(o_hh),
.o_pm(o_pm)
);
endmodule
test_tb.v
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2025/09/14 16:06:01
// Design Name:
// Module Name: test_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module test_tb();
reg i_clk = 0;
reg i_rst = 1;
reg i_ena = 1;
wire o_pm;
wire [7 : 0] o_hh;
wire [7 : 0] o_mm;
wire [7 : 0] o_ss;
test u_test(
.i_clk (i_clk),
.i_rst (i_rst),
.i_ena (i_ena),
.o_pm (o_pm ),
.o_hh (o_hh ),
.o_mm (o_mm ),
.o_ss (o_ss )
);
always #1 i_clk = ~i_clk;
initial begin
#3 i_rst <= 0; i_clk <= 0; i_ena <= 1;
#7 i_rst <= 1;
#3 i_rst <= 0;
#1000000000;
$stop;
end
endmodule