Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

verilog 12hour clock trouble

I am trying to design a twelve hour clock in Verilog to load into a DE2 board.

I have the seconds and minutes working just fine but am lost as to how get the hours to count properly.

The way the logic needs to work is after decimal_counter_hour_0 increments up to 9, decimal_counter_hour_1 will increase its

count by one and decimal_counter_hour_0 will return to a 0 on the positive clock edge showing 10:00. Because this is a 12 hour clock the count needs

to be 10:00, 11:00, 12:00, and then start over at 1:00. I am lost as to how to implament the logic of this requierment. If you could give me

a push in the right direction I would apreciate it. Thanks for the help. Below is the code to hours counters as they stand now.

//This counter is the ones place of the hours count.

module decimal_counter_hour_0(A,OVERFLOW,CLK,RST);

input CLK, RST;

output OVERFLOW;

output [3:0] A;

reg OVERFLOW;

reg [3:0] A;

always @ (posedge CLK or negedge RST)

if (~RST) begin

OVERFLOW <= 1'b0; //On reset a 0 from this counter is sent to the CLK input of the next counter telling it to hold its state.

A <= 4'b0000; //On reset a 0 is is sent to the hex display.

end

else if (A<9) begin //If 'A' has a count that is less than 9 add one to the count on each

A <= A + 1'b1; //positive clock edge.

OVERFLOW <= 1'b0; //A 0 from this counter is sent to the CLK input of the next counter telling it to hold its state

end //after the count has been incremented by one.

else begin

A <= 4'b0000; //On the next positive CLK edge after 'A' has been at 9, start the count over at 0.

OVERFLOW <= 1'b1; //A 1 from this counter is sent as a posedge clock signal to the next counter.

end

endmodule

//This counter is the tens place of the hours count.

module decimal_counter_hour_1(A,OVERFLOW,CLK,RST);

input CLK, RST;

output OVERFLOW;

output [3:0] A;

reg OVERFLOW;

reg [3:0] A;

always @ (posedge CLK or negedge RST)

if (~RST) begin

OVERFLOW <= 1'b0; //On reset a 0 from this counter is sent to the CLK input of the next counter telling it to hold its state.

A <= 4'b0000; //On reset a 0 is is sent to the hex display.

end

else if (A<1) begin //If 'A' has a count that is less than 1 add one to the count on each

A <= A + 1'b1; //positive clock edge.

OVERFLOW <= 1'b0; //A 0 from this counter is sent to the CLK input of the next counter telling it to hold its state

end //after the count has been incremented by one.

else begin

A <= 4'b0000; //On the next positive CLK edge after 'A' has been at 1, start the count over at 0.

OVERFLOW <= 1'b1; //A 1 from this counter is sent as a posedge clock signal to the next counter.

end

endmodule

1 Reply

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I am trying to design a twelve hour clock in Verilog to load into a DE2 board.

    I have the seconds and minutes working just fine but am lost as to how get the hours to count properly.

    The way the logic needs to work is after decimal_counter_hour_0 increments up to 9, decimal_counter_hour_1 will increase its

    count by one and decimal_counter_hour_0 will return to a 0 on the positive clock edge showing 10:00. Because this is a 12 hour clock the count needs

    to be 10:00, 11:00, 12:00, and then start over at 1:00. I am lost as to how to implament the logic of this requierment.

    --- Quote End ---

    Hello.

    It is not that simple; while all other digits (minutes and seconds) can be done with the simple "Overflow" logic the hours cannot:

    The lower digit of the hour overflows from 9 to 0 if the higher digit is 0 but it overflows from 2 to 1 if the higher digit is 1. This means the counter for the lower digit must know the higher digit.

    There are two principial ways to handle this:

    1) Use the output of the higher digit counter as input into the lower digit counter

    2) Count both digits in the same module. This solution appears easier to me.

    Solution 2 may look like this (code shown here is NOT tested):

    
    module decimal_counter_hour(A10,A1,OVERFLOW,CLK,RST);
        input CLK, RST;
        output OVERFLOW;
        output A10;
        output  A1;
        wire A10;
        wire OVERFLOW;
        wire  A1;
        
        reg  hour;
        
        initial hour = 1;
        always @ (posedge CLK or negedge RST)
        if (RST && hour<12) begin
            hour = hour + 1;
        end
        else begin
            hour = 1;
        end
        assign OVERFLOW = (hour < 2);
        assign A10 = (hour > 9);
        assign A1 = A10 ? (hour - 10) : hour;
    endmodule
    
    Martin