EDA数字钟(三)

这篇具有很好参考价值的文章主要介绍了EDA数字钟(三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

再次编写数字钟Verilog程序,使其符合规范,并采用模板化与模块化编程,使程序思路更加清晰。与之前不同,此次编程在Quartus II 13.0中建立项目,在AX530开发板上下载调试,引脚定义与配置需要视情况更改,项目文件将上传到资源中。


一、设计内容

设计功能与之前保持一致:
1.具有“秒”、“分”、“时”计时的功能,小时计数器按24小时制;
2.具有校时功能,能对“分”和“时”进行调整;
3.具有手动输入设置定时闹钟的功能,亮1分钟;
4.可实现时钟复位功能:00:00:00;
5.报整点:几点亮几下。
AX530开发板有六个数码管,没有拨码开关,为与之前保持一致,仅使用其中四个数码管,用按键切换显示内容。

二、模块结构

根据输入和输出划分模块,顶层模块仅实现模块间的连接,状态控制模块控制当前显示内容,计时模块实现计时、校时、秒针输出、整点报时功能,闹钟模块实现定时闹钟的设置与输出,显示模块根据当前工作模式确定显示的内容。

三、代码编写

1、顶层模块Digclk

顶层模块尽量减少逻辑,只用作模块连接,根据输出内容划分模块功能

/***************数字钟顶层模块***************/
module Digclk(
    clk,
    rst_n,
    btn,
    led,
    smg_sig,
    smg_loc
    );

    //输入输出
    input                clk;
    input                rst_n;
    input      [2:0]     btn;
    output     [3:0]     led;
    output     [7:0]     smg_sig;
    output     [5:0]     smg_loc;
    wire       [2:0]     led;
    wire       [7:0]     smg_sig;
    wire       [5:0]     smg_loc;

    /***************状态控制模块***************/
    wire [1:0] mode;
    wire [3:0] set_loc;
    wire set_inc;
    Ctrl U_ctrl(
        .clk(clk),
        .rst_n(rst_n),
        .swc_btn(btn[2]),//切换按键
        .mov_btn(btn[1]),//移位按键
        .inc_btn(btn[0]),//加一按键
        .mode(mode),//工作状态
        .set_loc(set_loc),//位置信号
        .set_inc(set_inc)//加一信号
    );
    /***************计时模块***************/
    wire [23:0] time_data;
    Time U_time(
        .clk(clk),
        .rst_n(rst_n),
        .mode(mode),
        .set_loc(set_loc),
        .set_inc(set_inc),
        .time_data(time_data),
        .sec(led[0]),//秒针LED
        .hour(led[2])//整点报时
    );
    /***************闹钟模块***************/
    wire [15:0] alm_data;
    Alarm U_alarm(
        .clk(clk),
        .rst_n(rst_n),
        .mode(mode),
        .set_loc(set_loc),        
        .set_inc(set_inc),
        .time_data(time_data),
        .alm_data(alm_data),
        .alm(led[1])//定时闹钟
    );
    /***************显示模块***************/
    Display U_display(
        .clk(clk),
        .rst_n(rst_n),
        .mode(mode),
        .time_data(time_data),
        .alm_data(alm_data),
        .set_loc(set_loc),
        .smg_sig(smg_sig),//数码管信号
        .smg_loc(smg_loc)//数码管位置
    );

    endmodule

2、状态控制模块Ctrl

通过消抖模块处理按键信息,输出当前的工作状态与校时操作信号与位置

/***************状态控制模块***************/
module Ctrl(
    clk,
    rst_n,
    swc_btn,//切换按键
    mov_btn,//移位按键
    inc_btn,//加一按键
    mode,//工作状态
    set_loc,//位置信号
    set_inc//加一信号
    );

    //输入输出
    input                clk;
    input                rst_n;
    input                swc_btn;
    input                mov_btn;
    input                inc_btn;
    output     [1:0]     mode;
    output     [3:0]     set_loc;
    output               set_inc;
    reg        [1:0]     mode;
    reg        [3:0]     set_loc;
    wire                 set_inc;

    /***************按键消抖***************/
    wire swc_btn_f;
    wire mov_btn_f;
    wire inc_btn_f;
    Filter U_filter1(
        .clk(clk),
        .rst_n(rst_n),
        .btn(swc_btn),
        .btn_f(swc_btn_f)
    );
    Filter U_filter2(
        .clk(clk),
        .rst_n(rst_n),
        .btn(mov_btn),
        .btn_f(mov_btn_f)
    );
    Filter U_filter3(
        .clk(clk),
        .rst_n(rst_n),
        .btn(inc_btn),
        .btn_f(inc_btn_f)
    );
    /***************工作状态***************/
    wire en_mode;
    wire co_mode;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            mode <= 0;
        end
        else if(en_mode)begin
            if(co_mode)
                mode <= 0;
            else
                mode <= mode + 1;
        end
    end
    assign en_mode = swc_btn_f;       
    assign co_mode = (en_mode) && (mode == 2);   
    /***************位置信号***************/
    reg [3:0] cnt_loc;
    wire en_loc;
    wire co_loc;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_loc <= 0;
        end
        else if(en_loc)begin
            if(co_loc)
                cnt_loc <= 0;
            else
                cnt_loc <= cnt_loc + 1;
        end
    end
    assign en_loc = mov_btn_f || swc_btn_f;       
    assign co_loc = (en_loc) && ((cnt_loc == 4) || swc_btn_f);   

    always@(*)begin
        case(cnt_loc)
            0: set_loc = 4'b0000;
            1: set_loc = 4'b1000;
            2: set_loc = 4'b0100;
            3: set_loc = 4'b0010;
            4: set_loc = 4'b0001;
            default: set_loc = 4'b0000;
        endcase
    end
    /***************加一信号***************/
    assign set_inc = inc_btn_f;

    endmodule

3、按键消抖模块Filter

间隔一段时间采样,将按键的下降沿转化为一个clk的脉冲输出,可作为基本模块使用

/***************按键消抖模块***************/
module Filter(
    clk,
    rst_n,
    btn,
    btn_f
    );

    //参数定义
    parameter  CNT_200MS = 24'd9_999_999;
    parameter  CNT_200NS = 24'd9;
    //输入输出
    input                clk;
    input                rst_n;
    input                btn;
    output               btn_f;
    wire                 btn_f;

    /***************间隔200ms***************/
    reg [23:0] cnt;
    wire en;
    wire co;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt <= 0;
        end
        else if(en)begin
            if(co)
                cnt <= 0;
            else
                cnt <= cnt + 1;
        end
    end
    assign en = 1;       
    assign co = (en) && (cnt == CNT_200MS);   
    /***************buf1***************/
    reg btn_buf1;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            btn_buf1 <= 0;
        end
        else begin
            if(co)
                btn_buf1 <= btn;
        end
    end
    /***************buf2***************/
    reg btn_buf2;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            btn_buf2 <= 0;
        end
        else begin
            btn_buf2 <= btn_buf1;
        end
    end
    /***************输出正脉冲***************/
    assign btn_f = (!btn_buf1) && (btn_buf2);

    endmodule

4、计时模块Time

使用六个计数器进行时分秒的计时,将加一信号接入使能信号实现校时功能
整点报时和秒针功能也可以单独划分为一个模块

/***************计时模块***************/
module Time(
    clk,
    rst_n,
    mode,
    set_loc,
    set_inc,
    time_data,
    sec,
    hour
    );

    //参数定义
    parameter  CNT_1S = 26'd49_999_999;
    parameter  CNT_1US = 26'd49;
    //输入输出
    input                clk;
    input                rst_n;
    input      [1:0]     mode;
    input      [3:0]     set_loc;
    input                set_inc;
    output     [23:0]    time_data;
    output               sec;
    output               hour;
    wire       [23:0]    time_data;
    reg                  sec;
    reg                  hour;

    /***************校时***************/
    wire set_state;
    assign set_state = ((mode == 0) || (mode == 1)) && (set_loc != 0);
    reg [5:0] inc;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            inc <= 0;
        end
        else begin
            if((mode == 0) && set_inc)
                inc <= {set_loc, 2'b00};
            else if((mode == 1) && set_inc)
                inc <= {2'b00, set_loc};
            else 
                inc <= 0;
        end
    end
    /***************分频***************/
    reg [25:0] cnt_div;
    wire en_div;
    wire co_div;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_div <= 0;
        end
        else if(en_div)begin
            if(co_div)
                cnt_div <= 0;
            else
                cnt_div <= cnt_div + 1;
        end
    end
    assign en_div = !set_state;       
    assign co_div = (en_div) && (cnt_div == CNT_1S);   
    /***************秒个位***************/
    reg [3:0] cnt_s0;
    wire en_s0;
    wire co_s0;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_s0 <= 0;
        end
        else if(en_s0)begin
            if(co_s0)
                cnt_s0 <= 0;
            else
                cnt_s0 <= cnt_s0 + 1;
        end
    end
    assign en_s0 = co_div || inc[0];       
    assign co_s0 = (en_s0) && (cnt_s0 == 9);   
    /***************秒十位***************/
    reg [3:0] cnt_s1;
    wire en_s1;
    wire co_s1;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_s1 <= 0;
        end
        else if(en_s1)begin
            if(co_s1)
                cnt_s1 <= 0;
            else
                cnt_s1 <= cnt_s1 + 1;
        end
    end
    assign en_s1 = co_s0 || inc[1];       
    assign co_s1 = (en_s1) && (cnt_s1 == 5); 
    /***************分个位***************/
    reg [3:0] cnt_m0;
    wire en_m0;
    wire co_m0;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_m0 <= 0;
        end
        else if(en_m0)begin
            if(co_m0)
                cnt_m0 <= 0;
            else
                cnt_m0 <= cnt_m0 + 1;
        end
    end
    assign en_m0 = co_s1 || inc[2];      
    assign co_m0 = (en_m0) && (cnt_m0 == 9);   
    /***************分十位***************/
    reg [3:0] cnt_m1;
    wire en_m1;
    wire co_m1;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_m1 <= 0;
        end
        else if(en_m1)begin
            if(co_m1)
                cnt_m1 <= 0;
            else
                cnt_m1 <= cnt_m1 + 1;
        end
    end
    assign en_m1 = co_m0 || inc[3];      
    assign co_m1 = (en_m1) && (cnt_m1 == 5); 
    /***************时个位***************/
    reg [3:0] cnt_h0;
    reg [3:0] cnt_h1;
    wire en_h0;
    wire co_h0;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_h0 <= 0;
        end
        else if(en_h0)begin
            if(co_h0)
                cnt_h0 <= 0;
            else
                cnt_h0 <= cnt_h0 + 1;
        end
    end
    assign en_h0 = co_m1 || inc[4];      
    assign co_h0 = (en_h0) && ((cnt_h0 == 9) || (((cnt_h1 == 2) && ((cnt_h0 == 3)))));   
    /***************时十位***************/
    wire en_h1;
    wire co_h1;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_h1 <= 0;
        end
        else if(en_h1)begin
            if(co_h1)
                cnt_h1 <= 0;
            else
                cnt_h1 <= cnt_h1 + 1;
        end
    end
    assign en_h1 = co_h0 || inc[5];      
    assign co_h1 = (en_h1) && ((((cnt_h1 == 2) && ((cnt_h0 >= 3)))) || ((cnt_h1 >= 2) && inc[5]));
    assign time_data = {cnt_h1, cnt_h0, cnt_m1, cnt_m0, cnt_s1, cnt_s0};
    /***************整点报时***************/
    reg flag_hour;
    reg [5:0] cnt_hour;
    wire en_hour;
    wire co_hour;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_hour <= 0;
        end
        else begin
            if(en_hour)begin
                if(co_hour)
                    cnt_hour <= 0;
                else
                    cnt_hour <= cnt_hour + 1;
            end
        end
    end
    assign en_hour = ({cnt_h1, cnt_h0} != 0) && ({cnt_m1, cnt_m0} == 0) && flag_hour && co_div;
    assign co_hour = (en_hour) && (cnt_hour >= (2 * (10 * cnt_h1 + cnt_h0) - 1));   

    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            flag_hour <= 1;
        end
        else begin
            if(co_hour)
                flag_hour <= 0;
            else if({cnt_m1, cnt_m0} != 0)
                flag_hour <= 1;
        end
    end

    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            hour <= 1;
        end
        else begin
            if(set_state == 1)
                hour <= 1;
            else if(({cnt_h1, cnt_h0} != 0) && ({cnt_m1, cnt_m0} == 0) && flag_hour)
                hour <= cnt_hour[0];
        end
    end
    /***************秒针***************/
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            sec <= 1;
        end
        else begin
            if(set_state == 1)
                sec <= 1;
            else
                sec <= cnt_s0[0];
        end
    end

    endmodule

5、闹钟模块Alarm

闹钟设置与校时功能相似
将计时时间与闹钟时间比较输出闹钟信号

/***************闹钟模块***************/
module Alarm(
    clk,
    rst_n,
    mode,
    set_loc,        
    set_inc,
    time_data,
    alm_data,
    alm
    );

    //输入输出
    input                clk;
    input                rst_n;
    input      [1:0]     mode;
    input      [3:0]     set_loc;
    input                set_inc;
    input      [23:0]    time_data;
    output     [23:0]    alm_data;
    output               alm;
    wire       [23:0]    alm_data;
    reg                  alm;

    /***************校时***************/
    reg [3:0] inc;
    always@(*)begin
        if((mode == 2) && set_inc)
            inc = set_loc;
        else
            inc = 4'b0000;
    end
    /***************分个位***************/
    reg [3:0] cnt_m0;
    wire en_m0;
    wire co_m0;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_m0 <= 0;
        end
        else if(en_m0)begin
            if(co_m0)
                cnt_m0 <= 0;
            else
                cnt_m0 <= cnt_m0 + 1;
        end
    end
    assign en_m0 = inc[0];      
    assign co_m0 = (en_m0) && (cnt_m0 == 9);   
    /***************分十位***************/
    reg [3:0] cnt_m1;
    wire en_m1;
    wire co_m1;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_m1 <= 0;
        end
        else if(en_m1)begin
            if(co_m1)
                cnt_m1 <= 0;
            else
                cnt_m1 <= cnt_m1 + 1;
        end
    end
    assign en_m1 = co_m0 || inc[1];      
    assign co_m1 = (en_m1) && (cnt_m1 == 5); 
    /***************时个位***************/
    reg [3:0] cnt_h0;
    reg [3:0] cnt_h1;
    wire en_h0;
    wire co_h0;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_h0 <= 0;
        end
        else if(en_h0)begin
            if(co_h0)
                cnt_h0 <= 0;
            else
                cnt_h0 <= cnt_h0 + 1;
        end
    end
    assign en_h0 = co_m1 || inc[2];      
    assign co_h0 = (en_h0) && ((cnt_h0 == 9) || (((cnt_h1 == 2) && ((cnt_h0 == 3)))));   
    /***************时十位***************/
    wire en_h1;
    wire co_h1;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_h1 <= 0;
        end
        else if(en_h1)begin
            if(co_h1)
                cnt_h1 <= 0;
            else
                cnt_h1 <= cnt_h1 + 1;
        end
    end
    assign en_h1 = co_h0 || inc[3];      
    assign co_h1 = (en_h1) && ((((cnt_h1 == 2) && ((cnt_h0 >= 3)))) || ((cnt_h1 >= 2) && inc[3]));

    assign alm_data = {cnt_h1, cnt_h0, cnt_m1, cnt_m0};
    /***************输出***************/
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            alm <= 1;
        end
        else begin
            if(set_loc != 0)
                alm <= 1;
            else if(time_data[23:8] == alm_data)
                alm <= 0;
            else
                alm <= 1;
        end
    end 

    endmodule

6、显示模块Display

根据当前工作模式确定显示内容

/***************显示模块***************/
module Display(
    clk,
    rst_n,
    mode,
    time_data,
    alm_data,
    set_loc,
    smg_sig,
    smg_loc
    );

    //输入输出
    input                clk;
    input                rst_n;
    input      [1:0]     mode;
    input      [23:0]    time_data;
    input      [15:0]    alm_data;
    input      [3:0]     set_loc;
    output     [7:0]     smg_sig;
    output     [5:0]     smg_loc;
    wire       [7:0]     smg_sig;
    wire       [5:0]     smg_loc;

    /***************取数***************/
    reg [15:0] show_data;
    wire [23:0] num_data;
    wire [5:0] dot_data;
    always@(*)begin
        case(mode)
            0: show_data = time_data[23:8];
            1: show_data = time_data[15:0];
            2: show_data = alm_data;
            default: show_data = 0;
        endcase
    end
    assign num_data = {8'b00000000, show_data};
    assign dot_data = {2'b00, set_loc};
    /***************数码管驱动***************/
    Smg U_smg(
        .clk(clk),
        .rst_n(rst_n),
        .num_data(num_data),
        .dot_data(dot_data),
        .smg_sig(smg_sig),
        .smg_loc(smg_loc)
    );

    endmodule

7、数码管驱动模块Smg

带小数点的数码管驱动模块,可作为基本模块使用

/***************显示模块***************/
module Smg(
    clk,
    rst_n,
    num_data,
    dot_data,
    smg_sig,
    smg_loc
    );

    //参数定义
    parameter  CNT_2MS = 17'd99_999;
    parameter  CNT_200NS = 17'd9;
    //输入输出
    input                clk;
    input                rst_n;
    input      [23:0]    num_data;
    input      [5:0]     dot_data;
    output     [7:0]     smg_sig;
    output     [5:0]     smg_loc;
    reg        [7:0]     smg_sig;
    reg        [5:0]     smg_loc;
    
    /***************分频***************/
    reg [16:0] cnt_div;
    wire en_div;
    wire co_div;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_div <= 0;
        end
        else if(en_div)begin
            if(co_div)
                cnt_div <= 0;
            else
                cnt_div <= cnt_div + 1;
        end
    end
    assign en_div = 1;       
    assign co_div = (en_div) && (cnt_div == CNT_2MS);   
    /***************扫描***************/
    reg [3:0] cnt_scan;
    wire en_scan;
    wire co_scan;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            cnt_scan <= 0;
        end
        else if(en_scan)begin
            if(co_scan)
                cnt_scan <= 0;
            else
                cnt_scan <= cnt_scan + 1;
        end
    end
    assign en_scan = co_div;       
    assign co_scan = (en_scan) && (cnt_scan == 5);
    /***************取数***************/
    reg [3:0] smg_data;
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            smg_data <= 0;
        end
        else begin
            case(cnt_scan)
                0: smg_data <= num_data[3:0];
                1: smg_data <= num_data[7:4];
                2: smg_data <= num_data[11:8];
                3: smg_data <= num_data[15:12];
                4: smg_data <= num_data[19:16];
                5: smg_data <= num_data[23:20];
            endcase
        end
    end
    /***************显示***************/
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            smg_loc <= 6'b000000;
        end
        else begin
            case(cnt_scan)
                0: smg_loc <= 6'b111110;
                1: smg_loc <= 6'b111101;
                2: smg_loc <= 6'b111011;
                3: smg_loc <= 6'b110111;
                4: smg_loc <= 6'b101111;
                5: smg_loc <= 6'b011111;
            endcase
        end
    end
    /***************译码***************/
    always@(posedge clk or negedge rst_n)begin
        if(!rst_n)begin
            smg_sig <= 8'b00000011;
        end
        else begin
            case(smg_data)
                0: smg_sig[7:1] = 7'b0000001;
		        1: smg_sig[7:1] = 7'b1001111;
		        2: smg_sig[7:1] = 7'b0010010;
		        3: smg_sig[7:1] = 7'b0000110;
		        4: smg_sig[7:1] = 7'b1001100;
		        5: smg_sig[7:1] = 7'b0100100;
		        6: smg_sig[7:1] = 7'b0100000;
		        7: smg_sig[7:1] = 7'b0001111;
		        8: smg_sig[7:1] = 7'b0000000;
		        9: smg_sig[7:1] = 7'b0000100;
		        default: smg_sig[7:1] = 7'b0110000;//E
            endcase
            smg_sig[0] <= ~dot_data[cnt_scan];
        end
    end

endmodule

四、测试文件

测试文件在之前的基础上进行修改

`timescale 1 ns/ 1 ns

module Digclk_tb();
reg [2:0] btn;
reg clk;
reg rst_n;                                     
wire [2:0]  led;
wire [5:0]  smg_loc;
wire [7:0]  smg_sig;
    
//模拟按键按下
task SWC;
    begin
        #1000 btn[2] = 0;
        #1000 btn[2] = 1;
    end
endtask
task MOV;
    begin
        #1000 btn[1] = 0;
        #1000 btn[1] = 1;
    end
endtask
task INC;
    begin
        #1000 btn[0] = 0;
        #1000 btn[0] = 1;
    end
endtask
    
Digclk u1 (
	.btn(btn),
	.clk(clk),
	.led(led),
	.rst_n(rst_n),
	.smg_loc(smg_loc),
	.smg_sig(smg_sig)
);
initial begin
    clk = 0;
    rst_n = 1;
end

always begin
    #10 clk = ~clk;
end

initial begin
    // Initialize Inputs
    rst_n = 1;
    btn = 3'b111;

    // Wait 200 ns for global rst_n to finish
    #100 rst_n = 0;
    #100 rst_n = 1;
    
    // Add stimulus here
//////////////////////////////////////////////闹钟测试 
    //闹钟置数1200,闹钟指针1000
    INC;//空加
    repeat(2) SWC;//2
    MOV;
    repeat(4) INC;//1
    MOV;
    repeat(2) INC;//2
//////////////////////////////////////////////校时测试
    //时分置数1159
    //置数模式
    #10000;
    SWC;
    MOV;
    INC;//1
    MOV;
    INC;//1
    MOV;
    repeat(5) INC;//5
    MOV;
    repeat(9) INC;//9    
    //秒置数58
    SWC;   
    #10000;
    repeat(3) MOV;
    repeat(1) INC;//5
    MOV;
    repeat(1) INC;//8
    MOV;
//////////////////////////////////////////////状态切换测试
    //显示分秒
    #10000;
    SWC;
    //显示闹钟
    #10000;
    SWC;
//////////////////////////////////////////////清零测试
    //清零
    #10000 rst_n = 0;
    #10000 rst_n = 1;
//////////////////////////////////////////////进位测试
    //分置数59
    SWC;
    MOV;
    repeat(5) INC;//5
    MOV;
    repeat(8) INC;//8
    //时置数23
    repeat(2) SWC;
    #10000 
    MOV;
    repeat(5) INC;//2
    MOV;
    repeat(3) INC;//3
    SWC;
//////////////////////////////////////////////防抖测试
    #10000 btn[2] = 0;//忽略
    #10 btn[2] = 1;
    #30 btn[2] = 0;//触发
    #1000 btn[2] = 1;
    #50 btn[2] = 0;//忽略
    #70 btn[2] = 1;
    #1000 btn[2] = 0;//触发
    #1000 btn[2] = 1;
end

endmodule

五、波形仿真

1、变量名称说明
rst_n:清零按键;
btn[2:0]:切换、移位、加一按键;
xxx_btn_f:经过消抖模块后的按键信号;
mode:工作模式(0:时分,1:分秒,2:闹钟)
time_data:计时时间;
alm_data:闹钟时间;
num_data:显示内容;
smg_loc:数码管位置;
smg_data:数码管数据;
smg_sig:数码管信号;
set_loc:操作位置;
dot_data:小数点信息;
led[2:0]:整点报时LED、闹钟LED,秒LED。
EDA数字钟(三)
2、闹钟设置测试
将闹钟设置为12:00
EDA数字钟(三)
3、时钟校时测试
将时钟设置为11:59:58
EDA数字钟(三)

4、闹钟、整点报时测试
到12:00闹钟响一分钟,整点报时闪12下
EDA数字钟(三)

5、显示内容测试
切换工作状态,分别显示时分、分秒、闹钟
EDA数字钟(三)
6、复位测试
EDA数字钟(三)
7、进位测试
设置计时值为23:59:23,测试数字钟进位
EDA数字钟(三)
8、消抖测试
对按键btn[2]进行消抖测试,将其转化为swc_btn_f
EDA数字钟(三)

总结

程序在AX530开发板上实测通过
逻辑部分做了部分改动,主要是为了方便操作
控制模块本来打算用状态机写的,但后来发现没有必要
单独写一个控制模块总感觉有些奇怪
校时的逻辑还是有些混乱,包括整点报时也可以再改改文章来源地址https://www.toymoban.com/news/detail-471530.html

到了这里,关于EDA数字钟(三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 年轻人的第一个数字钟!适用于FPGA的数字钟Verilog实现

    因为闲。 当然也不是很闲,初衷是因为本科时上过的数电实验课最后的大作业就是在 FPGA 上实现一个数字钟,这个作业当时困扰了我们班的诸多同学(难以置信,我们只是学材料的弱小可怜又无助{{{(_)}}}。最终,大部分同学在 拷贝一位学长的代码 一位学长的帮助下顺利通过

    2024年02月11日
    浏览(47)
  • 【verilog】多功能数字钟的设计

    掌握数字钟的工作原理。 掌握计数器级联构成更大模值计数器的方法。  能用verilog描述简单的时序逻辑电路。         多功能数字钟应该具有的基本功能有:显示时-分-秒、整点报时、小时和分钟可调等。首先要知道钟表的工作机理,整个钟表的工作应该是在1Hz信号的

    2024年02月04日
    浏览(61)
  • 自动报时数字钟

    设计任务和要求: 1、用数字显示时、分、秒。12小时循环一次。 2、可以在任意时刻校准时间,只用几只按钮开关实现,切求可靠方便。 3、能以蜂鸣器自动正点报时,在进时来到后或来到前,进行整点报时。 设计要求分析:       根据设计任务与要求,可初步将系统分为

    2024年02月08日
    浏览(48)
  • 实验 7 数字钟设计

    7.1 实 验 目 的 设计一个具有时功能和校的数字钟。 7.2 实 验 仪 器 与 器 材 1. EDA 开发软件 一 套 2.微机 一 台 3.实验开发系统 一 台 4.打印机 一 台 5.其他器件与材料 若 干 7.3 实 验 说 明 用 数码管显示小时 、 分 钟 和 秒钟。 三 个 按键用于时钟校准。 K1 用 与切换

    2024年01月22日
    浏览(42)
  • 【数字钟实验1】logisim

    数字逻辑大作业1.0,用logisim画数字钟(经典实验了属于是🧪) 开始做实验的时候也才刚刚学完时序逻辑那一章,计数器提都没提过(笑死我怀疑老师是特意这么安排的),而且logisim完全不会用,隧道什么的根本不懂【这也就导致了我后面没有力气做外观封装了,累了🤦‍♀️

    2024年02月11日
    浏览(43)
  • 数字系统设计(FPGA)课程设计: 多功能数字钟

    一、目的: 实现多功能数字钟,具备下列功能: 1、数字钟:能计时,实现小时、分钟、秒的显示; 2、数字跑表:精度至0.01秒 比如显示12.97秒; 3、闹钟: 可以设定闹钟,用试验箱上的蜂鸣器作为闹铃; 4、调时:可以对时间进行设定; 5、日期设定:能设定日期并显示当前

    2023年04月18日
    浏览(47)
  • 电子设计数字钟,multisim仿真·

    设计步骤(分模块叙述,并附上各模块与总体电路图) 1.计时模块,显示模块,调时模块设计 计数器模块由七片74LS160的芯片组成,两片为“秒”,两片为“分”,两片为“时”,还有一片作为“星期”,七个数码管显示器用来显示数字。‘秒’和‘分’采用60进制。通过异步

    2024年02月11日
    浏览(44)
  • 基于FPGA的数字钟设计

    这篇文章通过VHDL代码实现数字钟的功能,绑定引脚就可以看到实际的效果。 代码运行成功,就可以实现了计时(年月日/时分秒)、秒表、倒计时、闹钟的全部功能。

    2024年02月11日
    浏览(59)
  • 基于FPGA的可调数字钟设计

            在此特别感谢哔站up主 甘第 发布的FPGA企业实训课(基于FPGA的数字钟设计)教学视频,让一个FPGA小白开始了第一个FPGA设计开发流程。本设计参考了这个教学视频,在此基础上添加并修改了一些代码,完成了这个小小的不带任何功能的数字时钟。         初次学习

    2024年02月06日
    浏览(62)
  • 数电仿真实验-数字钟的设计

    1、掌握任意模值计数器的设计方法 2、掌握multisim仿真软件对电路进行仿真验证的方法。 3、掌握数字综合系统设计的方法,能够对整体电路进行功能测试及故障检测。

    2023年04月26日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包