0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

什么是变量?

汽车电子技术 来源: OpenFPGA 作者:碎碎思 2023-02-09 14:40 次阅读


pYYBAGPklRWAPZEZAATf9QVsofo091.png

System Verilog提供两组通用的数据类型:网络和变量(nets 和 variables)。网络和变量同时具有类型和数据类型特性。类型表示信号为网络或变量,数据类型表示网络或变量的值系统,即2态或4态。为简单起见,使用术语data type来表示信号的类型和数据类型。

软件工具(如仿真器和综合编译器)使用数据类型来确定如何存储数据和处理数据上的更改。数据类型影响操作,并在RTL建模中用于指示所需的硅行为。例如,数据类型用于确定加法器应基于整数还是基于浮点,以及应执行有符号算术还是无符号算术。

网络类型和变量类型

变量用作编程的临时存储。此临时存储用于仿真。实际的硅通常不需要相同的临时存储,这取决于使用变量的编程环境。SystemVerilog有几种变量类型,将在第下节中讨论。

网络用于将设计块连接在一起,网络将数据值从源(称为驱动程序)传输到目标或接收端驱动程序。SystemVerilog提供了几种网络类型,后面会对此进行了更详细的讨论。

两态和四态数据类型(位和逻辑)

SystemVerilog变量可以是2态数据类型或4态数据类型。对于2态,变量的每一位可以具有0或1的值,对于4态,变量的每一位可以具有0、1、Z或X的值。SystemVerilog网络只能是4态数据类型。关键字位定义变量为2态数据类型。关键字逻辑定义变量或网络为4态数据类型。

变量类型

程序块指定的左侧需要变量。以下代码示例中的信号总和和输出必须是变量。

poYBAGPklQWAOQn0AADbQLSJr20500.png

变量为仿真提供临时存储。

前面代码段中的always_comb过程将执行赋值语句sum=a+b;每次a或b改变值时。必须通过仿真器存储sum的值,直到下一次a或b发生变化。类似地,always_ff过程将在时钟的每个正边缘执行if-else决策语句。out的值必须在时钟周期之间通过仿真器进行存储。

仿真器所需的临时存储并不一定意味着实际硅需要存储。前面代码片段中的always_comb过程将在硅中作为组合逻辑实现。因此,总和的值将持续反映加法器的输出,并且不需要任何类型的硬件存储。另一方面,always_ff程序将作为触发器在硅中实现,触发器是一种硬件存储设备。

可综合变量数据类型

通过同时指定类型和数据类型来声明变量。类型可以显式指定或隐式推断,关键字var。

var关键字很少在实际SystemVeriIog代码中使用。相反,var类型是从其他关键字和上下文推断出来的。

SystemVerilog有几个内置变量数据类型的关键字。这些关键字推断var逻辑(4态)或var位(2态)变量类型。几个变量数据类型表示硅的行为,并且是可综合的。表3-1列出了这些可综合的数据类型。

表3-1:可综合变量数据类型

类型 代表
reg 用户定义向量大小的通用4态变量;等价于var logic
logic 通常推断用户定义向量大小的通用var logic 4态变量,模块input/inout端口除外,在模块input/inout端口上推断wire logic
integer 32位4态状态变量;等价于var logic [ 31: 0 ]
bit 具有用户定义向量大小的通用2态var变量;如果未指定大小,则默认为1位大小
int 32位2态变量;相当于var bit[31 0];综合编译器将int视为4态integer整数类型
byte 8位2态变量;等效于var bit [ 7 : 0 ]
shortint 16位2态变量;等效于var bit [ 15: 0 ]
longint 64位2态变量;等效于var bit [ 63: 0 ]
最佳做法准则3-3
使用4态逻辑数据类型推断RTL模型中的变量。不要在RTL模型中使用2态类型。本指南的一个例外是使用int类型声明for-loop迭代中变量。

使用4态变量允许仿真器在实际硬件中的值不明确时使用X值。

上下文相关的逻辑数据类型。

在几乎所有的上下文中,logic数据类型推断出一个与reg相同的4态变量。关键字logic实际上不是变量类型,它是一种数据类型,表示网络或变量可以有4态值。但是,当logic关键字单独使用或与模块输出端口的声明结合使用时,会推断变量。当logic与input or inout端口的声明结合使用时,如果logic不推断变量,则会推断网络类型.

