目录

Verilog-12-小时制电子钟

Verilog - 12 小时制电子钟

https://i-operation.csdnimg.cn/images/cf31225e169b4512917b2e77694eb0a2.pngVerilog实现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