在写FPGA代码进行参数类型定义时,对于写reg还是wire常常叫人迷惑,下面我将分为以下三种情况,详细解释如何定义参数类型
目录
一 、输入输出定义
输入输出定义是指,在写程序的时候,向各个程序模块里面输入和输出某些参数,例如下面的流水灯程序,PLL,time,water_led三个模块分别有不同的输入输出
针对这种情况应该这样定义
input 都为wire型;
output 若在always块下定义为reg型,写作output reg xxxxx
(不加reg默认wire,不用写output wire xxxx)
(原因:在设计中,输入信号一般来说你是不知道上一级是寄存器输出还是组合逻辑输出,那么对于本级来说就是一根导线,也就是wire型。而输出信号则由你自己来决定是寄存器输出还是组合逻辑输出,wire型、reg型都可以。always块下面进行赋值时,参数相当于被寄存器寄存,所以需要写reg型)
二 、例化定义
这种情况是指,top层汇总各个模块时进行的例化,如上面的图就是system上需要例化PLL,time,water_led三个模块
针对这种情况应该这样定义:
首先top层的输入和输出依然按照上面的定义方法写
把不包含在输入输出里的参数(如上面的图就是clk_25m,locked,time_en)挑出来,写wire型
(原因:例化时,可以把里面的参数都当做信号线,只有连接作用)
三 、 仿真定义
这种情况是指在写TB文件的时候进行参数定义
首先说一下写TB文件的过程,TB文件可以测试小模块也可以测试top层,比如我要测试time模块,那么我就需要把time模块的输入输出复制到TB文件里面,也就是module后面的(....);
复制过去按照例化的步骤进行例化
先将模块里面为input的变量写reg型,为output的变量写wire型
(注意不要忘写位宽,reg[ x:x] wire[ x:x])
但是有些时候会报错,所以按照上面的方法写完之后需要进行一些检测修改:
TB文件里面的参数在initial进行赋值的写reg型,其他的写wire型
然后就没有问题了
输入输出定义,例化定义,仿真定义已经几乎包含了FPGA里面所有的参数定义情况,按照我上面的方法定义不会有问题,下面来介绍一下原理:
Verilog 中变量的物理数据分为线型和寄存器型,线型数据包括wire,wand,wor等几种类型,其中wire最常用,对应于实际的数字电路,线型wire实际上就对应着硬件的连线,起到连接作用。寄存器是存储单元的抽象,寄存器数据类型的关键字是reg。常用来表示always模块内的指定信号,代表触发器。在always模块内被赋值的每一个信号都必须定义成reg型。
所以reg相当于存储单元,wire相当于物理连线
在需要赋值计算的时候就用reg,只是连接作用就用wire