zoukankan      html  css  js  c++  java
  • 数字时钟实现与动态可调与闹钟功能的实现

    设计的RTL结构

    处理模块实现模式切换与计数,4位数码管解码后 595control模块控制数码管的点闪动以及调时位的半秒闪动,595function模块16位串行输出给595驱动数码管显示

    module jishu
    (
    input clk,
    input rst_n,
    output [3:0] row_data,
    input [3:0] col_data,
    output alarm_beep,
    output[3:0]seg_flash_data,
    output Flag_1S,
    output [15:0]bcd_seg_display_num,
    input mode_in
    );
    wire [3:0]key_value;
    juzhen key_input
    (
    .clk(clk),
    .rst_n(rst_n),
    .col_data(col_data),
    .row_data(row_data),
    .key_value(key_value),
    .key_flag_r0(key_flag1),
    .key_flag(key_flag)
    );
    parameter T_half_S=12500000;
    parameter T_1S=25000000;

    reg [24:0]count1;
    reg Flag_1S_r;
    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin count1<=0; Flag_1S_r <= 0; end
    else if( count1 == T_half_S)
    begin
    count1 <= count1 + 1'b1;
    Flag_1S_r <=~ Flag_1S_r;
    end
    else if( count1 == T_1S)
    begin
    count1<=0;
    Flag_1S_r <=~ Flag_1S_r;
    end
    else
    count1 <= count1 + 1'b1;

    end
    assign Flag_1S = Flag_1S_r;
    wire key_in;
    debounce xiaodou

    (
    .clk(clk),
    .rst_n(rst_n),
    .key_n(mode_in),
    .key_pulse (key_in)
    );


    reg [3:0]bcd_sec_one_cnt;
    reg [3:0]bcd_min_one_cnt;
    reg [3:0]bcd_hour_one_cnt;
    reg [3:0]bcd_sec_ten_cnt;
    reg [3:0]bcd_min_ten_cnt;
    reg [3:0]bcd_hour_ten_cnt;
    reg[3:0] seg_flash_data_r;
    wire [15:0] bcd_seg_display_num;
    reg[2:0] mode;
    reg [15:0] bcd_seg_display_num_r;


    always @(posedge clk or negedge rst_n)
    begin
    if(!rst_n) begin mode<=0;end
    else
    begin if(key_in==1) if(mode == 3'b110) mode <= 3'b000;
    else mode <= mode + 1'b1;
    end
    end

    always @(posedge clk or negedge rst_n)
    if(!rst_n) begin bcd_sec_one_cnt<=0;bcd_sec_ten_cnt<=0;bcd_min_one_cnt<=0;bcd_min_ten_cnt<=0;bcd_hour_one_cnt<=0;bcd_hour_ten_cnt<=0;seg_flash_data_r<=4'b0000;end
    else
    begin
    case(mode)
    0: begin seg_flash_data_r<=4'b0000;
    bcd_seg_display_num_r[15:0] <= {bcd_min_ten_cnt,bcd_min_one_cnt,bcd_sec_ten_cnt,bcd_sec_one_cnt};
    if(count1 == T_1S)begin if(bcd_sec_one_cnt==9)
    begin bcd_sec_one_cnt<=0; if(bcd_sec_ten_cnt==5)
    begin bcd_sec_ten_cnt<=0;if(bcd_min_one_cnt==9)
    begin bcd_min_one_cnt<=0;if(bcd_min_ten_cnt==5)
    begin bcd_min_ten_cnt<=0;if(bcd_hour_ten_cnt==2&&bcd_hour_one_cnt==3)begin bcd_hour_ten_cnt<=0;bcd_hour_one_cnt<=0;end
    else if(bcd_hour_one_cnt==9)begin bcd_hour_one_cnt<=0;bcd_hour_ten_cnt<=bcd_hour_ten_cnt+1;end

    else bcd_hour_one_cnt<=bcd_hour_one_cnt+1;
    end
    else bcd_min_ten_cnt<=bcd_min_ten_cnt+1;end
    else bcd_min_one_cnt<=bcd_min_one_cnt+1;end
    else bcd_sec_ten_cnt<=bcd_sec_ten_cnt+1;end
    else bcd_sec_one_cnt<=bcd_sec_one_cnt+1;end end
    /* 1: begin seg_flash_data_r <= 4'b0001;
    if(key_value==6&key_flag==1)seg_flash_data_r[3:0] <= {seg_flash_data_r[2:0],seg_flash_data_r[3]}; //左移要调整的位
    if(key_value==14&key_flag==1)seg_flash_data_r[3:0] <= {seg_flash_data_r[0],seg_flash_data_r[3:1]};//右移要调整的位
    bcd_seg_display_num_r[15:0] <= {bcd_min_ten_cnt,bcd_min_one_cnt,bcd_sec_ten_cnt,bcd_sec_one_cnt}; //秒分调整显示界面
    if(seg_flash_data_r[0]==1&key_value==13&key_flag==1)begin if(bcd_sec_one_cnt==9)bcd_sec_one_cnt<=0; else bcd_sec_one_cnt<=bcd_sec_one_cnt+1;end
    if(seg_flash_data_r[1]==1&key_value==12&key_flag==1)begin if(bcd_sec_ten_cnt==5)bcd_sec_ten_cnt<=0;else bcd_sec_ten_cnt<=bcd_sec_ten_cnt+1;end
    if(seg_flash_data_r[2]==1&key_value==9&key_flag==1)begin if(bcd_min_one_cnt==9)bcd_min_one_cnt<=0;else bcd_min_one_cnt<=bcd_min_one_cnt+1;end
    if(seg_flash_data_r[3]==1&key_value==8&key_flag==1)begin if(bcd_min_ten_cnt==5)bcd_min_ten_cnt<=0;else bcd_min_ten_cnt<=bcd_min_ten_cnt+1;end end

    2:begin bcd_seg_display_num_r[15:0] <= {bcd_hour_ten_cnt,bcd_hour_one_cnt,bcd_min_ten_cnt,bcd_min_one_cnt}; seg_flash_data_r<=4'b0000;end



    3:begin seg_flash_data_r<=4'b0001;
    if(key_value==6&key_flag==1)seg_flash_data_r[3:0] <= {seg_flash_data_r[2:0],seg_flash_data_r[3]};
    if(key_value==14&key_flag==1)seg_flash_data_r[3:0] <= {seg_flash_data_r[0],seg_flash_data_r[3:1]};
    bcd_seg_display_num_r[15:0] <= {bcd_hour_ten_cnt,bcd_hour_one_cnt,bcd_min_ten_cnt,bcd_min_one_cnt};
    if(seg_flash_data_r[0]==1&key_value==13&key_flag==1)begin if(bcd_min_one_cnt==9)bcd_sec_one_cnt<=0; else bcd_sec_one_cnt<=bcd_sec_one_cnt+1;end
    if(seg_flash_data_r[1]==1&key_value==12&key_flag==1)begin if(bcd_min_ten_cnt==5)bcd_sec_ten_cnt<=0;else bcd_sec_ten_cnt<=bcd_sec_ten_cnt+1;end
    if(seg_flash_data_r[2]==1&key_value==5&key_flag==1)begin if(bcd_hour_one_cnt==9)bcd_hour_one_cnt<=0;else bcd_hour_one_cnt<=bcd_hour_one_cnt+1;end
    if(seg_flash_data_r[3]==1&key_value==4&key_flag==1)begin if(bcd_hour_ten_cnt==2)bcd_hour_ten_cnt<=0;else bcd_hour_ten_cnt<=bcd_hour_ten_cnt+1;end end*/











    1 :begin seg_flash_data_r<=4'b1000;
    bcd_seg_display_num_r[15:0] <= {bcd_hour_ten_cnt,bcd_hour_one_cnt,bcd_min_ten_cnt,bcd_min_one_cnt};
    if(key_value==4&key_flag==1)begin if(bcd_hour_ten_cnt==2)bcd_hour_ten_cnt<=0;else bcd_hour_ten_cnt<=bcd_hour_ten_cnt+1;end end


    2: begin
    seg_flash_data_r<=4'b0100;
    bcd_seg_display_num_r[15:0] <= {bcd_hour_ten_cnt,bcd_hour_one_cnt,bcd_min_ten_cnt,bcd_min_one_cnt};
    if(key_value==5&key_flag==1)begin if(bcd_hour_one_cnt==9)bcd_hour_one_cnt<=0;else bcd_hour_one_cnt<=bcd_hour_one_cnt+1;end end

    3: begin
    seg_flash_data_r<=4'b0010;
    bcd_seg_display_num_r[15:0] <= {bcd_hour_ten_cnt,bcd_hour_one_cnt,bcd_min_ten_cnt,bcd_min_one_cnt};
    if(key_value==8&key_flag==1)begin if(bcd_min_ten_cnt==5)bcd_min_ten_cnt<=0;else bcd_min_ten_cnt<=bcd_min_ten_cnt+1;end end

    4: begin
    seg_flash_data_r<=4'b0001;
    bcd_seg_display_num_r[15:0] <= {bcd_hour_ten_cnt,bcd_hour_one_cnt,bcd_min_ten_cnt,bcd_min_one_cnt};
    if(key_value==9&key_flag==1)begin if(bcd_min_one_cnt==9)bcd_min_one_cnt<=0;else bcd_min_one_cnt<=bcd_min_one_cnt+1;end end


    5:begin
    seg_flash_data_r<=4'b0010;
    bcd_seg_display_num_r[15:0] <= {bcd_min_ten_cnt,bcd_min_one_cnt,bcd_sec_ten_cnt,bcd_sec_one_cnt};
    if(key_value==12&key_flag==1)begin if(bcd_sec_ten_cnt==5)bcd_sec_ten_cnt<=0;else bcd_sec_ten_cnt<=bcd_sec_ten_cnt+1;end end


    6:begin
    seg_flash_data_r<=4'b0001;
    bcd_seg_display_num_r[15:0] <= {bcd_min_ten_cnt,bcd_min_one_cnt,bcd_sec_ten_cnt,bcd_sec_one_cnt};
    if(key_value==13&key_flag==1)begin if(bcd_sec_one_cnt==9)bcd_sec_one_cnt<=0; else bcd_sec_one_cnt<=bcd_sec_one_cnt+1;end end
    //default:begin bcd_sec_one_cnt<=0;bcd_sec_ten_cnt<=0;bcd_min_one_cnt<=0;bcd_min_ten_cnt<=0;bcd_hour_one_cnt<=0;bcd_hour_ten_cnt<=0;end
    endcase
    end
    assign seg_flash_data[3:0] = Flag_1S_r ?seg_flash_data_r[3:0]:4'b0000;
    assign bcd_seg_display_num[15:0] = bcd_seg_display_num_r[15:0];

    wire alarm =(bcd_hour_ten_cnt==1&&bcd_hour_one_cnt==2&&bcd_min_ten_cnt==0&&bcd_min_one_cnt==0&&bcd_sec_ten_cnt==0&&bcd_sec_one_cnt==0);

    reg [26:0]beep_count;

    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    beep_count <= 0;
    end
    else if(alarm)
    beep_count <= 27'd125000000;
    else if(beep_count>0)
    beep_count <= beep_count - 1;

    end

    assign alarm_beep = (beep_count>0 && ((beep_count[24]&& beep_count[14])||(~beep_count[24]&& beep_count[13])));
    endmodule

    显示控制模块

    module seg595_control_module(clk,rst_n,num1_ten_smg_data,num1_one_smg_data,num2_ten_smg_data,num2_one_smg_data,seg_flash_data,duan_wei_data,Flag_1S,start_sig,done_sig);
    input clk;
    input rst_n;
    input [7:0] num1_ten_smg_data;
    input [7:0] num1_one_smg_data;
    input [7:0] num2_ten_smg_data;
    input [7:0] num2_one_smg_data;
    input [3:0] seg_flash_data;
    output [15:0]duan_wei_data;
    output start_sig;
    input done_sig;
    input Flag_1S;

    parameter T_1S=25000000;
    //parameter T_1S=2500;


    reg [15:0]duan_wei_data_r;
    reg start_sig_r;
    reg [3:0]state;

    always@(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    state<=0;
    start_sig_r <= 1'b0;
    end
    else

    case (state)
    0:
    begin duan_wei_data_r[15:0] <= {num2_one_smg_data,8'h27}; state <= state + 1; start_sig_r <= 1'b1; end

    1:
    begin start_sig_r <= 1'b0; state<=4; end

    2:
    if(done_sig) begin duan_wei_data_r[15:0] <= {(seg_flash_data[3]?8'h00:num2_ten_smg_data),Flag_1S?8'h1e:8'h2e}; state <= state + 1; start_sig_r <= 1'b1; end//{num2_ten_smg_data,4'h2,(4'he&seg_flash_data)}; state <= state + 1; start_sig_r <= 1'b1; end

    3:
    begin start_sig_r <= 1'b0; state <= state + 1; end

    4:
    if(done_sig) begin duan_wei_data_r[15:0] <= {(seg_flash_data[2]?8'h00:num2_one_smg_data),Flag_1S?8'h1d:8'h2d};state <= state + 1; start_sig_r <= 1'b1; end//{num2_one_smg_data,4'h2,(4'hd&seg_flash_data)};state <= state + 1; start_sig_r <= 1'b1; end

    5:
    begin start_sig_r <= 1'b0; state <= state + 1; end

    6:
    if(done_sig) begin duan_wei_data_r[15:0] <= {(seg_flash_data[1]?8'h00:num1_ten_smg_data),Flag_1S?8'h1b:8'h
    b}; state <= state + 1; start_sig_r <= 1'b1; end//{num1_ten_smg_data,4'h2,(4'hb&seg_flash_data)}; state <= state + 1; start_sig_r <= 1'b1; end

    7:
    begin start_sig_r <= 1'b0; state <= state + 1; end

    8:
    if(done_sig) begin duan_wei_data_r[15:0] <= {(seg_flash_data[0]?8'h00:num1_one_smg_data),Flag_1S?8'h17:8'h27}; state <= state + 1; start_sig_r <= 1'b1; end//{num1_one_smg_data,4'h2,(4'h7&seg_flash_data)}; state <= state + 1; start_sig_r <= 1'b1; end

    9:
    begin start_sig_r <= 1'b0; state<=2; end

    default:
    begin state <= 0; start_sig_r <= 1'b0; end
    endcase
    end

    assign start_sig = start_sig_r;
    assign duan_wei_data = duan_wei_data_r;
    endmodule


    显示模块

    module seg595_function_module(clk,rst_n,duan_wei_data,start_sig,done_sig,sck,rck,dout);
    input clk;
    input rst_n;
    input [15:0]duan_wei_data;
    input start_sig;
    output done_sig;
    output sck;
    output rck;
    output dout;


    //分出5M频率

    reg [2:0]count1;
    reg sck_r;

    always @(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin count1<=0; sck_r<=0; end
    else if(count1 == 3'd4)
    begin count1<=0; sck_r = ~ sck_r; end
    else count1 <= count1 +1 ;
    end




    //整出下降沿脉冲
    reg sck_flag1;
    reg sck_flag2;
    always @(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    sck_flag1 <= 1'b1;
    sck_flag2 <= 1'b1;
    end
    else
    begin
    sck_flag1 <= sck_r;
    sck_flag2 <= sck_flag1;
    end
    end

    wire sck_negedge;

    assign sck_negedge= (sck_flag2 && ~sck_flag1)?1'b1:1'b0;


    reg [6:0]state;
    reg rck_r;
    reg dout_r;
    reg done_sig_r;

    // 每一个sck,下降沿放入数据,上升沿到,输入输出。 rck 每16个sck拉高一次。


    always @(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    begin
    dout_r <= 0;
    state <= 0;
    done_sig_r <= 1'b0;
    end
    else
    case (state)
    0: if(start_sig) state <= state + 1;
    1: if(sck_negedge)begin dout_r <= duan_wei_data[15]; rck_r <= 1'b1; state <= state + 1; end
    2: if(sck_negedge)begin dout_r <= duan_wei_data[14]; state <= state + 1; end
    3: if(sck_negedge)begin dout_r <= duan_wei_data[13]; state <= state + 1; end
    4: if(sck_negedge)begin dout_r <= duan_wei_data[12]; state <= state + 1; end
    5: if(sck_negedge)begin dout_r <= duan_wei_data[11]; state <= state + 1; end
    6: if(sck_negedge)begin dout_r <= duan_wei_data[10]; state <= state + 1; end
    7: if(sck_negedge)begin dout_r <= duan_wei_data[9]; state <= state + 1; end
    8: if(sck_negedge)begin dout_r <= duan_wei_data[8]; state <= state + 1; end
    9: if(sck_negedge)begin dout_r <= duan_wei_data[7]; state <= state + 1; end
    10: if(sck_negedge)begin dout_r <= duan_wei_data[6]; state <= state + 1; end
    11: if(sck_negedge)begin dout_r <= duan_wei_data[5]; state <= state + 1; end
    12: if(sck_negedge)begin dout_r <= duan_wei_data[4]; state <= state + 1; end
    13: if(sck_negedge)begin dout_r <= duan_wei_data[3]; state <= state + 1; end
    14: if(sck_negedge)begin dout_r <= duan_wei_data[2]; state <= state + 1; end
    15: if(sck_negedge)begin dout_r <= duan_wei_data[1]; state <= state + 1; end
    16: if(sck_negedge)begin dout_r <= duan_wei_data[0]; rck_r <= 1'b0; state <= state + 1; done_sig_r <= 1'b1; end
    17: begin done_sig_r <= 1'b0; state <= 0; end

    default: begin dout_r <= 0; state <= 0; done_sig_r <= 1'b0; end
    endcase
    end

    assign done_sig = done_sig_r;
    assign dout = dout_r;
    assign rck = rck_r;
    assign sck = sck_r;


    endmodule

    数码管解码模块

    module smg_encoder_module(clk,rst_n,num,smg_data);

    input clk;
    input rst_n;
    input [3:0]num;
    output [7:0]smg_data;

    /*共阴极数码管: 位选为低电平(即0)选中数码管; 各段选为高电平(即1接+5V时)选中各数码段;*/

    //由0到f的编码为


    parameter
    SEG_NUM0=8'h3f,

    SEG_NUM1=8'h06,

    SEG_NUM2=8'h5b,

    SEG_NUM3=8'h4f,

    SEG_NUM4=8'h66,

    SEG_NUM5=8'h6d,

    SEG_NUM6=8'h7d,

    SEG_NUM7=8'h07,

    SEG_NUM8=8'h7f,

    SEG_NUM9=8'h6f,

    SEG_NUMA=8'h77,

    SEG_NUMB=8'h7c,

    SEG_NUMC=8'h39,

    SEG_NUMD=8'h5e,

    SEG_NUME=8'h79,

    SEG_NUMF=8'h71;

    reg [7:0]smg_data_r;

    always @(posedge clk or negedge rst_n)
    begin
    if(!rst_n)
    smg_data_r <= 8'b00000000;
    else
    case (num)
    4'd0: smg_data_r <= SEG_NUM0;
    4'd1: smg_data_r <= SEG_NUM1;
    4'd2: smg_data_r <= SEG_NUM2;
    4'd3: smg_data_r <= SEG_NUM3;
    4'd4: smg_data_r <= SEG_NUM4;
    4'd5: smg_data_r <= SEG_NUM5;
    4'd6: smg_data_r <= SEG_NUM6;
    4'd7: smg_data_r <= SEG_NUM7;
    4'd8: smg_data_r <= SEG_NUM8;
    4'd9: smg_data_r <= SEG_NUM9;

    default: smg_data_r <= 8'b00000000;
    endcase
    end



    assign smg_data=smg_data_r;

    endmodule

  • 相关阅读:
    远程GIt仓库地址改了,如何在本地修改
    Vue中使用element-ui中的el-table时修改列的字体颜色
    vue子组件给父组件传值
    百度、高德、谷歌、火星、wgs84(2000)地图坐标相互转换的JS实现
    Canvas画图的基本命令与操作
    MySQL 索引的面试题总结
    面试官:Redis监控指标有哪些?
    ansible笔记(1):ansible的基本概念
    Nginx的超时timeout配置详解
    Etcd+Confd实现配置文件动态更新
  • 原文地址:https://www.cnblogs.com/xinshuwei/p/5647974.html
Copyright © 2011-2022 走看看