过时的reg数据类型

reg数据类型是原始Verilog语言遗留下来的过时数据类型。应使用logic类型而不是reg。最初的Verilog语言使用reg数据类型作为通用变量。

不幸的是,关键字reg的使用是一个误称,它似乎是“register”的缩写,寄存器是用触发器构建的硬件设备。实际上,使用reg变量与推断的硬件之间没有相关性。使用变量的上下文决定所表示的硬件是组合逻辑还是时序触发器逻辑。使用logic代替reg有助于防止这种错误观念,即硬件寄存器将被推断

X值可能表示存在设计问题

当仿真过程中出现X值时,通常表明存在设计问题。会导致X值的某些类型的设计错误包括:

  • 未复位或以其他方式初始化的寄存器。
  • 在低功耗模式下未正确保持状态的电路。
  • 未连接的模块输入端口(未连接的输入端口在高阻抗下浮动,当高阻抗值传播到其他逻辑时,通常会产生X值)。
  • 多驱动程序冲突(总线争用)。具有未知结果的操作。
  • 超出范围的位选择和数组索引
  • 建立或保持时间冲突。

在RTL模型中避免使用2态数据类型。

bit、byte、shortint、int和longint数据类型仅存储2态值。这些类型不能表示高阻抗(Z值),也不能使用X值表示未初始化或未知的仿真条件。当使用2态数据类型时,不会出现指示潜在设计错误(如上面列表中的错误)的X值。由于2态数据类型只能有一个0或1值,因此在仿真过程中出现错误的设计可能会正常运行,这是不好的!使用2态变量的合适位置是验证试验台中的随机刺激。

不可综合的变量类型

SystemVerilog有几种主要用于验证的变量类型,RTL综合编译器通常不支持这些类型。表3-2列出了这些额外的变量类型。这些数据类型没有在本系列中任何要综合的示例中使用。

表3-2:不可综合的变量数据类型

类型 代表
real 双精度浮点变量
shortreal 单精度浮点变量
time 具有timeunit和timeprecision属性的64位无符号4态变量
realtime 双精度浮点变量;与real一模一样
string 可存储8位ASCII字符字符串的字节类型的动态大小数组
event 存储仿真同步对象句柄的指针变量
class handle 存储类对象句柄的指针变量(声明类型是类的名称,而不是关键字类)
chandle 一个指针变量,用于存储从SystemVerilog直接编程接口(DPI,Direct Programming Interface)传递到仿真中的指针
virtual interface 存储接口端口句柄的指针变量(interface关键字是可选的)

上述的类型不代表在任何综合器中都不可综合,只代表了在大部分综合器中不可综合。

变量声明规则

变量是通过同时指定类型和数据类型来声明的,类型是关键字var,可以显式指定或隐式推断。

笔记
在实际的SystemVeriIog代码中很少使用var关键字。相反,var类型是从其他关键字和上下文推断出来的

一些示例变量声明:

logicv1//推断varlogic(1位4态变量)

bit v2;//推断var bit(1位2态变量)

integer

v3//推断var

integer

(32位4态变量)

intv4//推断varint(32位2态变量)

唯一需要var关键字的地方是将input 或者 inout端口声明为4态变量时。如果未显式声明为变量,则这些端口方向将默认为网络类型,输入端口很少需要是变量。

标量变量。标量变量是一个1位变量。reg, logic 和 bit数据类型默认为1位标量,

向量变量(packed arrays)。向量是连续位的数组。IEEE SystemVerilog标准将向量称为包阵列(packed arrays)。该reg, logic and bit数据类型可以表示任意大小的向量:通过在方括号中指定位的范围([]),后跟向量名称来声明向量的大小。范围声明为[最高有效位编号:最低有效位编号]。最高有效位(MSB)和最低有效位(LSB)可以是任意的数字,并且LSB可以小于或大于MSB。LSB为较小数字的向量范围称为小端点。LSB为较大数值的向量范围称为大端

logic[31:0]v9;//32位向量,小端逻辑

logic [1:32] v10;;//32位向量,大端逻辑

