当前位置:   article > 正文

用Verilog实现数字钟

用Verilog实现数字钟

实验基本指导书内容

实验目的与要求

  1. 实验目的:进一步掌握用VerilogHDL 语言编写任意进制计数器的方法,通过本次实验要充分认识到,顶层结构的设计和优化在综合设计中的重要性。
  2. 实验要求:利用前面实验所学知识,设计一数字钟并在GW48 实验箱上实现。具体要求如下:
    1. 计时可选十二进制计时和二十四进制计时;
    2. 可手动校时,能分别进行时、分的校正;
    3. 带闹钟功能,当计时计到闹铃时间时,发光二极管点亮,闹铃时间为1分,可用按键提前终止闹铃;
    4. 带秒表功能;(选做)
    3. 带日历显示,可显示月、日等。(选做)

实验基本原理与功能

基本原理:数字钟秒到分、分到时均为60进制,利用VerilogHDL编写模60的计数器,秒模块的CLK可从实验板上取得,秒模块的本身输出用来驱动显示秒的数码管,进位输出恰好是分模块的CLK。分模块的进位作为时模块的CLK。时模块为24进制。
需要调整时间时,可以用数据选择器将正常的各个模块时钟切断取而代之的是由实验箱上的按键产生的单脉冲,从而实现调整时间的功能。
闹铃时间与当前时间要共用数码管的方式显示,同样我们可以采用多位数据选择器来实现。
闹铃实现可采用比较计时模块输出与闹钟设定输出完全相等时,输出控制信号使扬声器发声。

实验主要技术指标

1、能够用数码管显示当前时间的时、分、秒。(时采用24小时制)
2、能够通过按键调整时钟的时、分。
3、能够设定闹铃时间。闹铃时间到,有声音提示。
4、铃时间与当前时间要共用数码管的方式显示,并能用按键来切换。

设计步骤

1、根据题目要求,参考GW48使用说明书,选取适当的模式来实现。
2、依据题目要求功能,设计顶层总体结构图。
3、使用VerilogHDL 语言来实现顶层结构中各个模块的功能,并创建顶层文件可调用的图形元件,如:24、60进制计数器,数据选择器等模块。
4、创建顶层GDF文档,并将各模块连接。
5、根据题目要求,以及第一步所选模式,并查表,定义引脚。
6、编译并下载到目标芯片中。
7、利用实验箱验证所设计的数字钟功能。

实验报告要求

1、写出实验目的及要求。
2、写出设计步骤,画出设计的顶层结构图。写出硬件测试的引脚锁定情况。
3、列出各个模块的程序清单及仿真波形并进行分析说明。
4、写出设计体会及心得。

各模块代码

24进制计数器

