verilog实现简易24小时计数器


1.顶层数码管显示模块

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    18:57:45 08/18/2019 
// Design Name: 
// Module Name:    dynamic_seg_top 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: //实现简易时钟计数功能
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
module dynamc_seg_top
//---------------------<端口声明>---------------------------------------
(
    input                           clk_50MHZ            , //时钟,50Mhz
    input                           rst_n                , //复位,低电平有效
    output reg     [ 7:0]           seg_sel              , //数码管位选
    output reg     [ 7:0]           seg_data           //数码管段选,即内容显示
);

//---------------------<信号定义>---------------------------------------
wire                             clk_1KHZ           ;
reg            [3:0]                 data_tmp           ;
reg            [7:0]                 cnt                ;
wire            [23:0]                        data                            ;
    
//----------------------------------------------------------------------
//   1k分频例化,扫描一个数码管时间为1ms
//----------------------------------------------------------------------
CLK_DIV #
    (
        .width(16),
        .cnt(50_000)
    )
    uut(
        .clk_50MHZ(clk_50MHZ),
        .rst_n(rst_n),
        .clk_out(clk_1KHZ)
  );

//======================================================================
//
//时,分,秒计数例化
//
//======================================================================
    clock_cnt 
    clk_cnt_uut(
        .clk_50MHZ(clk_50MHZ), 
        .rst_n(rst_n), 
        .data(data)
   );
