yaboPP电子
Technical Article

Understanding Verilog Shift Registers

2019年8月27日byGarrett Holthaus

This article will discuss how to implement a shift register in Verilog. The register described can be synthesized and downloaded to an FPGA for test in actual hardware.

This article will discuss how to implement a shift register in Verilog. The register described can be synthesized and downloaded to an FPGA for test in actual hardware.

Verilog Shift寄存器基本概念/特征

以最简单的形式,移位寄存器由串联连接的许多存储元素(例如,触发器)组成,因此一个存储元件的输出输入到了下一个输入中。存储元素由公共时钟信号控制:

Figure 1.4-bit shift register

假设我们正在使用正边触发的触发器。考虑图1(FF0和FF1)中标记为0和1的触发器。FF0的输入是移位寄存器的输入。FF1的输入是FF0的输出,它也是FF0的当前值。在正时钟边缘,FF0将捕获其输入,FF1将捕获FF0的当前值。

If all the flip flops start out reset to 0 and we hold the input of the shift register at 1, then a positive clock edge will cause ff0 to capture a 1.

在第二个正时钟边缘上,FF1将捕获1,因为它已经对FF0的输出进行了采样(见图2):

Figure 2.两个正时钟边缘或“偏移”的结果

On each successive positive clock edge, the 1 will “shift” to the next flip flop in the chain until it appears at the output of the shift register, which is the output of ff3 in the 4-bit shift register shown above. If we have held the input at 1 during this time, the register will now hold all 1s.

Verilog换档寄存器代码

Verilog is a hardware description language, or HDL, which means it can be used to describe actual logic circuit hardware. Because of this, there are several aspects of Verilog that are different from typical software programming languages.

There are two important things to keep in mind when writing Verilog code:

  1. Just like in an actual circuit, some parts of Verilog code execute simultaneously, not sequentially or line-by-line as in a single-threaded software program.
  2. Not all Verilog constructs can be synthesized, or turned into an actual logic circuit.

在此示例中,我们的目标是编写可合理的代码。这也将使我们可以将代码下载到FPGA中,以实际看到它!

模块声明

我们将从模块声明开始:

模块shiftreg4(输入shift_in,输入时钟,输出shift_out);

模块构成了基于Verilog设计的基本构建块。通过在模块中声明的移位寄存器,我们可以根据需要进行尽可能多的副本进行实例化的副本,从而连接我们在较大电路中的喜好。

Theinputand输出语句是端口声明 - 他们确定当我们实例化轮班寄存器时将有哪些连接。目前,我们只有一个移动输入,时钟输入和一个移动输出。

Reg

Next, we need to define the circuitry and wired connections for our shift register. Like the diagram above, we’ll use four flip flops for this 4-bit shift register.

我们可以使用Reg关键字创建触发器:

reg bit0; reg bit1; reg bit2; reg bit3; assign shift_out = bit3;

Here we have four flip flops named bit0 through bit3.

BIT0 FLIP FLOP将其输入连接到Shift_in端口;我们将在下一个代码中考虑到这一点。

BIT3 FLIP FLOP将其输出连接到Shift_Out端口,我们已经通过一个分配语句完成了此操作,该分配语句可用于接线和组合逻辑。

程序块

Now, we need to tell Verilog what to do with these flip flops, and this is accomplished in a procedural block.

A procedural block can be used to define either combinational or sequential logic but, in this example, we’ll only use one for sequential logic (logic with stored values, e.g., in flip flops).

always @(posedge clock) begin bit3 <= bit2; bit2 <= bit1; bit1 <= bit0; bit0 <= shift_in; end endmodule

The procedural block starts with the always keyword, followed by a sensitivity list. The sensitivity list tells Verilog when to evaluate the statements in the block; in this case, we evaluate the block on every positive clock edge (@posedge clock).

When the block is triggered on a positive clock edge, we simply shift the contents of each flip flop to the next flip flop in the chain. So, bit3 gets what was previously in bit2, bit2 gets what was in bit1, and so on. Note that we delineate where the block starts and finishes with begin and end statements.

端模

Finally, we end our module with an endmodule statement. Congratulations—you’ve just created a 4-bit Verilog shift register!

Practical Considerations: Indexing and the Shift Operator

我们创建了Verilog代码,以与我们设想的电路完全匹配,并连接四个单独的触发器。这非常适合确切了解将要合成的内容,但是如果我们必须手动声明设计中的每个翻牌失败,这变得乏味。

幸运的是,Verilog有许多不同的快捷方式,在这里我们可以使用索引和换档操作员:

reg [3:0]位;分配shift_out = bit [3];总是 @(posEdge时钟)开始bit <= bits << 1;位[0] <= shift_in;结尾

This is much more compact! We’ve declared a 4-bit register all at once with the bracket notation “[3:0],” which indicates that bit 3 is the most significant bit (MSB).

Note that we have to change our assign statement to wire bit 3 of the register to our shift_out signal. Now, instead of writing procedural block statements to individually change each bit, we can use a single statement with the shift left operator (<<) to accomplish what we want. On each positive clock, the data in our 4-bit register will be shifted one position to the left, and the new MSB will be driven on shift_out.

同样请注意,此实现使更改偏移顺序变得容易。目前,我们正在从LSB转移到MSB,但是我们可以轻松地更改它,以便我们从MSB转移到LSB。自己尝试一下!

Verilog中的合成

One caveat: In Verilog, just declaring a node as reg doesn’t automatically create a flip flop. This is where the principle of synthesis and synthesizable code comes in.

reg节点将保留其值,直到分配另一个值。合成代码以创建实际的硬件结构时,这可能会导致触发器(通常是想要的),闩锁(通常不需要)或错误,具体取决于节点的分配方式。将“ @posedge时钟”放在我们的敏感性列表中,并谨慎地将程序块中的所有登录信号分配为确保我们将获得我们期望的触发器。

Uses/Applications

Shift registers often find application in situations where we need to convert from parallel data (typically used internally in a microprocessor or other ASIC) to serial data (often used for communication between components on a PCB or between two separate PCBs). For this purpose, we typically add a load signal and wires to each of the individual flip flop inputs in the shift register so that parallel data can be loaded into the shift register all at once and then shifted out bit by bit.

To implement serial communication protocols such asI2Candspi, we can use a state machine to control when the individual data bits are shifted out of the register in order to meet the requirements of the scheme we have chosen.

We can also add wires to the outputs of each individual flip flop so that a device can receive serial data bit by bit and then read it out of the shift register in parallel when all bits have been shifted in.

结论

In this article, we discussed how to implement a basic shift register in Verilog. A typical workflow would next involve writing a testbench to instantiate our new shift register and drive some inputs to it so we can verify the correct operation in simulation, before synthesizing the code and downloading it to an FPGA for test in actual hardware.

I hope you enjoyed this short example!

1 Comment
  • Barry Moss 2019年8月30日

    Verilog中的REG关键字简单地表明该值将在始终块中分配。您可以在始终块中创建组合逻辑 - 实际上,这对于复杂的组合结构非常有用,您可能不想尝试使用分配语句在单行上定义这些结构。始终块的输出仍然定义为REG,即使通过没有寄存器或闩锁在合成中产生。这实际上是Verilog中相当令人困惑的命名法(reg!= register);因此,SystemVerilog已用逻辑关键字代替了Reg和电线。

    喜欢。 Reply