首页 > 其他 > 详细

几种计数器的实现

时间:2020-04-25 14:28:29      阅读:57      评论:0      收藏:0      [点我收藏+]

1.普通计数器 1. 用verilog实现一个4bit二进制计数器。

a) 异步复位

b) 同步复位

module count_2(
    input clk,
    input rst_n,
    output reg [3:0] o_cnt
)
    always @ (posedge clk or negedge rst_n) begin //异步复位
        if(!rst_n) begin
            o_cnt <= 4b0000; 
        end
        else if(o_cnt == 4b1111) begin
            o_cnt <= 4b0000;
        end
        else begin
            o_cnt <= o_cnt + 4b0001;
        end
    end
    /*
    always @ (posedge clk) begin //同步复位
        if(!rst_n) begin
            o_cnt <= 4‘b0000;
        end
        else if(o_cnt == 4‘b1111) begin
            o_cnt <= 4‘b0000;
        end
        else begin
            o_cnt <= o_cnt + 4‘b0001;
        end
    end
    */
 
endmodule
module count_tb(
    );
    
    reg clk, rst_n;
    wire [3:0] o_cnt;
    
    //generate system clock with the period == 2ns;
    always begin
        #1 clk = ~clk;
    end
    initial begin
        clk = 0;
    end
    
    //initialization
    initial begin
    rst_n = 0;
    #4
    rst_n = 1;
    
    #32
    rst_n = 0;
    #4
    rst_n = 1;
    
    end
    
    //Instantiation
    count_2 u0(
    .clk(clk),
    .rst_n(rst_n),
    .o_cnt(o_cnt)
    );
    
    
    
endmodule

 

2.

用verilog实现4bit约翰逊(Johnson)计数器。

约翰逊(Johnson)计数器又称扭环计数器,是一种用n位触发器来表示2n个状态的计数器。它与环形计数器不同,后者用n位触发器仅可表示n个状态。2进制计数器(n为触发器的个数)有2^n个状态。若以四位二进制计数器为例,它可表示16个状态。但由于8421码每组代码之间可能有二位或二位以上的二进制代码发生改变,这在计数器中特别是异步计数器中就有可能产生错误的译码信号,从而造成永久性的错误。而约翰逊计数器的状态表中,相邻两组代码只可能有一位二进制代码不同,故在计数过程中不会产生错误的译码信号。鉴于上述优点,约翰逊计数器在同步计数器中应用比较广泛。
代码实现:

技术分享图片
module johnson_counter(
                clk,
                rst_n,
                out
                );
    input clk;
    input rst_n;
    output [3:0]out;
    reg [3:0]counter;
    always@(posedge clk or negedge rst_n)
        if(!rst_n)
            counter<=4b0;
        else if(counter[0]==0)
            counter<={1b1,counter[3:1]};
        else 
            counter<={1b0,counter[3:1]};
    assign out=counter;
            
endmodule
View Code

tb:

技术分享图片
`timescale 1ns/1ps
module johnson_counter_tb;
    reg clk;
    reg rst_n;
    wire [3:0]out;
    johnson_counter johnson_counter(
                .clk(clk),
                .rst_n(rst_n),
                .out(out)
                );
    
    initial clk=0;
    always #10 clk=~clk;
    
    initial begin
        rst_n=0;
        #21;
        rst_n=1;
    end
endmodule
View Code

仿真:

技术分享图片

 

 可以看到相邻状态间的切换只有一位变化。

3.用verilog实现4bit环形计数器:复位有效时输出0001,复位释放后依次输出0010,0100,1000,0001,0010...

代码实现:

技术分享图片
module circle_counter(
                    clk,
                    rst_n,
                    out
                    );
    input clk;
    input rst_n;
    output [3:0]out;
    
    reg [3:0]counter;
    
    always@(posedge clk or negedge rst_n)
        if(!rst_n)
            counter<=4b0001;
        else
            counter<={counter[2:0],counter[3]};
    assign out=counter;
endmodule
View Code

tb:

技术分享图片
`timescale 1ns/1ps
module circle_counter_tb;
    reg clk;
    reg rst_n;
    wire [3:0]out;
    circle_counter circle_counter(
                .clk(clk),
                .rst_n(rst_n),
                .out(out)
                );
    
    initial clk=0;
    always #10 clk=~clk;
    
    initial begin
        rst_n=0;
        #21;
        rst_n=1;
    end
endmodule
View Code

技术分享图片

 

 

4.总结一下这三种计数器的特点。

假设都是N位的计数器,二进制计数器有2^N个状态,Johnson计数器由2N个状态,而环形计数器由N个状态;

相对于二进制计数器,Johnson计数器相邻两组代码只可能有一位二进制代码不同,环形计数器有两位二进制代码不同。

 

几种计数器的实现

原文:https://www.cnblogs.com/ajiaoa/p/12772706.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!