HDLBits刷题_Count clock

Create a set of counters suitable for use as a 12-hour clock (with am/pm indicator). Your counters are clocked by a fast-running clk, with a pulse on ena whenever your clock should increment (i.e., once per second).

reset resets the clock to 12:00 AM. pm is 0 for AM and 1 for PM. hh, mm, and ss are two BCD (Binary-Coded Decimal) digits each for hours (01-12), minutes (00-59), and seconds (00-59). Reset has higher priority than enable, and can occur even when not enabled.

The following timing diagram shows the rollover behaviour from 11:59:59 AM to 12:00:00 PM and the synchronous reset and enable behaviour.

解题思路:对于秒ss,当其计时到59时自动归零,并向分mm发出一个使能信号使其+1;

对于分mm,当mm计时到59并且ss计时到59时归零,并向时hh发出一个使能信号使其+1;

对于时hh,当hh计时到11,并且mm计时到59,并且ss计时到59时,让pm翻转;当计时到12:59:59时,令hh=1,mm=0,ss=0;

使能和清零信号单独处理。

module top_module(
    input clk,
    input reset,
    input ena,
    output pm,
    output [7:0] hh,
    output [7:0] mm,
    output [7:0] ss); 
    
    wire [1:0] enable; //使能信号,enable[0]为mm使能,enable[1]为hh使能
    ssBCD s1 (clk, reset, ena, ss); //ss计时模块
    assign enable[0] = (ss == 8'h59) ? 1 : 0; //ss==59时使能mm计时
    
    mmBCD m1 (clk, reset, enable[0], ss, mm); //mm计时模块
    assign enable[1] = ((ss == 8'h59) && (mm == 8'h59)) ? 1 : 0; //ss==59并且mm==59时使能mm计时
    
    hhBCD h1 (clk, reset, enable[1], ss, mm, hh, pm); //hh计时模块
            
endmodule

module ssBCD (input clk, reset, ena, output [7:0] ss); //ss计时模块
    always @(posedge clk) begin
        if (reset | (ss == 8'h59)) ss = 8'h00; //ss==59时自动归零
        else if (ena == 0) ss = ss; //使能信号控制ss计时与否
        else if (ss[3:0] == 9) begin ss[7:4]++; ss[3:0] = 0; end //2个BCD数字计时
        else ss[3:0]++;
    end
endmodule

module mmBCD (input clk, reset, ena, input [7:0] ss, output [7:0] mm);
    always @(posedge clk) begin
        if (reset | ((ss == 8'h59) && (mm == 8'h59))) mm = 8'h00;
        else if (ena == 0) mm = mm; 
        else if (mm[3:0] == 9) begin mm[7:4]++; mm[3:0] = 0; end
        else mm[3:0]++;
    end
endmodule


module hhBCD (input clk, reset, ena, input [7:0] ss, input [7:0] mm, output [7:0] hh, output pm);
    always @(posedge clk) begin
        if (reset) begin hh = 8'h12; pm = 0; end 
        else if ((hh == 8'h11) && (ss == 8'h59) && (mm == 8'h59)) begin hh = 8'h12; pm = !(pm); end 
        else if ((hh == 8'h12) && (ss == 8'h59) && (mm == 8'h59)) begin hh = 8'h01; end 
        else if (ena == 0) hh = hh; 
        else if (hh[3:0] == 9) begin hh[7:4]++; hh[3:0] = 0; end
        else hh[3:0]++;
    end
endmodule

你可能感兴趣的:(HDLBits刷题,fpga开发)