• 【FPGA】Verilog:升降计数器 | 波纹计数器 | 约翰逊计数器 | 实现 4-bit 升降计数器的 UP/DOWN


    目录

    Ⅰ. 理论部分

    0x00 升降计数器(UP DOWN Counter)

    0x01 波纹计数器(Ripple Counter)

    0x02 约翰逊计数器(Johnson Counter)

    Ⅱ. 实践部分

    0x00 实现:升降计数器(4-bit)

    0x01 绘制输出表

    0x02 设计代码

    0x03 仿真代码

    0x04 效果演示

    0x05 注意事项


    Ⅰ. 理论部分

    0x00 升降计数器(UP DOWN Counter)

    升降计数器 (UP DOWN Counter) 是一种接收一个 UP 或 DOWN 输入的计数器,根据此输入增加或减少计数器的当前值。

    • 如果 UP=1" role="presentation" style="position: relative;">UP=1,则顺时针方向计数;如果 DOWN=1" role="presentation" style="position: relative;">DOWN=1,则逆时针方向计数。
    • 如果 U=D=0" role="presentation" style="position: relative;">U=D=0,则保持静止状态,不允许 U=D=1" role="presentation" style="position: relative;">U=D=1 的输入。

    升降计数器(Up/Down Counter)

    0x01 波纹计数器(Ripple Counter)

    波纹计数器 (Ripple Counter) 其实就是异步计数器的别名,是完全相同的。它采用了多个 Flip-Flop 的串联形式,第一个 Flip-Flop 接收时钟值输入,而连接在后面的 Flip-Flop 则将前一个 Flip-Flop 的输出作为输入值。

    异步计数器是异步时序电路,其主要特点是内部各触发器的时钟脉冲端 CP 不全都连接在一起,因此各触发器的翻转时刻有先有后,其输出可能会产生干扰毛刺现象,但其电路结构简单。

    波纹计数器 / 异步计数器(Ripple Counter)

    0x02 约翰逊计数器(Johnson Counter)

    约翰逊计数器是一种环形计数器,它将最后一个 Flip-flop 的输出 (Q) 取反 (~Q) 并传递给第一个Flip-flop 的输入。约翰逊计数器通常使用 CD4017、CD4022 等元件,主要用作十进制计数器或八进制计数器。

    约翰逊计数器(Johnson Counter)

    Ⅱ. 实践部分

    0x00 实现:升降计数器(4-bit)

    📚 请描述 4 位升降寄存器的结果和仿真过程。用 Verilog 实现 4 位升降计数器,画出输出表,并在 Verilog 中验证仿真结果。

    0x01 绘制输出表

    升计数器输出表(UP)

    Number of Clk Transitions

    输出

    L1(MSB)

    L2

    L3

    L4(LSB)

    DISPLAY

    1

    0

    0

    0

    1

    U

    2

    0

    0

    1

    0

    U

    3

    0

    0

    1

    1

    U

    4

    0

    1

    0

    0

    U

    5

    0

    1

    0

    1

    U

    6

    0

    1

    1

    0

    U

    7

    0

    1

    1

    1

    U

    降计数器输出表(DOWN)

    Number of Clk Transitions

    输出

    L1(MSB)

    L2

    L3

    L4(LSB)

    DISPLAY

    1

    0

    1

    1

    1

    d

    2

    0

    1

    1

    0

    d

    3

    0

    1

    0

    1

    d

    4

    0

    1

    0

    0

    d

    5

    0

    0

    1

    1

    d

    6

    0

    0

    1

    0

    d

    7

    0

    0

    0

    1

    d

    0x02 设计代码

    💬 Design source:

    1. `timescale 1ns / 1ps
    2. module UD(
    3. input reset,
    4. input clk,
    5. input up,
    6. output[3:0] out,
    7. output[6:0] DS
    8. );
    9. reg[3:0] out;
    10. reg[6:0] DS;
    11. always @(posedge clk) begin
    12. if(reset) begin
    13. out[3] <= 1'b0;
    14. out[2] <= 1'b0;
    15. out[1] <= 1'b0;
    16. out[0] <= 1'b0;
    17. DS <= 1'b0;
    18. end
    19. else begin
    20. if((up == 1'b1)) begin
    21. out = out+1;
    22. DS[0] <= 1'b0;
    23. DS[1] <= 1'b1;
    24. DS[2] <= 1'b1;
    25. DS[3] <= 1'b1;
    26. DS[4] <= 1'b1;
    27. DS[5] <= 1'b1;
    28. DS[6] <= 1'b0;
    29. end
    30. if((up == 1'b0)) begin
    31. out = out-1;
    32. DS[0] <= 1'b0;
    33. DS[1] <= 1'b1;
    34. DS[2] <= 1'b1;
    35. DS[3] <= 1'b1;
    36. DS[4] <= 1'b1;
    37. DS[5] <= 1'b0;
    38. DS[6] <= 1'b1;
    39. end
    40. end
    41. end
    42. endmodule

    0x03 仿真代码

    💬 Testbench:

    1. `timescale 1ns / 1ps
    2. module UD_tb;
    3. reg clk,reset,up;
    4. wire[3:0] out;
    5. wire[6:0] DS;
    6. UD u_UD(
    7. .clk(clk ),
    8. .reset(reset ),
    9. .up(up ),
    10. .out(out ),
    11. .DS(DS )
    12. );
    13. initial clk = 1'b0;
    14. initial reset = 1'b1;
    15. initial up = 1'b0;
    16. always clk = #20 ~clk;
    17. always@(reset) begin
    18. reset = #30 ~reset;
    19. end
    20. always@(up) begin
    21. up = #50 ~up;
    22. up = #20 ~up;
    23. up = #20 ~up;
    24. up = #20 ~up;
    25. up = #20 ~up;
    26. up = #20 ~up;
    27. up = #20 ~up;
    28. up = #20 ~up;
    29. up = #20 ~up;
    30. up = #20 ~up;
    31. end
    32. initial begin
    33. #420
    34. $finish;
    35. end
    36. endmodule

    🚩 运行结果如下:

    0x04 效果演示

    🔑 解读:每次时钟转换时,升降计数器都会在收到上行输入时将存储值递增 1,在收到下行输入时将存储值递减 1。由于是 4 位计数器,可表示的最大值为 15,最小值为 0。当接收到 UP 输入时,它将在 7 段显示屏上显示字母 "U";当接收到 DOWN 输入时,将在 7 段显示屏上显示字母 "d"。该电路设计为上升沿触发器,因此当时钟值从 0 变为 1 时,当前状态的变化将被应用到存储器中。

    0x05 注意事项

    📌 注意:值得注意的是,使用 7 段显示时,不要忘记在编写约束文件时不仅要为 7 段显示分配 7 个变量,还要在设计源文件中适当声明和分配 dp 和 digit 变量。即使正确分配了 7 段显示,如果没有分配 DP 和 DIGIT 变量,显示也将无法工作。

    1. 📌 [ 笔者 ]   王亦优
    2. 📃 [ 更新 ]   2023.11.10
    3. ❌ [ 勘误 ]   /* 暂无 */
    4. 📜 [ 声明 ]   由于作者水平有限,本文有错误和不准确之处在所难免,
    5. 本人也很想知道这些错误,恳望读者批评指正!

    📜 参考资料 

    Introduction to Logic and Computer Design, Alan Marcovitz, McGrawHill, 2008

    Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. .

    百度百科[EB/OL]. []. https://baike.baidu.com/.

  • 相关阅读:
    什么是日志分析?为什么IT管理员需要日志分析?
    【无标题】
    20220719_Filter_Listener_AJAX_Axios的用法
    详解WMS——定义与功能
    如何将PCB区域修改为板子形状大小(修改黑色区域大小)
    2023年中国汽车覆盖件模具竞争格局、市场规模及行业需求前景[图]
    【selection】 学习光标API并实现编辑区插入表情图片的功能
    【Mysql】mysql | 命令 | 常用命令 | 登录指明端口
    【python】采集**本子,不要看了,快进来~
    【C++风云录】开源金融与科技库探索:优化计算与高效分析
  • 原文地址:https://blog.csdn.net/weixin_50502862/article/details/134319516