关于verilog always用法中always块的总线与敏感列表问题

在中说明了如何使用SystemVerilog的interface来实现FPGA内部的输出数据总线功能,但仅给出了传输单个数据的方法。然而在实际应用中,我们可能会遇到需要传输多个数据的需求,此时前文给出的方案将存在一定的局限性。虽然我们可以声明多个不同的interface实例来分别传输这些数据,但总没有仅通过一个interface实例传输来得方便。

要将多个数据通过一个interface传输,我们首先想到的是SystemVerilog的struct——通过将这些待传输的数据用struct打包,便可以通过一个interface传输了。但问题也随之而来了:
1.struct不像interface那样支持参数化,对不同位宽的数据必须单独定义struct,这显然有悖于泛化编程的思想;
2.数据总线interface中定义的struct类型不能被外部模块引用,只能通过interface中定义的modport来传输给外部的目标模块,然而interface的一个modport只能传递一个struct实例,对需要使用不同struct实例的外部模块来说需求显然无法满足,即无法实现多个外部模块与interface内部不同struct实例的连接。

实际上,interface也可以实现struct的数据打包功能,而由于interface支持参数化,这也使得对打包数据的泛化编程变得可能;而且,interface支持定义modport,支持嵌入运算代码,使得其功能比struct更加强大。

因此,传输多个数据的数据总线的解决方案是:
2.外部模块以打包interface或其内定义的modport作为形参,而在外部模块实例化时,选择数据总线interface中与本模块实例对应的打包interface实例连接至本模块实例上。

(本文中所有Verilog描述仅为展示inout端口的用法,实际描述则需要更丰富的功能描述)

在芯片中为了管脚复用,很多管脚都是双向的,既可以输入也可以输出。在Verilog中即为inout型端口。Inout端口的实现是使用三态门,如FPGA中的管脚复用部分:

三态门的第三个状态是高阻态Z。在实际电路中高阻态意味着响应的管脚悬空、断开。当三态门的控制信号为真时,三态门导通;控制信号为假时,三态门的输出端是高阻态。

Verilog中的inout端口被综合为如下形式:

Inout端口是一个很容易出错的地方,理解inout端口模型必须要抓住三点:

  1. inout端口不可能独立存在;

  2. 作为输入必须有reg型缓冲(一个inout两个控制信号);

  3. 相连的两个inout端口由一对信号交错控制;

  1. inout端口不可能独立存在:

分析inout的端口特性,对于一个模块来说,inout端口既可以当做输入,又可以当做输出,那么,与inout端口相连的另一模块是什么情形呢?显然,另一模块也应该是inout端口,inout端口不可能独立存在。但是在实际编写Verilog代码的过程中,却常常忽略这一点,而仅仅是另一模块的一条输出线和一条输入线同时连接到inout端口上,乍看起来符合逻辑,实则不然。

图中的存储器Memory用RAM实现,无论CPU还是RAM都只有一组数据总线,而图中输入给Memory的有WriteData,从Memory输出的有MemData,这两组其实是一组数据总线,而实现此管脚复用功能的就是管脚复用。在用Verilog描述的过程中,只考虑CPU的数据通路结构时,就容易忽略它的双向端口的具体实现,并非如图中一般,简简单单的与RAM模块的inout端口相连。所以,一定要注意到inout端口不能独立存在,用Verilog描述上图中的CPU模块时也要描述一个inout端口及相关逻辑。

  1. 作为输入必须有reg型缓冲:

考虑到这种情况:当control信号为真时,三态门导通,这时,DataOut的输出通过双向端口传输到DataBus上。但是DataIn与DataOut直接相连,如何保证DataOut的数据不会影响到DataIn相连的电路呢?

解决这个问题的办法是把DataIn声明为reg型,而reg型的变量在always过程块中被复制,需要再增加一个控制信号,由always敏感表列监控,以此保证inout端口作为输出时不会影响DataIn。

实际用Verilog描述的过程中,常常容易忽略某一个inout端口的reg声明。以CPU和RAM为例,RAM本身作为存储器就是用reg声明的,所以不需要这个reg缓冲(前提是写RAM时一定要在always敏感表列中添加控制信号);而CPU模块的inout端口的reg声明却常常被忽略,因为这个东西看上去"画蛇添足"。这也是初学者使用inout端口时最容易犯错的地方。

  1. 相连的两个inout端口由一对信号交叉控制:

前面提到inout端口不能独立存在,进一步考虑,当一个模块的inout端口作为输出时,那么另一个模块的inout端口必然作为输入;反之,当一个模块的inout端口作为输入时,那么另一个模块的inout端口必然作为输出。因此,这两个inout端口的控制信号实际上是由一对信号交叉控制。

