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

【FPGA】Verilog:升降计数器 | 波纹计数器 | 约翰逊计数器 | 实现 4-bit 升降计数器的 UP/DOWN_第1张图片

目录

Ⅰ. 理论部分

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/Down Counter)

【FPGA】Verilog:升降计数器 | 波纹计数器 | 约翰逊计数器 | 实现 4-bit 升降计数器的 UP/DOWN_第2张图片

0x01 波纹计数器(Ripple Counter)

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

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

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

【FPGA】Verilog:升降计数器 | 波纹计数器 | 约翰逊计数器 | 实现 4-bit 升降计数器的 UP/DOWN_第3张图片

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

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

约翰逊计数器(Johnson Counter)

【FPGA】Verilog:升降计数器 | 波纹计数器 | 约翰逊计数器 | 实现 4-bit 升降计数器的 UP/DOWN_第4张图片

Ⅱ. 实践部分

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:

`timescale 1ns / 1ps

module UD(
    input reset,
    input clk,
    input up,
    output[3:0] out,
    output[6:0] DS
);

reg[3:0] out;
reg[6:0] DS;

always @(posedge clk) begin

    if(reset) begin
        out[3] <= 1'b0;
        out[2] <= 1'b0;
        out[1] <= 1'b0;
        out[0] <= 1'b0;
        DS <= 1'b0;
    end

    else begin
        if((up == 1'b1)) begin
            out = out+1;
            DS[0] <= 1'b0;
            DS[1] <= 1'b1;
            DS[2] <= 1'b1;
            DS[3] <= 1'b1;
            DS[4] <= 1'b1;
            DS[5] <= 1'b1;
            DS[6] <= 1'b0;
        end
        if((up == 1'b0)) begin
            out = out-1;
            DS[0] <= 1'b0;
            DS[1] <= 1'b1;
            DS[2] <= 1'b1;
            DS[3] <= 1'b1;
            DS[4] <= 1'b1;
            DS[5] <= 1'b0;
            DS[6] <= 1'b1;
        end
    end

end


endmodule

0x03 仿真代码

Testbench:

`timescale 1ns / 1ps

module UD_tb;

reg clk,reset,up;
wire[3:0] out;
wire[6:0] DS;

UD u_UD(
    .clk(clk ),
    .reset(reset ),
    .up(up ),
    .out(out ),
    .DS(DS )
);

initial clk = 1'b0;
initial reset = 1'b1;
initial up = 1'b0;


always clk = #20 ~clk;

always@(reset) begin
    reset = #30 ~reset;
end

always@(up) begin
    up = #50 ~up;
    up = #20 ~up;
    up = #20 ~up;
    up = #20 ~up;
    up = #20 ~up;
    up = #20 ~up;
    up = #20 ~up;
    up = #20 ~up;
    up = #20 ~up;
    up = #20 ~up;
end

initial begin
    #420
    $finish;
end

endmodule

运行结果如下:

【FPGA】Verilog:升降计数器 | 波纹计数器 | 约翰逊计数器 | 实现 4-bit 升降计数器的 UP/DOWN_第5张图片

0x04 效果演示

【FPGA】Verilog:升降计数器 | 波纹计数器 | 约翰逊计数器 | 实现 4-bit 升降计数器的 UP/DOWN_第6张图片

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

0x05 注意事项

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

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

参考资料 

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

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

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

你可能感兴趣的:(fpga开发)