verilog设计一个分,秒定时器电路:输入时钟1KHZ进行分秒计数

verilog设计一个分,秒定时器电路:输入时钟1KHZ进行分秒计数

目标

实现分秒计数
在这里插入图片描述

问题分析

首先要求1KHZ的时钟,周期为1*10e-3s,达成1秒需要1000个周期,因为没有提到占空比就偷懒了,用一个flag信号来代替分频的过程。
其次,既然是要实现分秒计数功能,还需要两个计数器。因为两个计数器都是60进制计数,这两个计数器既可以分开写,也可以通过模块例化来实现。

波形分析

在这里插入图片描述
分频器用计数器计数到998时产生一个周期高电平flag信号en_1作为使能端控制分秒计数器运行,每次en_1为高电平,秒计数器就加1,直到加到59,清0向高位输出一个高电平。分计数器2类似。

代码部分

module clock
(
     input wire         sys_clk     ,
     input wire         sys_rst_n   ,
     
     output reg [5:0]   cnt_s       ,
     output reg [5:0]   cnt_m
    

);

reg [13:0]  cnt_1000;
reg    en_1;
reg    cnt_1m;
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_1000 <= 12'd0;
    else if(cnt_1000 == 999)
        cnt_1000 <= 12'd0;
    else    
        cnt_1000 <= cnt_1000 +12'd1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        en_1 <= 1'b0;
    else if (cnt_1000 == 998)
        en_1 <= 1'b1;
    else
        en_1 <= 1'b0;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_s <= 6'd0;
    else if (cnt_s == 6'd59)
        cnt_s <= 6'd0;
    else if(en_1 <= 1'b1)
        cnt_s <= cnt_s +6'd1;
    else
        cnt_s <= cnt_s;

always@(posedge sys_clk or negedge sys_rst_n)
    if (sys_rst_n == 1'b0)
        cnt_1m <= 1'b0;
    else if (cnt_s == 6'd59)
        cnt_1m <= 1'b1;
    else
        cnt_1m <= 1'b0;
 always@(posedge sys_clk or negedge sys_rst_n)
    if (sys_rst_n == 1'b0)
        cnt_m <= 6'd0;
    else if(cnt_1m == 1'b1)
        cnt_m <= 6'd1;
    else    
        cnt_m <= 6'd0;
        
        
endmodule

模块例化演示代码

分频部分

module cnt_div
(
     input wire         sys_clk     ,
     input wire         sys_rst_n   ,
     
     output reg         en_1      
    

);
reg [13:0]  cnt_1000;
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_1000 <= 12'd0;
    else if(cnt_1000 == 999)
        cnt_1000 <= 12'd0;
    else    
        cnt_1000 <= cnt_1000 +12'd1;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        en_1 <= 1'b0;
    else if (cnt_1000 == 998)
        en_1 <= 1'b1;
    else
        en_1 <= 1'b0;
        
endmodule     

60进制计数器部分

module cnt_60
(
     input wire         sys_clk     ,
     input wire         sys_rst_n   ,
     input  wire         en_1       ,
     output reg [5:0]   cnt_s       ,
     output reg         cnt_1m
    

);



always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_s <= 6'd0;
    else if (cnt_s == 6'd59)
        cnt_s <= 6'd0;
    else if(en_1 <= 1'b1)
        cnt_s <= cnt_s +6'd1;
    else
        cnt_s <= cnt_s;

always@(posedge sys_clk or negedge sys_rst_n)
    if (sys_rst_n == 1'b0)
        cnt_1m <= 1'b0;
    else if (cnt_s == 6'd59)
        cnt_1m <= 1'b1;
    else
        cnt_1m <= 1'b0;
        
        
        
endmodule        

顶端调用例化模块

module clock_static
(
     input wire         sys_clk     ,
     input wire         sys_rst_n   ,
     
     output wire [5:0]   cnt_s       ,
     output wire [5:0]   cnt_m
    

);

cnt_div
(
     .sys_clk   (sys_clk) ,
     .sys_rst_n (sys_rst_n) ,
     
     .en_1      (en_1)
    

);




cnt_60  second
(
     . sys_clk  (sys_clk) ,
     . sys_rst_n(sys_rst_n) ,
     .  en_1    (en_1) ,
     . cnt_s    (cnt_s) ,
     . cnt_1m   (cnt_1m)
    

);
cnt_60  minutes
(
    . sys_clk    (sys_clk),
    . sys_rst_n  (sys_rst_n),
    .  en_1      (cnt_1m),
    . cnt_s      (cnt_m),
    . cnt_1m     ()
    

);

endmodule

Quartus验证

使用的是例化的代码,验证效果如下在这里插入图片描述

总结

题目比较简单,使用了计数器的知识,尝试练习了一下模块例化的使用,若有细节错误,请帮忙指出改正

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页