Verilog 数据类型

17 Mar 2025 | 5 分钟阅读

Verilog 引入了几个新的数据类型。这些数据类型使 RTL 描述更易于编写和理解。

Verilog 硬件描述语言 (HDL) 的一组数据类型用于表示数字硬件中存在的存储和传输元素。

Verilog 中,数据类型分为NETS(网络)和Registers(寄存器)。这些数据类型在赋值和保存值的方式上有所不同,它们也代表不同的硬件结构。

Verilog HDL 值集由四种基本值组成:

描述
0逻辑零或假
1逻辑一或真
X未知逻辑值
Z三态门的髙阻抗

整数和实数数据类型

许多数据类型对于 C 程序员来说将是熟悉的。其思想是,如果两种语言具有相同的数据类型,则可以在 Verilog 中转换在 C 中建模的算法。

Verilog 引入了新的两态数据类型,其中每比特仅为 0 或 1。在 RTL 模型中使用两态变量可以提高模拟器的效率。并且它们不会影响综合结果。

类型描述
bit用户定义的尺寸
byte8 位,有符号
shortint16 位,有符号
int32 位,有符号
longint64 位,有符号
  • 两态整数类型

与 C 不同,Verilog 为固定宽度类型指定了位数。

类型描述
reg用户定义的尺寸
logic在所有方面都与 reg 相同
整数32 位,有符号
  • 四态整数类型

我们更喜欢 logic,因为它比 reg 更好。我们可以在使用 reg 或 wire 的地方使用 logic。

类型描述
time64 位无符号
shortreal类似于 C 中的 float
shortreal类似于 C 中的 double
realtime与 real 相同

非整数数据类型

数组

在 Verilog 中,我们可以定义标量和向量网络变量。我们还可以定义内存数组,它们是变量类型的一维数组。

Verilog 允许使用多维数组的网络和变量,并消除了对内存数组使用的一些限制。

Verilog 将此向前推进了一步,并改进了数组的概念,允许对数组进行更多操作。

在 Verilog 中,数组可以具有打包解包维度,或两者兼有。

打包维度

  • 保证在内存中连续布局。
  • 可以复制到任何其他打包对象。
  • 可以切片(“部分选择”)。
  • 仅限于“比特”类型(bit、logic、int 等),其中一些(例如 int)具有固定大小。

解包维度

内存布局方式可以由模拟器自由选择。我们可以可靠地将一个数组复制到另一个相同类型的数组。

对于不同类型的数组,我们必须使用强制类型转换,并且存在如何将解包类型转换为打包类型的规则。

Verilog 允许对完整的解包数组和解包数组的切片进行多种操作。

对于这些操作,涉及的数组或切片必须具有相同的类型和形状,即解包维度的数量和长度相同。

只要数组或切片元素具有相同的位数,打包维度就可以不同。允许的操作是:

  • 读取和写入整个数组。
  • 读取和写入数组切片。
  • 读取和写入数组元素。
  • 数组、切片和元素的相等关系。

Verilog 还包括动态数组(元素数量在模拟期间可能会更改)和关联数组(具有非连续范围)。

Verilog 包括几种数组查询函数和方法来支持所有这些数组类型。

网络 (Nets)

网络用于连接逻辑门等硬件实体,因此不存储任何值。

网络变量代表逻辑门等结构化实体之间的物理连接。这些变量除了 trireg 外不存储值。这些变量具有驱动器的值,该值由驱动电路连续变化。

一些网络数据类型包括 wire、tri、wor、trior、wand、triand、tri0、tri1、supply0、supply1trireg。当信号是以下情况时,必须使用网络数据类型:

  • 由某些设备的输出驱动。
  • 声明为输入或双向端口。
  • 在连续赋值语句的左侧。

1. Wire (导线)
wire 代表电路中的物理导线,用于连接门或模块。在函数或块中,可以读取 wire 的值,但不能对其进行赋值。

wire 不存储其值,但必须由连续赋值语句驱动,或通过将其连接到门或模块的输出来驱动。

2. Wand (有线与)
wand 的值取决于连接到它的所有驱动器的逻辑 AND。

3. Wor (有线或)
wor 的值取决于连接到它的所有驱动器的逻辑 OR。

4. Tri (三态)
连接到 tri 的所有驱动器都必须是 z,除了一个决定 tri 值的驱动器。

5. Supply0 和 Supply1
Supply0 和 supply1 定义连接到逻辑 0(地)和逻辑 1(电源)的导线。

寄存器

寄存器是数据对象,它从一个过程赋值保存其值到下一个。它们仅在函数和过程块中使用。

过程中的赋值语句充当改变数据存储元素值的触发器。

Reg 是 Verilog 变量类型,不一定表示物理寄存器。在多位寄存器中,数据存储为无符号数,并且不会对用户可能认为的二补数进行符号扩展。

一些寄存器数据类型是 reg、integer、time 和 realreg 是最常用的类型。

  • Reg 用于描述逻辑。
  • Integer 是通用变量。它们主要用于循环索引、参数和常量。它们将数据存储为有符号数,而显式声明的 reg 类型则将其存储为无符号数。如果它们保存的数字不是在编译时定义的,则它们的默认大小将是 32 位。如果它们保存常量,则综合器会在编译时将其调整为所需的最小宽度。
  • Real 在 system 模块中使用。
  • Timerealtime 用于在测试平台中存储仿真时间。Time 是一个 64 位量,可与 $time 系统任务结合使用以保存仿真时间。

注意:reg 不一定总是表示一个触发器,因为它也可以表示组合逻辑。

  • Reg 变量在仿真开始时初始化为 x。任何未连接的 wire 变量都具有 x 值。
  • 寄存器或 wire 的大小可以在声明期间指定。
  • 当 reg 或 wire 的大小大于一位时,则寄存器和 wire 被声明为向量。

Verilog 字符串

字符串存储在 reg 中,并且 reg 变量的宽度必须足够大才能容纳该字符串。

字符串中的每个字符代表一个 ASCII 值,需要 1 字节。如果变量的大小小于字符串,则 Verilog 会截断字符串的最左侧比特。如果变量的大小大于字符串,则 Verilog 会在字符串的左侧添加零。


下一个主题行为建模和时序