RTL建模中最常见的约定是小端逻辑,并使用0作为向量范围的LSB。上述变量v9说明了这一惯例。本系列中的所有例子都使用了小端逻辑约定。

byte、shortint、int、longint和integer数据类型具有预定义的向量大小,如表3-1所述。预定义范围为小端,LSB编号为位0。

有符号和无符号变量

在操作中,存储在向量变量中的值可以被视为有符号或无符号。无符号变量仅存储正值。有符号变量可以存储正值和负值。SystemVerilog使用2的补码表示负值。有符号变量的最高有效位是符号位。设置符号位时,向量的剩余位以二补形式表示负值。

默认情况下,reg、logic、bit和time数据类型是无符号变量,byte、shortint、int、integer和longint数据类型是有符号变量。可以通过将变量显式声明为有符号或无符号来更改此默认值。

poYBAGPklPGASxtWAAB2v4osmN0826.png

常量位选择和部分选择

向量可以全部或部分引用。位选择引用向量的单个位。位选择使用向量名称,后跟方括号中的位号([ ])部分选择指向量的多个连续位。部分选择使用向量名称,后跟方括号中的一系列位号([ ])

部分选择必须满足两个规则:位的范围必须是连续的,并且部分选择的endian必须与向量声明的endian相同。位选择或部分选择的结果总是无符号的,即使完整变量是有符号的。

变量位选择和部分选择。前面代码段中的位选择使用了硬编码位号。这称为固定位选择。位选择的索引号也可以是变量。比如说。

pYYBAGPklOKAFaObAAB2bZH4TOk180.png

pYYBAGPklNSAILOXAAE3GHdSpTE913.png

零位选择的起点也可以是可变的。零位选择可以从变量起点递增或递减。选择的总位数为固定范围,可变部分选择的形式为:

pYYBAGPklL6ALVclAACv3kh9cKo002.png

第二个问题:标记指示从起始点位号开始递增。标记指示从起始点位号开始递减。

下面的示例使用可变部分选择来迭代32位向量的字节。

poYBAGPklLKAFOZzAADz3FO0yZs916.png

可变位和部分选择是可综合的。但是,前面说明变量位和部分选择的代码段不满足某些综合编译器所需的其他RTL编码限制。

带有子字段的向量。通过使用两组或多组方括号来定义向量范围,可以使用子字段声明向量。下面的代码片段显示了简单32位向量和带有子字段的32位向量之间的区别:

poYBAGPklJ6AKrz1AAB78sBgqLo571.png

图3-1说明了这两种声明的区别。

poYBAGPklI-AD_8tAAHZmn1rVKk300.png

图3-1:带有子字段的向量

声明:

pYYBAGPklGCAC7H2AABRw0Jb8oU979.png

第一个范围[3 :0]定义向量中有多少子字段。在本例中,有四个子字段,索引为 b [ 0 ],b [ l ],b [ 2 ],和 b[3]。第二个范围[7:0]定义了每个子字段的大小,在本例中为8位。图3-1说明了简单32位向量和细分为4字节的32位向量的布局。

细分向量的子字段可以使用单个索引而不是部分选择来引用。下面的代码片段演示了在向量b的字节之间循环,并且更简单,因为每个字节都是向量的一个子字段。

poYBAGPklFKATskNAADPjWuqfrM944.png

细分向量的位选择需要多个索引-选择向量b第三字节的位7编码为:b[3][7]

最佳做法准则3-4
当设计主要选择整个向量或向量的单个位时,使用简单的向量声明;当设计经常选择向量的部分时,使用带有子字段的向量,并且这些部分位于已知边界上,例如字节或字边界。

选择向量的子字段而不是使用简单向量的固定部分或可变部分,可以使代码更易于编写和维护。

变量分配规则

变量可以通过多种方式赋值:

  • 作为过程赋值语句的左侧(在always、always_comb、always_latch、always_ff或初始过程块中,或在任务或函数中)。
  • 作为连续赋值语句的左侧(使用assign语句)。
  • 作为赋值运算符的结果,例如++增量运算符。
  • 作为模块、任务或功能的输入。
  • 作为模块实例、任务实例、功能实例或原语实例的输出端口的连接。

