【Verilog HDL 训练】第 08 天(二进制、Johnson、环形计数器)

举报
李锐博恩 发表于 2021/07/15 04:38:57 2021/07/15
【摘要】 5月6日 计数器 1. 用verilog实现一个4bit二进制计数器。 a) 异步复位 b) 同步复位 input clk, rst_n; output [3:0] o_cnt; Verilog实现代码: module count_2( input clk, input rst_n, output reg [3:0] o_cnt) always @ (posed...

5月6日

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

a) 异步复位

b) 同步复位

input clk, rst_n; output [3:0] o_cnt;


Verilog实现代码:


  
  1. module count_2(
  2. input clk,
  3. input rst_n,
  4. output reg [3:0] o_cnt
  5. )
  6. always @ (posedge clk or negedge rst_n) begin //异步复位
  7. if(!rst_n) begin
  8. o_cnt <= 4'b0000;
  9. end
  10. else if(o_cnt == 4'b1111) begin
  11. o_cnt <= 4'b0000;
  12. end
  13. else begin
  14. o_cnt <= o_cnt + 4'b0001;
  15. end
  16. end
  17. /*
  18. always @ (posedge clk) begin //同步复位
  19. if(!rst_n) begin
  20. o_cnt <= 4'b0000;
  21. end
  22. else if(o_cnt == 4'b1111) begin
  23. o_cnt <= 4'b0000;
  24. end
  25. else begin
  26. o_cnt <= o_cnt + 4'b0001;
  27. end
  28. end
  29. */
  30. endmodule

 

仿真代码:


  
  1. module count_tb(
  2. );
  3. reg clk, rst_n;
  4. wire [3:0] o_cnt;
  5. //generate system clock with the period == 2ns;
  6. always begin
  7. #1 clk = ~clk;
  8. end
  9. initial begin
  10. clk = 0;
  11. end
  12. //initialization
  13. initial begin
  14. rst_n = 0;
  15. #4
  16. rst_n = 1;
  17. #32
  18. rst_n = 0;
  19. #4
  20. rst_n = 1;
  21. end
  22. //Instantiation
  23. count_2 u0(
  24. .clk(clk),
  25. .rst_n(rst_n),
  26. .o_cnt(o_cnt)
  27. );
  28. endmodule

仿真时序图:

RTL原理图:

 

上面是异步复位的仿真图,下面给出同步复位的仿真图:

同步复位的RTL原理图:

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

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

Verilog代码:


  
  1. `timescale 1ns / 1ps
  2. module count_tb(
  3. );
  4. reg clk, rst_n;
  5. wire [3:0] o_cnt;
  6. //generate system clock with the period == 2ns;
  7. always begin
  8. #1 clk = ~clk;
  9. end
  10. initial begin
  11. clk = 0;
  12. end
  13. //initialization
  14. initial begin
  15. rst_n = 0;
  16. #4
  17. rst_n = 1;
  18. #32
  19. rst_n = 0;
  20. #4
  21. rst_n = 1;
  22. end
  23. //Instantiation
  24. count_johnson u0(
  25. .clk(clk),
  26. .rst_n(rst_n),
  27. .o_cnt(o_cnt)
  28. );
  29. endmodule

 

测试文件:


  
  1. `timescale 1ns / 1ps
  2. module count_tb(
  3. );
  4. reg clk, rst_n;
  5. wire [3:0] o_cnt;
  6. //generate system clock with the period == 2ns;
  7. always begin
  8. #1 clk = ~clk;
  9. end
  10. initial begin
  11. clk = 0;
  12. end
  13. //initialization
  14. initial begin
  15. rst_n = 0;
  16. #4
  17. rst_n = 1;
  18. #32
  19. rst_n = 0;
  20. #4
  21. rst_n = 1;
  22. end
  23. //Instantiation
  24. count_johnson u0(
  25. .clk(clk),
  26. .rst_n(rst_n),
  27. .o_cnt(o_cnt)
  28. );
  29. endmodule

时序图:

RTL原理图:

 

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

Verilog描述:


  
  1. `timescale 1ns / 1ps
  2. module count_circle(
  3. input clk,
  4. input rst_n,
  5. output reg [3:0] o_cnt
  6. );
  7. always @ (posedge clk or negedge rst_n) begin
  8. if(!rst_n) begin
  9. o_cnt <=4'b0001;
  10. end
  11. else begin
  12. o_cnt <= {o_cnt[2:0],o_cnt[3]};
  13. end
  14. end
  15. endmodule

测试文件:


  
  1. `timescale 1ns / 1ps
  2. module count_tb(
  3. );
  4. reg clk, rst_n;
  5. wire [3:0] o_cnt;
  6. //generate system clock with the period == 2ns;
  7. always begin
  8. #1 clk = ~clk;
  9. end
  10. initial begin
  11. clk = 0;
  12. end
  13. //initialization
  14. initial begin
  15. rst_n = 0;
  16. #4
  17. rst_n = 1;
  18. #32
  19. rst_n = 0;
  20. #4
  21. rst_n = 1;
  22. end
  23. //Instantiation
  24. count_circle u0(
  25. .clk(clk),
  26. .rst_n(rst_n),
  27. .o_cnt(o_cnt)
  28. );
  29. endmodule

 

仿真时序图:

RTL原理图:

4. 比较一下以上三种计数器的特点。

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

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

 

5. 记录1,2,3题目使用的工具,操作步骤,以及出现的错误和提示信息。

工具:Vivado,notepad++

操作步骤:

先编写Verilog代码,再功能仿真,再生成RTL图。

错误提示:如果用参数,下面就一致用参数,不要用着用着不用了,或者本来没用,又用了。(哈哈)

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/89883249

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。