//----------------------------------------------------------------------
//   数码管扫描,8位循环扫描,频率为1k
//----------------------------------------------------------------------
always @(posedge clk_1KHZ or negedge rst_n)
    begin
    if(!rst_n)
        seg_sel <= 8'b0111_1111;
    else if(seg_sel==8'b1111_1110)
        seg_sel <= 8'b0111_1111;
    else
        seg_sel <= ~(~seg_sel>>1);
    end

//----------------------------------------------------------------------
//     位选,不同计数对应不同位选编码,也对应分割的不同数据
//----------------------------------------------------------------------
always @(*)
    begin
    case(seg_sel)
        8'b0111_1111: data_tmp = data[ 3: 0]         ; // 位1
        8'b1011_1111: data_tmp = data[ 7: 4]            ; // 位2
        8'b1101_1111: data_tmp = 4'ha                     ; // 位3
        8'b1110_1111: data_tmp = data[11:8]             ; // 位4
        8'b1111_0111: data_tmp = data[15:12]         ; // 位5
        8'b1111_1011: data_tmp = 4'hb                     ; // 位6
        8'b1111_1101: data_tmp = data[19:16]         ; // 位7
        8'b1111_1110: data_tmp = data[23:20]         ; // 位8
        default:       data_tmp = 4'b0000             ;
    endcase
    end

//----------------------------------------------------------------------
//     段选,将不同分割数据进行段选编码,实验平台为2个4位一体共阳数码管
//----------------------------------------------------------------------
always @(*)
    begin
    case(data_tmp)
        4'h0:   seg_data = 9'hc0;
        4'h1:   seg_data = 9'hf9;
        4'h2:   seg_data = 9'ha4;
        4'h3:   seg_data = 9'hb0;
        4'h4:   seg_data = 9'h99;
        4'h5:   seg_data = 9'h92;
        4'h6:   seg_data = 9'h82;
        4'h7:   seg_data = 9'hf8;
        4'h8:   seg_data = 9'h80;
        4'h9:   seg_data = 9'h90;
           4'ha:   seg_data = 9'hbf;//
           4'hb:   seg_data = 9'hbf;//第三位和第六位显示时钟的分隔线
        default:seg_data = 9'hc0;
    endcase
    end

endmodule

2.时分秒计数模块

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    19:51:36 02/25/2020 
// Design Name: 
// Module Name:    clock_cnt 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module clock_cnt
    (
        input clk_50MHZ,
        input rst_n,
        output  [23:0]data
   );

reg [7:0] second    ;//时钟“秒”
reg [7:0] minute    ;//时钟“分”
reg [7:0] hour        ;//时钟“小时”
wire clk_1HZ            ;
//----------------------------------------------------------------------
//--   例化计数分频产生1HZ时钟
//----------------------------------------------------------------------

CLK_DIV #
    (
        .width(28),
        .cnt(50_000_000)
    )
    uut(
        .clk_50MHZ(clk_50MHZ),
        .rst_n(rst_n),
        .clk_out(clk_1HZ)
  );

//----------------------------------------------------------------------
//--   秒计数,从0-59计数,1秒加一,到59清零
//----------------------------------------------------------------------
always @(posedge clk_1HZ or negedge rst_n)
           begin
               if(!rst_n)
                    second<=8'd0;
               else if (second[3:0]==4'd9)
                    begin
                        second[3:0]<=8'd0;
                        if(second[7:4]==4'd5)
                            second[7:4]<=4'd0;
                        else
                            second[7:4]<=second[7:4]+4'd1;
                    end
                else
                    second[3:0]<=second[3:0]+4'd1;
           end 

//----------------------------------------------------------------------
//--   分计数,从0-59计数,1分钟加一,到59清零
//----------------------------------------------------------------------
always @(posedge clk_1HZ or negedge rst_n)
           begin
               if(!rst_n)
                    minute<=8'd0;
               else if ((second[3:0]==4'd9)&(second[7:4]==4'd5))
                    begin
                        if(minute[3:0]==4'd9)
                            begin
                                minute[3:0] <=4'd0;
                                if(minute[7:4]==4'd5)
                                    minute[7:4] <=4'd0;
                                else
                                    minute[7:4] <=minute[7:4]+4'd1;
                            end
                        else
                            begin
                                minute[3:0]<=minute[3:0]+4'd1;
                            end
                    end
                else
                    minute<=minute;
           end 
        
//----------------------------------------------------------------------
//--   小时计数,从0-23计数,1小时加一,到23清零
//----------------------------------------------------------------------
always @(posedge clk_1HZ or negedge rst_n)
           begin
               if(!rst_n)
                        hour<=8'd0;
               else if ((second[3:0]==4'd9)&(second[7:4]==4'd5)&(minute[3:0]==4'd9)&(minute[7:4]==4'd5))
                    begin
                        if(hour[7:4]==4'd2)
                            begin
                                if(hour[3:0]==4'd3)
                                    begin
                                        hour[3:0] <=4'd0;
                                        hour[7:4]<=4'd0;
                                    end
                                else
                                    begin
                                        hour[7:4]<=hour[7:4];
                                        hour[3:0] <=hour[3:0]+4'd1;
                                    end
                            end
                        else 
                            begin
                                if(hour[3:0]==4'd9)
                                    begin
                                        hour[3:0] <=4'd0;
                                        hour[7:4] <=hour[7:4]+4'd1;
                                    end
                                else
                                    begin
                                        hour[3:0] <=hour[3:0]+4'd1;
                                        hour[7:4]    <=hour[7:4];
                                    end
                            end
                    end
                else
                    hour<=hour;
           end 
        
    assign data[3:0]        =second    [3:0];//将“秒”的个位数送到数码管第一位
    assign data[7:4]        =second    [7:4];//将“秒”的十位数送到数码管第二位
    assign data[11:8]        =minute    [3:0];//将“分“的个位数送到数码管第四位
    assign data[15:12]    =minute    [7:4];//将”分”的十位数送到数码管第五位
    assign data[19:16]    =hour    [3:0];//将“时“的个位数送到数码管第七位
    assign data[23:20]    =hour    [7:4];//将”时”的个位数送到数码管第八位
                
endmodule

3.任意时钟分频模块

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    18:54:40 02/25/2020 
// Design Name: 
// Module Name:    CLK_DIV 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: //任意时钟分频模块
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
module CLK_DIV #
    (
        parameter  width  = 28,
        parameter  cnt    = 50_000_000
    )
    (
        input      clk_50MHZ,
        input      rst_n        ,
        output     clk_out
    );
     
     reg           [width-1:0]  cnt_p;
     reg             cnt_n;
     reg             clk_p;
     reg          clk_n;
     
     //上升沿计数器,实现0-49_999_999计数
     always@(posedge clk_50MHZ or negedge rst_n)
                begin
                    if(!rst_n)                 
                    cnt_p <= 1'b0;            
                    else if(cnt_p == (cnt-1))    
                    cnt_p <= 1'b0;            
                    else                        
                    cnt_p <= cnt_p + 1'b1;   
                end 
                
     //上升沿触发时钟分频,实现1HZ时钟输出
     always@(posedge clk_50MHZ or negedge rst_n)
          begin
                    if(!rst_n)                        
                    clk_p<=1'b0;            
                    else if(cnt_p<(cnt>>1)) 
                    clk_p<=1'b0;              
                    else                    
                    clk_p<=1'b1;              
                end
                
     always@(negedge clk_50MHZ or negedge rst_n)
                begin
                    if(!rst_n)                 
                    cnt_n <= 1'b0;            
                    else if(cnt_n == (cnt-1))    
                    cnt_n <= 1'b0;            
                    else                        
                    cnt_n <= cnt_n + 1'b1;   
                end             
                
     always@(negedge clk_50MHZ or negedge rst_n)
          begin
                    if(!rst_n)                        
                    clk_n<=1'b0;            
                    else if(cnt_n<(cnt>>1)) 
                    clk_n<=1'b0;              
                    else                    
                    clk_n<=1'b1;              
                end
                
        wire clk1=clk_50MHZ;  //当分频系数为1时,输出时钟
        wire clk2=clk_p;      //当分频系数为偶数时,输出等于clk_p
        wire clk3=clk_p&clk_n;//当分频系数为奇数时,输出等于clk_p&clk_n
        
        assign clk_out=(cnt==1)?clk1:(cnt[0]? clk2:clk3);
                
                
                
                    


endmodule

 

4.时分秒仿真testbench文件

`timescale 100ps / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   22:18:22 02/25/2020
// Design Name:   clock_cnt
// Module Name:   C:/mydesign/dybamic_seg1/clk_tb.v
// Project Name:  dybamic_seg
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: clock_cnt
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module clk_tb;

    // Inputs
    reg clk_50MHZ;
    reg rst_n;

    // Outputs
    wire [23:0] data;

    // Instantiate the Unit Under Test (UUT)
    clock_cnt uut (
        .clk_50MHZ(clk_50MHZ), 
        .rst_n(rst_n), 
        .data(data)
    );

    initial begin
        // Initialize Inputs
        clk_50MHZ = 0;
        rst_n = 0;

        // Wait 100 ns for global reset to finish
        #10;
     rst_n = 1; 
        #10;     
        // Add stimulus here

    end
    always #1 clk_50MHZ=~clk_50MHZ;
      
endmodule

5.显示模块仿真testbench文件

`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer:
//
// Create Date:   15:11:16 02/26/2020
// Design Name:   dynamc_seg_top
// Module Name:   C:/mydesign/dybamic_seg1/dy_segtb.v
// Project Name:  dybamic_seg
// Target Device:  
// Tool versions:  
// Description: 
//
// Verilog Test Fixture created by ISE for module: dynamc_seg_top
//
// Dependencies:
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
////////////////////////////////////////////////////////////////////////////////

module dy_segtb;

    // Inputs
    reg clk_50MHZ;
    reg rst_n;

    // Outputs
    wire [7:0] seg_sel;
    wire [7:0] seg_data;

    // Instantiate the Unit Under Test (UUT)
    dynamc_seg_top uut (
        .clk_50MHZ(clk_50MHZ), 
        .rst_n(rst_n), 
        .seg_sel(seg_sel), 
        .seg_data(seg_data)
    );

    initial begin
        // Initialize Inputs
        clk_50MHZ = 0;
        rst_n = 0;

        // Wait 100 ns for global reset to finish
        #10;
        rst_n = 1;
     #10;  
        // Add stimulus here

    end
    always #1 clk_50MHZ=~clk_50MHZ;
      
endmodule

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM