EDA数字钟(三)

news2024/12/26 0:18:52

文章目录

  • 前言
  • 一、设计内容
  • 二、模块结构
  • 三、代码编写
    • 1、顶层模块Digclk
    • 2、状态控制模块Ctrl
    • 3、按键消抖模块Filter
    • 4、计时模块Time
    • 5、闹钟模块Alarm
    • 6、显示模块Display
    • 7、数码管驱动模块Smg
  • 四、测试文件
  • 五、波形仿真
  • 总结


前言

再次编写数字钟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。

2、闹钟设置测试
将闹钟设置为12:00

3、时钟校时测试
将时钟设置为11:59:58

4、闹钟、整点报时测试
到12:00闹钟响一分钟,整点报时闪12下

5、显示内容测试
切换工作状态,分别显示时分、分秒、闹钟

6、复位测试

7、进位测试
设置计时值为23:59:23,测试数字钟进位

8、消抖测试
对按键btn[2]进行消抖测试,将其转化为swc_btn_f

总结

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/609296.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据迁移工具,用这8种就够了

前言 最近由于工作需要需要进行数据迁移&#xff0c;那么ETL数据迁移工具该用哪些呢&#xff1f; ETL(是Extract-Transform-Load的缩写&#xff0c;即数据抽取、转换、装载的过程)&#xff0c;对于企业应用来说&#xff0c;我们经常会遇到各种数据的处理、转换、迁移的场景。…

50 Projects 50 Days - Split Landing Page 学习记录

项目地址 Split Landing Page 展示效果 Split Landing Page 实现思路 当鼠标移动到左右两块区域时&#xff0c;分别给容器添加不同的class实现样式的变换。 有两种思路可以实现&#xff0c;一种是hover时改变宽度&#xff0c;一种是hover时改变flex拉伸比例&#xff0c;两…

从零手写操作系统之RVOS外设中断实现-04

从零手写操作系统之RVOS外设中断实现-04 RISC-V 中断&#xff08;Interrupt&#xff09;的分类RISC-V Trap &#xff08;中断&#xff09;处理中涉及的寄存器寄存器 mie、mip中断处理流程PLIC 介绍外部中断&#xff08;external interrupt &#xff09;PLICPLIC Interrupt Sour…

精调万分(Fine tune SAM)-万分预测器的解读和精调之一

缘起 分割万物(segment-anything model, SAM, 万分), 是图像分割领域的革命, 图像分割从此进入大模型时代. 如何自定义这个大模型以为己用? 或者说, 通过精调取长补短用于自己的项目?这是一个值得研究的问题, 在这里我试着探索一下, 万分在医学影像学里面的脊柱分割的应用. …

【sentinel】滑动时间窗口算法在Sentinel中的应用

固定窗口算法&#xff08;计数器法&#xff09; 算法介绍 计数器法是限流算法里最简单也是最容易实现的一种算法。比如我们规定&#xff0c;对于A接口来说&#xff0c;我们1秒的访问次数不能超过10次。那么我们可以这么做&#xff1a;在一开始的时候&#xff0c;我们可以设置…

ESP-BOX官方例程实践

1.下载esp-box项目代码 github仓库&#xff1a;https://github.com/espressif/esp-box gitee仓库&#xff1a;https://gitee.com/EspressifSystems/esp-box 使用git工具和如下命令进行下载&#xff1a; git clone --recursive https://github.com/espressif/esp-box.git or gi…

【C++ 基础篇:21】:friend 友元四连问:什么是友元?友元类?友元函数?什么时候用友元?

本系列 C 相关文章 仅为笔者学习笔记记录&#xff0c;用自己的理解记录学习&#xff01;C 学习系列将分为三个阶段&#xff1a;基础篇、STL 篇、高阶数据结构与算法篇&#xff0c;相关重点内容如下&#xff1a; 基础篇&#xff1a;类与对象&#xff08;涉及C的三大特性等&#…

S7-200 PLC的CPU模块介绍

更多关于西门子S7-200PLC内容查看&#xff1a;西门子200系列PLC学习课程大纲(课程筹备中) 1.什么是西门子200PLC的CPU? 如下图1-1所示&#xff0c;S7-200 PLC CUP是将一个微处理器&#xff0c;一个集成电源&#xff0c;一定的数字量或模拟量I/O&#xff0c;一定的通信接口等…

【Linux】—— git的管理以及使用

前言&#xff1a; 在上篇我们已经学习了关于调试器gdb的相关知识&#xff0c;本期我将为大家介绍的是关于版本控制工具——git的使用教程&#xff01;&#xff01;&#xff01; 目录 前言 &#xff08;一&#xff09;git的历史介绍 &#xff08;二&#xff09;github和gite…

