FPGA 入门 —— 信号类型与功能描述
FPGA 入门 —— 信号类型
信号类型
数据类型主要包括两种,线网类型(net tye)和寄存器类型(reg type),在进行工程设计的时候也只会使用到这两种类型的信号
信号位宽
定义信号类型的同时,必须定义好信号的位宽,默认信号位宽时一位(如果我们没有定义信号位宽即没有描述,那就是一位)
信号位宽取决于要改信号表示的最大值,该信号能表示的无符号最大值时:$ 2^n-1 $,其中 n 表示该信号的位宽
举例:
wire a; //表示位宽为 1 的信号类型
wire [7:0] a; //表示位宽为 8 的信号类型
线网类型 wire
线网类型用于对结构化器件之间的物理连线的建模,由于现网类型代表的是物理连接线,因此其不存储逻辑值,必须由器件驱动。通常用 assign 进行赋值
wire 类型定义语法如下:
wire [msb: lsb] wire1, wire2 , …… , wiren
-
msb、lsb 定义了范围,表示了位宽,必须为常数值,例如 [7:0] 是 8 位位宽,也就可以表示成 8'b0 至 8'b1111_1111
-
如果没有定义范围,缺省值为 1
-
如果没有定义信号类型时,缺省为 wire 类型
-
数组按照降序方式进行定义,例如:[7:0] ,不要写成 [0:7]
寄存器类型 reg
reg 是最常用的寄存器类型,寄存器类型通常用于对存储单元的描述,寄存器类型信号的特点是在某种触发机制下分配了一个值,在下一触发机制到来之前保留原值,但必须注意的是:reg 类型的变量不一定是存储单元,如在 always 语句中进行描述的必须是用 reg 类型的变量
reg 类型定义如下:
reg [msb: lsb] reg1, reg2, …… , regn
-
msb、lsb 定义了范围,表示了位宽,必须为常数值,例如 [7:0] 是 8 位位宽,也就可以表示成 8'b0 至 8'b1111_1111
-
如果没有定义范围,缺省值为 1
-
如果没有定义信号类型时,缺省为 wire 类型,不是 reg 类型
-
数组按照降序方式进行定义,例如:[7:0] ,不要写成 [0:7]
对比 wire 与 reg
从仿真分析角度来说
wire 对应于连续赋值,如 assign
reg 对应于过程赋值,如 always,initial
-
wire 型数据常用来表示以 assign 关键字指定的组合逻辑信号,模块的输入输出端口类型都默认为 wire 型,wire 相当于物理连线,默认初始值是 z,reg 型数据表示寄存器模型,用于 always 块、initial 语句中被赋值的变量
-
wire 使用在连续赋值语句中,reg 用在过程赋值语句(always、initial)中
-
wire 若无驱动器连接其值为z,reg 默认初始值为不定值 x
-
wire 表示直通,即输入有变化,输出马上无条件地反映(如与、非门的简单连接),reg 表示一定要有触发,输出才会反映输入的状态
-
wire 一般用在组合逻辑中,reg 一般用在时序逻辑中
-
reg 变量在 always 中有两种情况:
-
always @(a or b or c)形式的,即不带时钟边沿的,综合出来还是组合逻辑;
-
always @(posedge clk)形式的,即带有边沿的,综合出来一般是时序逻辑,会包含触发器(Flip-Flop)
- always 块不止能实现时序逻辑,还能实现组合逻辑:
-
如果这个条件是时钟上升沿或下降沿,那硬件模型就是一个触发器,只有是指定了 always@(posedge or negedge)才是触发器
-
如果这个条件是某一信号的高低电平,那这个硬件模型就是一个锁存器
-
如果这个条件是赋值语句右侧任意操作数的变化,那这个硬件模型就是一个组合逻辑
-
对组合逻辑输出变量,可以直接用 assign。即如果不指定为 reg 类型,那么就默认为 1 位 wire 类型,故无需指定 1 位 wire 类型的变量。当然专门指定出 wire 类型,可能是多位或为使程序易读
-
reg 型数据保持最后一次的赋值,而 wire 型数据需要持续的驱动
在连续赋值语句 assign 中,表达式右侧的计算结果可以立即更新到表达式的左侧,可以理解为逻辑之后直接连接了一条线,这个逻辑对应于表达式的右侧,这条线对应于 wire
在过程赋值语句中,表达式右侧的计算结果在某种条件的触发下放到一个变量当中,这个变量可以声明成 reg 型
- reg和wire类似于C、C++的变量,但若此变量要放在begin...end之内,则该变量只能是reg型;在begin...end之外,则用wire型
什么时候使用 reg 或 wire ?
-
assign 语句中变量需要定义成 wire 型,使用 wire 必须搭配 assign
-
元件例化时候的输出必须用 wire
-
input、output 和 inout 的预设值都是 wire
-
变量放在 begin……end 之内必须使用 reg 变量
-
在 initial 语句中使用
reg 类型信号并不一定生成寄存器,针对什么时候用 wire 类型,什么时候用 reg 类型这一问题,这里给出一个简单的解决方法:
always 中设计的信号都定义为 reg 类型,其他信号都定义为 wire 类型
注意:这个方法只适合与 FPGA 入门的新手,当我们需要更加复杂的信号的时候,我们就需要进一步判读我们所需要的信号类型,这个方法就不奏效了