【verilog】 FPGA倒计时器设计

  • 思路
  • CODE
  • 顶层CODE

思路

将时间拆分为6个参数:

        second_1  -> 秒个位
        second_10 -> 秒十位
        minute_1  -> 分个位
        minute_10 -> 分十位
        hour_1;   -> 时个位
        hour_10;  -> 时十位

在异步复位的时候为上述六个参数赋初始值。
然后对50Mhz系统时钟进行计数,计数50M次(即为1s)。然后对六个参数的当前值做出判断,并在下一个clk做出改变。

当计满一秒,且秒的个位大于0时,——》秒的个位减1
当计满一秒,且秒的个位等于0,秒的十位大于0时,——》秒的十位减1,秒的个位变9
当计满一秒,且秒为00,并且分的个位大于0时,——》分的个位减1,秒由00变为59
当计满一秒,且秒为00,并且分的个位等于0,分的十位大于0时,——》分的十位减1,个位变为9,秒由00变为59
当计满一秒,且秒为00,分也为00,时的个位大于0时,——》时的个位减1,分由00变为59,秒也由00变为59
当计满一秒,且秒为00,分也为00,时的个位等于0,时的十位大于0时,——》时的十位减1,个位变9,分由00变为59,秒也由00变为59
当计满一秒,且时分秒为:00 00 00时,——》还原为预设值

仅当【suspend】状态值为1的时候才会对50Mhz系统时钟进行计数,为0时暂停计数,这样就实现了计数器的暂停。

CODE

module down_cnt(
                clk,
                rst,
                suspend,
                second_1,
                second_10,
                minute_1,
                minute_10,
                hour_1,
                hour_10
);
 

        input clk;
        input rst;
        input suspend; //当suspend为状态量,为0时计时暂停,为1时计时继续。
        output reg [3:0] second_1; //秒个位
        output reg [2:0] second_10;//秒十位
        output reg [3:0] minute_1; //分个位
        output reg [2:0] minute_10;//分十位
        output reg [3:0] hour_1;   //时个位
        output reg [1:0] hour_10;  //时十位

        reg [31:0] cnt;//50M -> 1s (50M时钟进行50M次计数得到一秒,)

always@(posedge clk or negedge rst)
        begin
                if(!rst)//复位时设置倒计时初始值
                    begin
                            cnt <= 32'd0;
                            second_1 <= 4'd0;
                            second_10 <= 3'd0;
                            minute_1 <= 4'd1;
                            minute_10 <= 3'd0;
                            hour_1 <= 4'd0;
                            hour_10 <= 2'd0;
                    end	
                    //当计满一秒,且秒的个位大于0时,——》秒的个位减1
                    else if(cnt == 32'd5000_0000 && second_1>4'd0)
                        begin
                            second_1 <= second_1 - 4'd1;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒的个位等于0,秒的十位大于0时,——》秒的十位减1,秒的个位变9
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10>3'd0 )
                        begin
                            second_10 <= second_10 - 3'd1;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒为00,并且分的个位大于0时,——》分的个位减1,秒由00变为59
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1>4'd0 )
                        begin
                            minute_1 <= minute_1 - 4'd1;	
                            second_10 <= 3'd5;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒为00,并且分的个位等于0,分的十位大于0时,——》分的十位减1,个位变为9,秒由00变为59
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1==4'd0 && minute_10 > 3'd0)
                        begin
                           minute_10 <= minute_10 - 3'd1;
                            minute_1 <= 4'd9;
                            second_10 <= 3'd5;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒为00,分也为00,时的个位大于0时,——》时的个位减1,分由00变为59,秒也由00变为59
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1==4'd0 && minute_10 ==3'd0 && hour_1 >4'd0)
                        begin
                            hour_1 <= hour_1 - 4'd1;
                            minute_10 <= 3'd5;
                            minute_1 <= 4'd9;
                            second_10 <= 3'd5;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且秒为00,分也为00,时的个位等于0,时的十位大于0时,——》时的十位减1,个位变9,分由00变为59,秒也由00变为59
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0&& minute_1==4'd0 && minute_10 ==3'd0 && hour_1 == 4'd0 && hour_10 > 2'd0 && hour_10< 2'd2 )
                        begin
                            hour_10 <= hour_10 - 2'd1;
                           hour_1 <= 4'd9;
                            minute_10 <= 3'd5;
                            minute_1 <= 4'd9;
                            second_10 <= 3'd5;
                            second_1 <= 4'd9;
                            cnt <= 32'd0;
                        end
                    //当计满一秒,且时分秒为:00 00 00时,——》还原为预设值
                    else if(cnt == 32'd5000_0000 && second_1==4'd0 && second_10==3'd0 && minute_1==4'd0 && minute_10 ==3'd0 && hour_1 == 4'd0 && hour_10 == 2'd0 )
                        begin
                            hour_10 <= 2'd0;
                            hour_1 <= 4'd0;
                            minute_10 <= 3'd0;
                            minute_1 <= 4'd0;
                            second_10 <= 3'd0;
                            second_1 <= 4'd0;
                            cnt <= 32'd0;
                        end                       
                    else if(suspend == 1'b1)
                        begin
                            cnt <= cnt + 32'd1;
                        end
                    else
                        begin
                            cnt <= cnt;
                        end

        end
endmodule

顶层CODE

使用六个数码管来显示六个时间参数,下为顶层文件。(数码管的驱动见:链接)

module top(
				clk,
				rst,
				dig,
                suspend,
                dict
				);
    input clk;
    input rst;
    input suspend;
    output  [5:0] dig;  //六个数码管片选
    output  [7:0] dict; //动态数码管段选
    
    wire [23:0] set_data;//数码管显示的内容:4bit*6 
 down_cnt f1(
            .clk(clk),
            .rst(rst),
            .suspend(suspend),
            .second_1(set_data[3:0]),
            .second_10(set_data[7:4]),
            .minute_1(set_data[11:8]),
            .minute_10(set_data[15:12]),
            .hour_1(set_data[19:16]),
            .hour_10(set_data[23:20])
);
                
        dig8_6 f2(
                 .clk(clk),
                 .rst(rst),
                 .set_data(set_data),
                 .dig(dig), 
                 .dict(dict)
               );
               
            
endmodule

你可能感兴趣的:(Verilog,fpga,verilog)