变量只能由单个源分配。例如,如果变量从assign 连续赋值语句中,则在程序块或模块输入端口中也为变量赋值是非法的。但是,对同一变量的任何数量的程序赋值都被视为一个源。要使以下代码正常工作,此规则非常重要:

pYYBAGPklEeAANuTAACsVmTPc1w334.png

在RTL建模中,单个源变量赋值的语义限制非常重要,该限制有助于确保抽象RTL仿真行为和综合后实现行为相同

always_ff,always_comb and always_latch程序块进一步将对变量的程序赋值限制为仅在一个程序内,这强制了综合编译器的要求。同一过程中变量的多个赋值被视为单个驱动程序。

poYBAGPklC6ANcvXAAIcQ27cSS0227.png

未初始化变量

在为变量指定值之前,变量未初始化。4态变量的未初始化值为X(所有位均设置为x)。2态变量的未初始化值为“0”(所有位均设置为0)。

在下面的示例中,直到clk的第一个正边缘出现,变量q才被初始化。作为一种4态逻辑类型,在第一个时钟之前,q将有一个X值,此时q将被指定为0值或d值。如果clk的正边缘没有出现,该X值可能表示设计问题,可能是由于时钟选通或其他一些情况。

poYBAGPklCOAHOTDAACtC3werrI451.png
笔记
未初始化的2态变量可以隐藏设计问题。未初始化的2态变量的值为0,这可能是一个合法的复位值。这可能会隐藏设计中复位逻辑的问题。

在线变量初始化

SystemVerilog允许在声明变量时初始化变量,称为在线初始化。例如:

pYYBAGPklBeAJ2ZqAAARW3DIiKs450.png

在仿真开始时,变量的在线初始化只执行一次.

一些FPGA设备可以编程,使寄存器在已知状态下通电,而无需复位。在线变量初始化可用于仿真这些时序设备(如触发器)的通电状态。

笔记
ASIC技术不支持在线变量初始化,某些FPGA技术可能支持在线变量初始化。

当针对不支持可编程通电状态的设备时,综合编译器将:(a)不允许在线初始化,(b)忽略它-当忽略在线初始化时,RTL仿真行为和综合门级实现可能不匹配,

最佳做法准则3-5
仅在将作为FPGA实现的RTL模型中使用变量初始化,并且仅对触发器的加电时建模。

对于ASIC设计,应使用复位功能来初始化变量。不要使用在线初始化。对于FPGA设计,只有在确定RTL模型始终针对支持加电寄存器状态的设备时,才使用在线初始化。在RTL模型中使用在线初始化有效地将模型锁定为仅用于该类型FPGA设备。

最佳做法准则3-6
仅在RTL模型中使用内嵌变量初始化。不要使用初始过程初始化变量。

支持在线变量初始化的综合编译器和目标FPGA设备也允许使用初始过程对触发器的通电值进行建模。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Verilog
    +关注

    关注

    28

    文章

    1326

    浏览量

    109302
  • System
    +关注

    关注

    0

    文章

    161

    浏览量

    36571
  • 变量
    +关注

    关注

    0

    文章

    595

    浏览量

    28112