Unity异步编程【6】——Unity中的UniTask如何取消指定的任务或所有的任务

今天儿童节&#xff0c;犬子已经9个多月了&#xff0c;今天是他的第一个儿童节。中年得子&#xff0c;其乐无穷&#xff08;音&#xff1a;ku bu kan yan&#xff09;…回头是岸啊 〇、 示例效果 一连创建5个异步任务[id 从0~4]&#xff0c;先停止其中的第id 4的任务&#x…

Flutter进阶篇-布局(Layout)原理

1、约束、尺寸、位置 overrideWidget build(BuildContext context) {return Scaffold(body: LayoutBuilder(builder: (context, constraints) {print("body约束:" constraints.toString());return Container(color: Colors.black,width: 300,height: 300,child: L…

【企业化架构部署】基于Nginx搭建LNMP架构

文章目录 一、安装 MySQL 数据库1. 安装Mysql环境依赖包2. 创建运行用户3. 编译安装4. 修改mysql 配置文件5. 更改mysql安装目录和配置文件的属主属组6. 设置路径环境变量7. 初始化数据库8. 添加mysqld系统服务9. 修改mysql 的登录密码10. 授权远程登录 二、编译安装 nginx 服务…

Maven 工具

Maven 工具 Maven简介Maven 基础概念创建 Maven项目依赖配置生命周期与插件分模块开发聚合和继承聚合继承聚合与继承的区别 属性版本管理多环境配置与应用私服 Maven简介 Maven 本质是一个项目管理工具&#xff0c;将项目开发和管理过程抽象成一个项目对象模型&#xff08;POM…

【爬虫】3.4爬取网站复杂数据

1. Web服务器网站 进一步把前面的Web网站的mysql.html, python.html, java.html丰富其中 的内容&#xff0c;并加上图形&#xff1a; mysql.html <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>my…

ICV报告: 智能座舱SoC全球市场规模预计2025年突破50亿美元

在智能化、互联化车辆需求不断增加的推动下&#xff0c;汽车行业正在经历一场范式转变。这一转变的前沿之一是智能座舱SoC。本市场研究报告对智能座舱SoC市场进行了全面的分析&#xff0c;包括其应用领域、当前状况和主要行业参与者。 智能座舱SoC指的是现代汽车智能座舱系统的…

Qt6.5.1+WebRTC学习笔记(十)开发环境搭建(win10+vs2022)

一、准备 1.操作系统win10 64位 2.合理的上网方式&#xff0c;需要正常访问google,最好有40G以上流量 3.安装VS2022&#xff0c;笔者使用的是社区版&#xff0c;并选中C相关&#xff0c;笔者设置如下 注意&#xff0c;win10的sdk需要是10.0.22621.0&#xff0c;其他版本可能…

吴恩达 ChatGPT Prompt Engineering for Developers 系列课程笔记--06 Transforming

06 Transforming 大语言模型&#xff08;LLM&#xff09;很擅于将输入转换为不同格式的输出&#xff0c;比如翻译、拼写校正或HTML格式转化。相比于复杂的正则表达式&#xff0c;Chat GPT实现更加准确和高效。 1) 不同语种的转换 下述语句实现了英文到西班牙语的翻译。 pro…

Windows IIS/docker+gunicorn两种方式部署django项目

写在最前 本篇文章并不涉及如何使用宝塔搭建django项目&#xff0c;仅适用于windows和docker部署&#xff0c;其中docker是运行在linux平台上的&#xff0c;如果您想在windows上运行docker&#xff0c;请自行搜索如何在windows上运行docker 一、Windows IIS部署 软件版本Win…

MySQL-Linux版安装

MySQL-Linux版安装 1、准备一台Linux服务器 云服务器或者虚拟机都可以&#xff1b; Linux的版本为 CentOS7&#xff1b; 2、 下载Linux版MySQL安装包 下载地址 3、上传MySQL安装包 使用FinalShell软件上传即可&#xff01; 4、 创建目录,并解压 mkdir mysqltar -xvf my…

【SpringCloud学习笔记】zuul网关

【SpringCloud学习笔记】 为什么需要网关zuul网关搭建zuul网关服务网关过滤器 为什么需要网关 微服务项目一般有多个服务&#xff0c;每个服务的地址都不同&#xff0c;客户端如果直接访问服务&#xff0c;无疑是增加客户端开发难度&#xff0c;项目小还好&#xff0c;如果项目…