我是靠谱客的博主 天真黑米,这篇文章主要介绍计数器—verilog,现在分享给大家,希望可以做个参考。

目录

常规带使能计数器

加减计数器

环形计数器

约翰逊(Johnson)计数器(扭环形计数器)

简易秒表

低功耗可恢复计数器


计数器的介绍

计数器是应用最广泛的逻辑部件之一。计数器可以统计输入脉冲的个数,具有计时、计数、分频、定时、产生节拍脉冲等功能。

计数器的种类繁多,根据计数器中触发器时钟端的链接方式,分为同步计数器和异步计数器;

根据计数方式,分为二进制计数器、十进制计数器和任意进制计数器;

根据计数器中的状态变化规律,分为加法计数器、减法计数器和加/减计数器。
 

常规带使能计数器

介绍:带使能端的模100异步清零计数器为例

1. 设计代码

复制代码
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
31
32
33
34
35
36
37
38
39
40
41
42
// 以带使能的模100异步清零计数器为例---------- `timescale 1ns/1ps module cnt #(parameter COUNT=100)( input clk, input rst_n, input cnt_en, output reg [6:0]out//如果参数化中COUNT比较大,需要更改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 //写法1: if(out!=COUNT-1)begin out<=out+1'b1; set<=1'b0; end else begin out<=7'd0; set<=1'b1; end /* //写法2: 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 //maybe end endmodule

2. 测试代码

复制代码
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
module cnt_tst(); reg clk ; reg rst_n ; reg cnt_en ; wire [6: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

3. 仿真波形

 

加减计数器

1. 设计代码

复制代码
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// ----------------------加减计数器----------------- `timescale 1ns/1ns module count_module( input clk, input rst_n, input mode, output reg [3:0]number, output reg zero ); reg [3:0] num_temp; always @(posedge clk or negedge rst_n) begin if(~rst_n) begin num_temp <= 4'b0; number <= 4'b0; end else begin if (mode == 1'b1) begin if(num_temp == 4'd9) begin num_temp <= 4'd0; number <= num_temp; end else begin num_temp <= num_temp + 4'd1; number <= num_temp; end end else begin if(num_temp == 4'd0) begin num_temp <= 4'd9; number <= num_temp; end else begin num_temp <= num_temp - 4'd1; number <= num_temp; end end end end always @(posedge clk or negedge rst_n) begin if(~rst_n) zero <= 4'b0; else zero <= (num_temp == 4'b0); end endmodule

2.测试代码

复制代码
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
module testbench(); reg clk,rst_n; reg mode; reg [3:0]number; reg zero; count_module counter( .clk (clk), .rst_n (rst_n), .mode(mode), .number(number), .zero (zero) ); initial begin clk=0; rst_n=0; mode = 1; #20 rst_n=1; #500 mode = 1; #500 mode = 0; #500 mode = 1; end always #10 clk=~clk; endmodule

3.仿真波形

 

环形计数器

环形计数器,n个触发器表示n个状态。所谓环形,是指“1”,在每一组数中出现的位置形成的效果图,像一个环一样,依次循环,以4bit环形计数器为例子,“1”的位置依次在第0bit、第1bit,第2bit,第3bit,再回到第0bit,依次类推,就像一个环。如 4bit环形计数器:复位有效时输出0001,复位释放后依次输出0010,0100,1000,0001,0010…。

1. 设计代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
//环形计数器 module ring_counter#(parameter word_size=4)( input clk, input rst_n, input enable, output reg [word_size-1:0]count ); always@(posedge clk,negedge rst_n) if(!rst_n) count<={{(word_size-1){1'b0}},1'b1}; else if(enable==1'b1)count<={ count[word_size-2:0],count[word_size-1]}; endmodule

2. 测试代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module ring_counter_tst #(parameter word_size=4)(); reg clk; reg rst_n; reg enable; wire [word_size-1:0]count; ring_counter U_ring_counter( .clk (clk), .rst_n (rst_n), .enable(enable), .count (count) ); initial begin clk=0; rst_n=0; enable=0; #20 rst_n=1; #20 enable=1; end always #10 clk=~clk; endmodule

3. 仿真波形

 

约翰逊(Johnson)计数器(扭环形计数器)

约翰逊(Johnson)计数器又称扭环计数器,是一种用n位触发器来表示2n个状态的计数器。约翰逊(Johnson)计数器有一个非常明显地好处,相邻两组数只有一位不同,具体如下例子所示,因此在计数过程中不会存在竞争冒险问题。

以4bit约翰逊(Johnson)计数器为例,4bit约翰逊(Johnson)计数器,能表示8种状态,相邻两组数之间,仅有1bit不同:

0000 1000 1100 1110 1111 0111 0011

0001 0000 1000

为什么叫扭环形呢?小编的理解:相邻两组数的变化很像是扭了一下,如上图中1000 和1100,将1000的高三位放在1100中的低三位,再将1000中最低位0取反,放到1100中的最高位。

1. 设计代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
module johnson_counter#(parameter WIDTH = 4)( input clk, input rst_n, output reg [WIDTH-1:0] cnt ); always@(posedge clk or negedge rst_n) begin if(!rst_n) cnt <= { WIDTH { 1'b0 }}; else cnt <= { ~cnt[0], cnt[WIDTH-1:1] }; end endmodule

2. 测试代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
module johnson_counter_tst #(parameter WIDTH = 4)(); reg clk; reg rst_n; wire [WIDTH-1:0] cnt; johnson_counter U_johnson_counter( . clk(clk), . rst_n(rst_n), . cnt(cnt) ); initial begin clk=0; rst_n=0; #20 rst_n=1; end always #10 clk=~clk; endmodule

3. 仿真波形

 

简易秒表

实现简易秒表的功能:具有两个输出,当输出端口second从1-60循环计数,每当second计数到60,输出端口minute加一,一直到minute=60,暂停计数。

1. 设计代码

复制代码
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
`timescale 1ns/1ns module count_module ( input clk, input rst_n, output reg [5:0]second, output reg [5:0]minute ); always @(posedge clk or negedge rst_n) begin if(~rst_n) begin second <= 6'b0; minute <= 6'b0; end else begin if(minute == 6'd60) begin second <= second; minute <= minute; end else if(second == 6'd60)begin second <= 6'b1; minute <= minute + 6'b1; end else begin second <= second + 6'b1; end end end endmodule

2. 测试代码

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
module testbench(); reg clk,rst_n; wire [5:0]second; wire [5:0]minute; count_module miaobiao_counter( .clk (clk), .rst_n (rst_n), .second(second), .minute (minute) ); initial begin clk=0; rst_n=0; #20 rst_n=1; end always #10 clk=~clk; endmodule

3. 仿真波形

 

 

低功耗可恢复计数器

这个暂时还没有找到资料,望批评指正~~

引用

计数器是非常基本的使用,没有计数器就无法处理时序。我在学习时发现市面上有几种不同的计数器写法,非常有趣,在此记录下来——咸鱼FPGA

【手撕代码】数字IC秋招中常见六种计数器(含源码)——IC媛

Verilog学习之路(9)—计数器和移位寄存器——Willliam_william

最后

以上就是天真黑米最近收集整理的关于计数器—verilog的全部内容,更多相关计数器—verilog内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(68)

评论列表共有 0 条评论

立即
投稿
返回
顶部