常规计数器

一、原理

计数器可以统计输入脉冲的个数,具有计时、计数、分频、定时、产生节拍脉冲等功能。

根据计数器中触发器时钟端的链接方式,分为同步计数器和异步计数器;
根据计数方式,分为二进制计数器、十进制计数器和任意进制计数器;
根据计数器中的状态变化规律,分为加法计数器、减法计数器和加/减计数器。

二、常规计数器 

// 带使能的模9(out=0、1、2、3、4、5、6、7、8,可以定时9×周期T)异步清零计数器
`timescale 1ns/1ps
module cnt #(parameter COUNT=9)(   //这里可以改模
    input clk,
    input rst_n,
    input cnt_en,
    output reg [3:0]out//在这里更改out的位宽来适配COUNT的值 
    );        //  9=1001 如果这里位宽改了,测试用例也要改out的位宽
    reg set;   
always@(posedge clk or negedge rst_n)//异步清零 
begin             
    if(!rst_n) 
        begin out<=7'd0;set<=1'b0;end
    else if(cnt_en) 
         begin
            if(out==COUNT-1) 
            begin out<=7'd0;set<=1'b1;end
            else  
            begin out<=out+1'b1;set<=1'b0;end  
         end             
        else 
            begin out<=7'd0;set<=1'b0;end    
end 
endmodule

三、生成的电路图

1、清零未使能时(rst_n=0,cnt_en=0),Q端为0,经过 +1 后,第一个选择器输出1。由于未使能,则第二个选择器的输入 I0 被“卡住”,所以只要不使能,第二个选择器输入 I0 端一直是 1 。由于不使能, 第二个选择器的输出选择默认输入(default)即第二个选择器一直输出0,即D端一直是0 。总结:清零且未使能,不管来多少个时钟上升沿,D触发器的D端和Q端(out)都是0

2、清零未使能时(rst_n=1,cnt_en=0),和上面一样,不管来多少个时钟上升沿,D触发器的D端和Q端(out)都是0

3、不清零且使能(rst_n=1,cnt_en=1),第一个时钟上升沿未到前,D端是1,但是Q端仍是0。在第一个上升沿后,Q端变成1 。第一个上升沿后,第二个上升沿前的这段时间,Q端 +1 ,第一个选择器输出2,第二个选择器输出2,D端是2,Q端是1 。

总结:不清零且使能(rst_n=1,cnt_en=1),第一个时钟上升沿到达那一刻,Q端是1 。 

4、不清零且使能(rst_n=1,cnt_en=1),第八个时钟上升沿到,Q端是8 。在第八个上升沿后,第九个上升沿前的这段时间(蓝色部分),Q端是8,第一个选择器输出0 ,第二个选择器输出0,D端是0 。当第九个上升沿到时,Q端才变成0 。 

总结:不清零且使能(rst_n=1,cnt_en=1),第八个时钟上升沿到达那一刻,Q端是8 。

           不清零且使能(rst_n=1,cnt_en=1),第九个时钟上升沿到达那一刻,Q端是0 。

           不清零且使能(rst_n=1,cnt_en=1),第十个时钟上升沿到达那一刻,Q端是1 。

 5、对电路图总结:不清零且使能(rst_n=1,cnt_en=1)后的第一个上升沿开始,到第十个上升沿结束,即out=1、2、3、4、5、6、7、8、0 各维持一个时钟周期。这样便是9个时钟周期。

四、仿真波形

 对于上面的电路,只要 不清零且使能(rst_n=1,cnt_en=1),那么第一个out肯定是1。

但是在引用计数模块时,可以加个set信号,让它在 不清零且使能(rst_n=1,cnt_en=1)后(第八个上升沿时,out为8)的第九个上升沿判断out是否为8,如果是,则让out=0,且set=1。

第十个上升沿,out=1,set=0 。

也就是说:

        可以用set信号来定时,当 不清零且使能(rst_n=1,cnt_en=1)且在第一个时钟有效沿后,只要 out = 0,那么set就输出一个高电平。相邻两个set高电平期间的时间,就是 9个时钟周期。分别是 out =0、1、2、3、4、5、6、7、8 这九个值各维持一个时钟周期。

五、测试代码

module cnt_tst();
    reg clk;
    reg rst_n;
    reg cnt_en;
    wire [3:0]out;
cnt U_cnt(
    .clk(clk),
    .rst_n(rst_n),
    .cnt_en(cnt_en),
    .out(out)
);
initial
begin
    clk=1;
    rst_n=0;
    cnt_en=0;
    #10; 
    rst_n=1;
    cnt_en=1;
    #100; 
    cnt_en=0;
    #200;
    cnt_en=1;
    #2000; 
    cnt_en=0;
end
always #10 clk=~clk;
endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值