首页 > 应用 > 通信

了解Verilog移位寄存器

Garrett Holthaus 2019-09-23

Verilog移位寄存器基本概念/特征CPM电子头条

 CPM电子头条

在其最简单的形式中,移位寄存器由串联连接的多个存储元件(例如触发器)组成,这样一个存储元件的输出就输入到到下一个存储元件中。存储元件由公共时钟信号控制:CPM电子头条

 CPM电子头条

了解Verilog移位寄存器CPM电子头条

图1.4位移位寄存器CPM电子头条

 CPM电子头条

假设我们使用正边缘触发器。考虑图1中标记为0和1的触发器(ff0和ff1)。ff0的输入是移位寄存器的输入。ff0的输入是移位寄存器的输入。ff1的输入是ff0的输出,也是ff0的当前值。在正时钟边缘,ff0将捕获其输入,ff1将捕获ff0的当前值。如果所有触发器开始复位为0并且将移位寄存器的输入保持为1,则正时钟沿将导致ff0捕获1。在第二个正时钟边沿,ff1将捕获1,因为它已对ff0的输出进行采样(参见图2):CPM电子头条

 CPM电子头条

了解Verilog移位寄存器CPM电子头条

图2.两个正时钟边沿或“移位”的结果CPM电子头条

 CPM电子头条

在每个连续的正时钟沿,1将移位到链中的下一个触发器,直到它出现在移位寄存器的输出端,这是上面所示的4位移位寄存器中ff3的输出。如果在此期间将输入保持为1,则寄存器现在将保持全1。CPM电子头条

 CPM电子头条

Verilog移位寄存器代码CPM电子头条

 CPM电子头条

Verilog是一种硬件描述语言,即HDL,这意味着它可以用来描述实际的逻辑电路硬件。因此,Verilog的几个方面与典型的软件编程语言不同。编写Verilog代码时要记住两件重要的事情:就像在实际电路中一样,Verilog代码的某些部分同时执行,而不是像单线程软件程序那样按顺序或逐行执行;并非所有Verilog结构都可以合成,或者变成实际的逻辑电路。我们的目标是在这个例子中编写可综合的代码。这也将允许我们将代码下载到FPGA中,以实际看到它的实际运行!CPM电子头条

 CPM电子头条

模块声明CPM电子头条

 CPM电子头条

从模块声明开始:CPM电子头条

 CPM电子头条

了解Verilog移位寄存器CPM电子头条

 CPM电子头条

模块构成了基于Verilog的设计的基本构建模块。通过在模块中声明我们的移位寄存器,我们可以根据需要实例化它的多个副本,在更大的电路中连接我们喜欢的方式。在输入和输出语句是端口声明,它们决定连接将提供什么,当我们实例移位寄存器。目前,我们只有一个移位输入、一个时钟输入和一个移位输出。CPM电子头条

 CPM电子头条

寄存器CPM电子头条

 CPM电子头条

接下来,我们需要为移位寄存器定义电路和有线连接。如上图所示,我们将为这个4位移位寄存器使用四个触发器。我们可以使用reg关键字创建一个触发器:CPM电子头条

 CPM电子头条

了解Verilog移位寄存器CPM电子头条

 CPM电子头条

这里我们有四个名为bit0到bit3的触发器。bit0触发器的输入连接到shift_in端口;我们将在下一段代码中处理这个问题。bit3触发器的输出将连接到shift_out端口,我们使用assign语句完成了这一操作,该语句可用于布线和组合逻辑。CPM电子头条

 CPM电子头条

程序块CPM电子头条

 CPM电子头条

需要告诉Verilog如何处理这些触发器,这是在程序块中完成的。程序块可用于定义组合逻辑或顺序逻辑,但在此示例中,我们将仅使用一个用于顺序逻辑(具有存储值的逻辑,例如在触发器中)。 CPM电子头条

 CPM电子头条

了解Verilog移位寄存器CPM电子头条

 CPM电子头条

过程块以always关键字开头,后跟灵敏度列表。灵敏度列表告诉Verilog何时评估块中的语句;在这种情况下,我们在每个正时钟边缘(@posedge时钟)评估块。CPM电子头条

 CPM电子头条

当块在正时钟边缘触发时,我们只需将每个触发器的内容移位到链中的下一个触发器。因此,bit3得到bit2中先前的内容,bit2得到bit1中的内容,依此类推。请注意,我们用begin和end语句描述块的开始和结束位置。CPM电子头条

CPM电子头条
CPM电子头条

EndmoduleCPM电子头条

 CPM电子头条

最后,我们使用endmodule语句结束我们的模块。恭喜你刚刚创建了一个4位Verilog移位寄存器!CPM电子头条

 CPM电子头条

实际考虑因素:索引和移位运算符CPM电子头条

 CPM电子头条

我们创建的verilog代码与我们预想的电路完全匹配,四个独立的触发器串联连接。这对于准确知道将要合成的内容非常有用,但是如果我们必须手动声明设计中的每个触发器,这将变得很乏味。幸运的是,Verilog有许多不同的快捷方式,在这里我们可以使用索引和移位运算符:CPM电子头条

 CPM电子头条

了解Verilog移位寄存器CPM电子头条

 CPM电子头条

这个更紧凑!我们用括号[3:0]一次性声明了一个4位寄存器,这表示第3位是最高位(MSB)。请注意,我们必须将assign语句更改为将寄存器的第3位连接到我们的shift_out信号。现在可以使用带左移位运算符(<<)的单个语句来完成我们想要的操作,而不是编写程序块语句来单独更改每个位。在每个正时钟上,4位寄存器中的数据将向左移位一个位置,新的MSB将在shift_out上驱动。另请注意,此实现可以轻松更改轮询顺序。目前,我们正在从LSB转向MSB,但我们可以轻松改变这一点,以便我们从MSB转向LSB。CPM电子头条

 CPM电子头条

Verilog中的合成CPM电子头条

 CPM电子头条

一个警告:在Verilog中,只是将一个节点声明为reg不会自动创建一个触发器。这就是合成和可综合代码的原理。一个reg节点将保持其值,直到为其分配另一个值。当合成代码以创建实际硬件结构时,这可能导致触发器(通常是所需的),锁存器(通常不需要)或错误,这取决于节点的分配方式。将@posedge clock放在我们的灵敏度列表中并小心地始终分配给程序块中的所有reg信号,这样可以确保得到期望的触发器。CPM电子头条

 CPM电子头条

应用CPM电子头条

 CPM电子头条

移位寄存器通常适用于需要从并行数据(通常在微处理器或其他ASIC内部使用)转换为串行数据(通常用于PCB上的组件之间或两个单独的PCB之间的通信)的情况。为此,我们通常将一个负载信号和线路添加到移位寄存器中的每个触发器输入端,以便并行数据可以一次性加载到移位寄存器中,然后逐位移出。CPM电子头条

 CPM电子头条

为了实现诸如I2C和SPI之类的串行通信协议,我们可以使用状态机来控制何时将各个数据位移出寄存器,以满足我们选择的方案的要求。我们还可以在每个触发器的输出端加上电线,这样一个设备就可以一点一点地接收串行数据,然后当所有的位都被移入时,将其并行地从移位寄存器中读出。CPM电子头条

 CPM电子头条

总结CPM电子头条

 CPM电子头条

本文讨论了如何在Verilog中实现基本移位寄存器。接下来一个典型的工作流程是编写一个测试台来实例化新的移位寄存器并驱动一些输入,这样我们就可以在模拟中验证正确的操作,然后再合成代码并将其下载到一个FPGA中进行实际硬件测试。CPM电子头条