收藏 人收藏

    评论

    相关推荐

    全局变量和局部变量有什么区别

    全局变量是编程术语中的一种,源自于变量之分。变量分为局部与全局,局部变量又可称之为内部变量。局部变量
    发表于 12-11 11:58 3.2w次阅读
    全局<b class='flag-5'>变量</b>和局部<b class='flag-5'>变量</b>有什么区别

    全局变量和成员变量的区别分析

    成员变量是指定维度的成员变量,用于标识某个维度成员。简介由 Analysis Services 内部使用的值,以标识某个维度成员。MemberKeyColumn 属性指定维度的成员变量。例如,1到12之间的某个数字可以是相应于年
    发表于 12-11 13:50 6730次阅读
    全局<b class='flag-5'>变量</b>和成员<b class='flag-5'>变量</b>的区别分析

    全局变量和成员变量的区别分析

    成员变量是指定维度的成员变量,用于标识某个维度成员。简介由 Analysis Services 内部使用的值,以标识某个维度成员。MemberKeyColumn 属性指定维度的成员变量。例如,1到12之间的某个数字可以是相应于年
    发表于 12-11 13:50 1147次阅读
    全局<b class='flag-5'>变量</b>和成员<b class='flag-5'>变量</b>的区别分析

    静态变量、自动变量与寄存器变量的存储

    register限定词通知编译器--程序中的变量将频繁使用。它的意思是建议编译器将程序中用register限定的变量放置在计算机的内部寄存其中,这样可能得到更小更快的程序。但是,编译器将根据实际情况考虑是否采纳该建议--是否将register
    发表于 06-03 11:27 2638次阅读
    静态<b class='flag-5'>变量</b>、自动<b class='flag-5'>变量</b>与寄存器<b class='flag-5'>变量</b>的存储

    什么是PLC变量

    什么是变量变量是用于程序的,可以有不同值的变量。 根据应用范围,变量可分为以下几类 局部变量: 局部
    的头像 发表于 10-11 11:53 1.6w次阅读
    什么是PLC<b class='flag-5'>变量</b>

    西门子PLC变量表中定义变量

    什么是变量变量是用于程序的,可以有不同值的变量。  根据应用范围,变量可分为以下几类 ●  局部变量:  局部
    的头像 发表于 12-23 16:25 1.8w次阅读
    西门子PLC<b class='flag-5'>变量</b>表中定义<b class='flag-5'>变量</b>

    Static变量和Local变量的区别

    变量可以分为3类,即Static、Automatic、和Local。如下表所示。
    的头像 发表于 10-12 09:35 1005次阅读

    C语言的变量-1

    变量,顾名思义就是可以变化的量。在C语言中,提供了很多变量类型,这些变量类型可以用来表示不同数据类型的数据。为了区分不同的变量,我们需要给变量
    的头像 发表于 02-21 15:04 511次阅读
    C语言的<b class='flag-5'>变量</b>-1

    C语言的变量-2

    在C语言中,我们可以将字符也作为变量,存储字符的变量类型就称为字符型变量
    的头像 发表于 02-21 15:06 403次阅读
    C语言的<b class='flag-5'>变量</b>-2

    变量的存储

    在编写C程序的过程中,我们常常会使用到变量。而基本的变量类型在前面的教程也已经讲到,在我们创建这些变量的时候,变量会被创建在内存。值得注意的是,变量
    的头像 发表于 02-21 15:07 513次阅读
    <b class='flag-5'>变量</b>的存储

    C语言全局变量与局部变量

    在一个函数内部定义的变量只在本函数范围内有效,也就是说只有在本函数内才能引用它们,在此函数以外是不能使用这些变量的。 在复合语句内定义的变量只在复合语句范围内有效,只有在本复合语句内才能引用它们。在复合语句以外是不能使用这
    的头像 发表于 03-10 14:33 676次阅读

    Bash脚本中特殊变量$0是什么?

    在 Bash 脚本中,`$0` 是一个特殊变量,它代表当前脚本的路径和名称。这个变量用于表示脚本自身,它是 Bash 环境中的一个重要组成部分。`$0` 变量是一个只读变量,无法更改。
    的头像 发表于 05-12 14:41 1515次阅读

    Java变量的命名规范

    什么是变量变量就是初中数学的代数的概念,例如一个简单的方程,x,y都是变量: y=x^2+1 在Java程序设计中,变量是指一个包含值的存储地址以及对应的符号名称。 从定义上来看,
    的头像 发表于 10-10 11:49 417次阅读

    什么是变量?PLC变量哪些部分组成?

    变量在 TIA Portal 中集中管理。 在程序编辑器中创建 PLC 变量与在 PLC 变量表中创建 PLC 变量没什么区别。 如果在程序或 HMI 画面的多个位置使用某个
    发表于 10-15 11:31 2022次阅读
    什么是<b class='flag-5'>变量</b>?PLC<b class='flag-5'>变量</b>哪些部分组成?

    for循环里的变量是局部变量

    对于一个普通for循环而言,循环变量是局部变量。在大多数编程语言中,循环变量只在循环内部的作用域中可见。换句话说,循环变量的声明和赋值仅在循环的每次迭代中有效,并且不能在循环外部访问或
    的头像 发表于 11-23 14:50 1000次阅读