当ReadRAM有效时,CPU从RAM中读取数据,这时RAM的三态门导通,RAM的inout端口作为输出用,CPU的inout端口作为输入用,并且用ReadRAM信号控制CPU读取;

当WriteRAM有效时,CPU向RAM写入数据,这时CPU的三态门导通,CPU的inout端口作为输出用,RAM的inout端口作为输入用,并且用WriteRAM信号控制RAM写数据。

理解inout端口的实现,并且注意到上面三点,就可以开始用Verilog描述inout端口了。进行抽象:

1.三态门及其高阻态的实现(输出):

2.输入缓冲(输入):

下面给出真正的inout端口的应用描述,仍以上图中CPU和RAM为例(注意到RAM中没有声明reg型缓冲而CPU则显示声明reg型缓冲,以及两个模块中的一对控制信号的交叉):

//仅仅为了说明inout端口用法,真实的CPU描述远非如此

误解:用一对相反的信号控制两个inout端口实现双向传输。

造成这种误解的原因是在两个module中的inout端口中,三态门不可能同时导通,默认两个三态门总是一个导通另一个不导通,忽略了两个都不导通的情况。所以在实际电路中,用于控制两个inout端口的,必然是一对控制信号的交叉形式。

有关包含inout端口模块的单独仿真和inout端口的应用情况类似,只不过两个模块间的关系不同,需要做一下变动。

Testbench作为最顶层模块,是没有端口列表的,也就不可能为其声明一个inout端口。如前所述,inout端口不可能独立存在。这时候,虽然不能声明一个inout端口,但是可以描述一个和inout端口有相同功能的逻辑。

把inout端口拆分为两个连在一起的输入端口和输出端口,如下图所示。在testbench中,用于给实例输入的信号是reg型,从实例输出的信号被声明为wire型,而inout端口本身必须被声明为wire型。因此,需要定义一个wire型的TestOut和reg型的TestIn。Testbench的目的是为了测试模块的功能而不是跟模块交换数据,因此,在testbench中的"类inout端口"没有真正的inout端口那么多约束。唯一需要注意的是reg型的TestIn向inout被测试模块的inout端口写数据时需要有一个控制信号,这个控制信号就是被测模块内部的WriteRAM。

这样,用于测试上面的RAM模块的Verilog描述如下:

进一步考虑,testbench中的"inout端口"本身已被声明为wire类型,显然wire型的TestOut就失去了意义,可以将它们合并:wire型的inout足以显示输出信号的变化。最终的testbench模型如下:

总线上的inout端口

实际应用中最常见的应用inout端口的地方是总线,如数据总线、控制总线、地址总线,而总线绝大多数都是双向总线,挂接在总线上的部件往往很多。如果总线上只挂接了两个部件,这种情况就是前面描述的两个inout端口相连接的问题。但是总线上挂接的部件往往很多,这时候应该怎么Verilog描述呢?

其实原理是一样的,最基本的原则就是:

在同一时刻,一条总线上最多只能有一个inout端口作为输出部件。

换句话说,即是在某一时刻,一条总线上最多有一个inout端口作输出,其余的部件要么作为输入部件,要么就是高阻态。这样才能避免数字电路中一个很尴尬的问题:多驱动。

因此,在描述总线的时候,挂接在总线上的部件只要注意到上面的规则避免多驱动,即可实现所需的功能。

加载中,请稍候......

【摘要】:目前电脑横机的机头速度最高已达到1.6m/s,同时全成型编织功能日益完善,这种发展趋势对横机通信提出了更高的要求。CAN总线因技术上的局限,已难以在横机高速通信中发挥其优势。因此提出基于FPGA的电脑横机控制系统高速串行总线的实现方案,重点解决实时性、高速性和可靠性等方面的设计要求。本文主要完成了高速串行总线控制器的前端设计。 本文在对总线发展趋势和几种常用串行总线分析和研究的基础上,根据横机通信的需求提出了高速串行总线的总体架构和设计指标。详细设计了物理层协议,包括位定时、同步和编码方式等,同时规范了数据链路层协议,保证数据通信的高速性和实时性。采用自顶向下的设计方法将整个高速串行总线控制器主要划分为:寄存器模块、位时序逻辑模块、位流处理器模块、CRC校验模块、验收滤波模块和FIFO模块。在整个开发流程中,使用Altera的QuartusⅡ集成开发环境。采用Verilog HDL对上述各模块进行RTL级设计,并通过Synplify Pro进行综合。最后,构建Testbench在ModelSim环境下对几个重要模块进行布线后仿真。 仿真结果表明本文设计的高速串行总线通信方式是可行的,各模块达到了预定的功能要求。因此,基于FPGA实现高速串行总线对横机通信具有一定的参考价值。

【学位授予单位】:浙江理工大学
【学位授予年份】:2012
【分类号】:TP273


我要回帖

更多关于 verilog always用法 的文章

 

随机推荐