module counter_24(CLK,DOUT,COUT);
input CLK;
output COUT;
output[4:0] DOUT;
reg[4:0] Q;
reg COUT;
assign DOUT = Q;
always@ (posedge CLK)
    begin
        if (Q < 5'd23) begin Q <= Q + 1; COUT <= 1'b0; end
        else begin Q <= 5'b0; COUT <= 1'b1; end
    end
endmodule

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

60进制计数器

module counter_60(CLK,DOUT,COUT);
input CLK;
output COUT;
output[5:0] DOUT;
reg[5:0] Q;
reg COUT;
assign DOUT = Q;
always@ (posedge CLK)
    begin
        if (Q < 6'd59) begin Q <= Q + 1; COUT <= 1'b0; end
        else begin Q <= 6'b0; COUT <= 1'b1; end
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

状态调节

module STATUS(mode,select,set,mode_cnt,select_cnt,set_hour,set_min,set_ahour,set_amin,clk_10hz);
    input clk_10hz;
    input mode,select,set;
    output mode_cnt,set_hour,set_min,set_ahour,set_amin;
    output reg [3:0] select_cnt;
    reg mode_cnt;
    //模式选择
    always@(posedge mode)
        mode_cnt = mode_cnt + 1;
    always@(posedge select,posedge mode)
        if(mode) select_cnt = 0;
        else if(select_cnt < 2) select_cnt=select_cnt + 1;
        else select_cnt=1;
    //长按与短按
    reg[15:0] cnt;
    reg rapid;
    always@(posedge clk_10hz) 
    begin
        if(set) cnt=cnt+1;
        else cnt=0;
        if(cnt>9)rapid=1;
        else rapid=0;
    end
    //控制子模式
    assign set_hour=(mode_cnt==0)&(select_cnt==1)&((!rapid&set)|(rapid&clk_10hz));
    assign set_min=(mode_cnt==0)&(select_cnt==2)&((!rapid&set)|(rapid&clk_10hz));
    assign set_ahour=(mode_cnt==1)&(select_cnt==1)&((!rapid&set)|(rapid&clk_10hz));
    assign set_amin=(mode_cnt==1)&(select_cnt==2)&((!rapid&set)|(rapid&clk_10hz));
endmodule 

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

蜂鸣器

module speak(hour,min,sec,ahour,amin,set,clk_1khz,clk_4hz,clk_1hz,speak);
    input set,clk_1khz,clk_4hz,clk_1hz;     
    input [4:0]hour;
    input [5:0]min,sec;
    input [4:0]ahour;
    input [5:0]amin;
    output speak;
    reg pusle,tellingtime;
    reg [1:0]cnt;
    always@(posedge clk_4hz)begin
        cnt=cnt+1;
        if(cnt==2'b10)pusle=1;
        else pusle=0;
    end
    always@(*)begin 
        if(min==5'd59&&sec>5'd55)
        tellingtime = pusle;  
        else if(min==0&&sec==0&&sec<4)
        tellingtime = 1;
        else tellingtime = 0;
    end 
    assign speak1=tellingtime?clk_1khz:0;
    assign speak2=(hour==ahour)&&(min==amin)&&(!set)&&(clk_1khz&clk_1hz);
    assign speak=speak1||speak2;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

显示驱动

module PRTCTRL(AT,APM,IN_H,IN_M,IN_S,IN_AH,IN_AM,AM,PM,PRT_H,PRT_M,PRT_S);
    input APM,AT;
    output reg AM,PM;
    input [4:0] IN_H;
    input [5:0] IN_M,IN_S;
    input [4:0] IN_AH;
    input [5:0] IN_AM;
    output reg [7:0] PRT_H,PRT_M,PRT_S;
    reg APMS;
    always@(posedge APM) APMS = ~APMS;
    always @(*) begin
        PRT_H[7:4] <= AT?IN_AH / 6'd10:IN_H / 6'd10;
        PRT_H[3:0] <= AT?IN_AH % 6'd10:IN_H % 6'd10;
        if (APMS) begin
            if(AT?IN_AH>4'd12:IN_H>4'd12)begin
                PRT_H[7:4] <= AT?(IN_AH - 4'd12) / 6'd10:(IN_H - 4'd12) / 6'd10;
                PRT_H[3:0] <= AT?(IN_AH - 4'd12) % 6'd10:(IN_H - 4'd12) % 6'd10;end
            PM <= AT?IN_AH>4'd12:IN_H>4'd12;
            AM <=~PM;end
        else begin
            AM = 0;PM = 0;end
        PRT_M[7:4] <= AT?IN_AM / 6'd10:IN_M / 6'd10;
        PRT_M[3:0] <= AT?IN_AM % 6'd10:IN_M % 6'd10;
        PRT_S[7:4] <= AT?'b0:IN_S / 6'd10;
        PRT_S[3:0] <= AT?'b0:IN_S % 6'd10;
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

分频器

module TIMEDIV(CLK_1K,CLK_1,CLK_4,CLK_10);
    input CLK_1K;
    output reg CLK_1,CLK_4,CLK_10;
    reg [9:0] T;
    always@(posedge CLK_1K)begin
        T = T + 'd1;
        CLK_10 =(T % 'd100 == 0)? ~CLK_10 :CLK_10;//100
        CLK_4 =(T % 'd250 == 0)? ~CLK_4 :CLK_4;//250
        if (T % 'd1000 == 0)begin//1000
            CLK_1 = ~CLK_1;
            T = 0;end
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

顶层连接图

顶层连接图

引脚锁定图

引脚锁定图

本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/411103
推荐阅读
相关标签
  

闽ICP备14008679号