当前位置: 首页 > news >正文

【SystemVerilog 2023 Std】第5章 词法约定 Lexical conventions (1)

参考资料:IEEE Std 1800-2023标准《IEEE Standard for SystemVerilog — Unified Hardware Design, Specification, and Verification Language》

文章目录

  • 5.1 General
  • 5.2 Lexical tokens
  • 5.3 White space
  • 5.4 Comments
  • 5.5 Operators
  • 5.6 Identifiers, keywords, and system names
    • 5.6.1 Escaped identifiers
    • 5.6.2 Keywords
    • 5.6.3 System tasks and system functions
    • 5.6.4 Compiler directives
  • 5.7 Numbers
    • 5.7.1 Integer literal constants
    • 5.7.2 Real literal constants

5.1 General

本章阐述以下内容:
— 词法单元(白空格、注释、运算符)
— 整型、实型、字符串、数组、结构体和时间字面量
— 内置方法调用
— 属性(attribute)

5.2 Lexical tokens

SystemVerilog 源文本文件应为词法 token 流。每个词法 token 由一个或多个字符构成。源文件中词法 token 的布局应为自由格式;即空格和换行符除作为词法 token 分隔符的作用外,语法上无实际意义(转义标识符除外)(见 5.6.1 节)。

SystemVerilog 的词法 token 类型如下:
— 空白符(White space)
— 注释(Comment)
— 运算符(Operator)
— 数字(Number)
— 字符串字面量(String literal)
— 标识符(Identifier)
— 关键字(Keyword)

5.3 White space

空白符应包含空格、制表符、换行符、换页符和文件结束符的字符。除了用作分隔其他词法单元的情况外,这些字符将被忽略。然而,在字符串字面量中,空格和制表符应被视为有效字符(见第 5.9 节)。

5.4 Comments

SystemVerilog 共有两种注释形式。单行注释应以两个字符 // 开始,并以换行符结束。块注释应以 /* 开始,并以 */ 结束。块注释不可嵌套。单行注释标记 // 在块注释内部无特殊含义,块注释标记 /**/ 在单行注释内部也无特殊含义。

5.5 Operators

操作符可以是单个、两个或三个字符组成的序列,并在表达式中使用。第 11 章讨论了操作符在表达式中的用法。

一元操作符(unary operator)应出现在其操作数左侧。二元操作符(binary operator)应出现在其操作数之间。条件操作符(conditional operator)包含两个操作符字符,用于分隔三个操作数。

5.6 Identifiers, keywords, and system names

标识符(identifier)用于赋予对象唯一名称,以便被引用。标识符可以是简单标识符或转义标识符(见 5.6.1 节)。简单标识符(simple identifier)应由字母、数字、美元符号($)和下划线(_
组成的任意序列构成。关键字(keyword)(见 5.6.2 节)不得用作用户定义的标识符。

简单标识符的首字符不得为数字或 $;它必须是字母或下划线。标识符应区分大小写。

例如:

shiftreg_a
busa_index
error_condition
merge_ab
_bus3
n$657

工具实现可设置标识符的最大长度限制,但该限制应至少为 1024 个字符。若标识符超出实现特定的长度限制,则须报告错误。

5.6.1 Escaped identifiers

转义标识符应以反斜杠字符(\)开始,并以空白符结束。它们提供了一种在标识符中包含除空白符外的任意可打印 ASCII 字符的方法。

开头的反斜杠字符和结尾的空白符都不被视为标识符的一部分。因此,转义标识符 \cpu3会被视为与非转义标识符 cpu3 相同。但转义关键字是个例外。转义关键字被视为用户定义的标识符。

例如:

\busa+index
\-clock
\***error-condition***
\net1/\net2
\{a,b}
\a*(b+c)
\net // "net" is a keyword. "\net " is a user-defined identifier.

5.6.2 Keywords

关键字是预定义的非转义标识符,用于定义语言结构。若 SystemVerilog 关键字前置转义符(反斜杠),则不被解析为关键字。

所有关键字均以纯小写形式定义。附录 B 列出了所有已定义的关键字。第 22.14 节讨论了保留关键字与先前版本的 IEEE Std 1364 和 IEEE Std 1800 标准的兼容性。

5.6.3 System tasks and system functions

美元符号($)引入了一种语言结构,支持开发用户自定义的系统任务和系统函数。系统结构并非设计语义,而是指向仿真器功能。$ 后跟随的名称会被解析为系统任务或系统函数。

系统任务和系统功能的语法请参见以下语法。

system_tf_call ::=system_tf_identifier [ (  list_of_arguments ) ]| system_tf_identifier ( data_type [ , expression ] )| system_tf_identifier ( expression { , [ expression ] } [ , [ clocking_event ] ] )system_tf_identifier ::= $[ a-zA-Z0-9_$ ]{ [ a-zA-Z0-9_$ ] }注:system_tf_identifier中的$字符不能后跟空格。system_tf_identifier不能被转义。

本文档定义了 SystemVerilog 的一套标准系统任务和系统函数(见第 20 章和第 21 章)。与 SystemVerilog 普通任务不同(见 13.3 节),这些标准系统任务不消耗仿真时间,并且可在 void 函数适用的位置使用(见 13.4 节)。

可使用 PLI 定义额外的用户自定义系统任务和系统函数,如第 36 章所述。软件实现也可指定额外的系统任务和系统函数,这些功能可能是工具特定的(常见附加系统任务和系统函数见附录 D)。额外的系统任务和系统函数不属于本标准范畴。

例如:

$display ("display a message");
$finish;

5.6.4 Compiler directives

'字符(ASCII 值为 0x60,称为重音符)引入了一种用于实现编译器指令的语言构造。编译器依照指令要求的行为应在编译器读取指令后立即生效。该指令将持续作用于当前编译单元的剩余部分(见 3.12.1 节),除非遇到其他编译器指令更改其设定。因此,一个描述文件中的编译器指令可控制多个描述文件的编译行为。但编译器指令不得影响其他编译单元。

例如:

`define wordsize

本文档定义了 SystemVerilog 的一套标准编译器指令(见第 22 条)。软件实现也可指定额外的编译器指令,这些指令可能是工具特定的(常见附加编译器指令见附录 E)。额外的编译器指令不属于本标准范畴。

5.7 Numbers

常量数字可指定为整数常量(见 5.7.1 节)或实数常量(见 5.7.2 节)。数字的形式语法如下。

primary_literal ::= number | time_literal | unbased_unsized_literal | string_literal
time_literal ::=unsigned_number time_unit| fixed_point_number time_unit
time_unit ::= s | ms | us | ns | ps | fs
number ::= integral_number| real_number
integral_number ::=decimal_number| octal_number| binary_number| hex_number
decimal_number ::=unsigned_number| [ size ] decimal_base unsigned_number| [ size ] decimal_base x_digit { _ }| [ size ] decimal_base z_digit { _ }
binary_number ::= [ size ] binary_base binary_value
octal_number ::= [ size ] octal_base octal_value
hex_number ::= [ size ] hex_base hex_value
sign ::= + | -
size ::= unsigned_number
real_number ::=fixed_point_number| unsigned_number [ . unsigned_number ] exp [ sign ] unsigned_number
fixed_point_number ::= unsigned_number . unsigned_number
exp ::= e | E
unsigned_number ::= decimal_digit { _ | decimal_digit }
binary_value ::= binary_digit { _ | binary_digit }
octal_value ::= octal_digit { _ | octal_digit }
hex_value ::= hex_digit { _ | hex_digit }
decimal_base ::= '[s|S]d | '[s|S]D
binary_base ::= '[s|S]b | '[s|S]B
octal_base ::= '[s|S]o | '[s|S]O
hex_base ::= '[s|S]h | '[s|S]H
decimal_digit ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
binary_digit ::= x_digit | z_digit | 0 | 1
octal_digit ::= x_digit | z_digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
hex_digit ::= x_digit | z_digit | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | A | B | C | D | E | F
x_digit ::= x | X
z_digit ::= z | Z | ?
unbased_unsized_literal ::= '0 | '1 | 'z_or_x 注:time_literal中的无符号数或定点数不能后跟white_space。unbased_unsized_literal中的撇号(')不能后跟white_space。

5.7.1 Integer literal constants

整型常量可以用十进制、十六进制、八进制或二进制格式指定。

有两种形式表示整型文字常量。第一种形式是简单十进制数,它应由数字 0 到 9 组成的序列表示,可选择以一元运算符加号或减号开头。第二种形式指定基于进制的文字常量,它应由最多三个标记组成 —— 一个可选的位宽常量、后跟基本格式字符的撇号字符(', ASCII 0x27)、以及表示该数值的数字。宏替换这三个标记应是合法的。

第一个标记 —— 位宽常量 —— 应以精确的位数指定整型文字常量的大小。它必须被指定为一个非零的无符号十进制数。例如,两个十六进制数字的位宽规范为 8,因为一个十六进制数字需要 4 位。

第二个标记—— 进制格式 ——应由一个指定数字基数的字母组成,可选择性地在前面加上单个字符 s(或 S)表示有符号量,且整个标记前需加撇号字符。合法的进制规范分别为 dD(十进制)、hH(十六进制)、oO(八进制)、以及 bB(二进制)。

撇号字符与进制格式字符之间不得被任何空白符分隔。

第三个标记—— 无符号数 ——应由符合指定进制格式的合法数字组成。无符号数标记必须紧跟在进制格式之后,前面可以有可选的空白符。十六进制数字 a 到 f 不区分大小写。

没有指定位宽和进制格式的简单十进制数应被视为有符号整数,而使用进制格式指定的数字,如果包含 s 标志则被视为有符号整数,如果仅使用进制格式(不带s)则被视为无符号整数。s 标志不影响指定的位模式,仅影响其解释方式。

出现在位宽常量之前的加号或减号是一元加号或减号运算符。在进制格式和数字之间出现加号或减号是非法的语法。

负数应以二进制补码形式表示。

在十六进制、八进制和二进制文字常量中,x 表示未知值,z 表示高阻值。有关 SystemVerilog 值集的讨论请参见第 6.3 节。
在十六进制中,一个 x 会将 4 位设置为未知值;在八进制中,会将 3 位设置为未知值;在二进制中,会将 1 位设置为未知值。类似地,一个 z 会分别在十六进制中设置 4 位、八进制中设置 3 位、二进制中设置 1 位为高阻值。

如果无符号数的位宽小于为文字常量指定的位宽,则应在该无符号数的左侧用零填充。如果无符号数的最左边位是 xz,则应分别使用 x 或 z 向左侧填充。如果无符号数的位宽大于为文字常量指定的位宽,则无符号数应从左侧截断。

无位宽数值(指简单十进制数或带有进制说明符但未指定位宽的数值)的位宽应至少为 32 位。若一个无位宽数值的实际需求超过 32 位,则其位宽至少应为能正确表示该值的最小宽度,若该数值是有符号数还需包含符号位。
例如:'h7_0000_0000(一个无符号十六进制数)应至少分配 35 位。4294967296(2³²,一个有符号正整数)应至少用 34 位表示。

对于高位为未知值(Xx)或高阻态(Zz)的无位宽无符号文字常量,其位宽应扩展至包含该文字常量的表达式所需的位宽。

可以通过在单比特数值前加撇号(')(但不带进制说明符)来指定无位宽无符号单比特值。该无位宽值的所有位都将被设置为指定比特的值。在自确定上下文中,其位宽应为 1 比特。

'0, '1, 'X, 'x, 'Z, 'z // sets all bits to specified value

在定义数值时使用 xz 是不区分大小写的。

在数字中使用时,问号(?)字符是 SystemVerilog 中 z 字符的替代符号。在十六进制数中,它会将 4 位设置为高阻值;在八进制数中,设置为 3 位;在二进制中(in binary),设置为 1 位。当高阻值表示无关条件时,问号可用于提高可读性。有关 casez 和 casex 的讨论请参见 12.5.1 节。问号字符也用于用户定义原语(UDP)状态表中。请参见 29.3.6 节。

在十进制文字常量中,无符号数字标记不得包含任何 xz? 数字,除非该标记中仅有一个数字,此时表示该十进制文字常量的所有位均为 xz

下划线字符(_)在数字中除首字符外的任何位置均合法。下划线字符将被忽略。此特性可用于分隔长数字以增强可读性。


以下是几个例子:

示例1:无位宽文字常量数值

659       // is a decimal number
'h 837FF  // is a hexadecimal number
'o7460    // is an octal number
4af       // is illegal (hexadecimal format requires 'h)

示例2:有位宽文字常量数值

4'b1001   // is a 4-bit binary number
5 'D 3    // is a 5-bit decimal number
3'b01x    // is a 3-bit number with the least// significant bit unknown
12'hx     // is a 12-bit unknown number
16'hz     // is a 16-bit high-impedance number

示例3:在文字常量数值中使用符号

8 'd -6    // this is illegal syntax
-8 'd 6    // this defines the two's-complement of 6,// held in 8 bits—equivalent to -(8'd 6)
4 'shf     // this denotes the 4-bit number '1111', to// be interpreted as a two's-complement number,// or '-1'. This is equivalent to -4'h 1
-4 'sd15   // this is equivalent to -(-4'd 1), or '0001'
16'sd?     // the same as 16'sbz

示例4:文字常量数值的自动左侧填充

logic [11:0] a, b, c, d;
logic [84:0] e, f, g;
initial begina = 'h x;   // yields xxxb = 'h 3x;  // yields 03xc = 'h z3;  // yields zz3d = 'h 0z3; // yields 0z3e = 'h5; 	// yields {82{1'b0},3'b101}f = 'hx; 	// yields {85{1'hx}}g = 'hz; 	// yields {85{1'hz}}
end

示例5:使用单比特值对常量文字数值进行自动左侧填充

logic [15:0] a, b, c, d;
a = '0; // sets all 16 bits to 0
b = '1; // sets all 16 bits to 1
c = 'x; // sets all 16 bits to x
d = 'z; // sets all 16 bits to z

Example 6: Underscores in literal constant numbers

27_195_000              // unsized decimal 27195000
16'b0011_0101_0001_1111 // 16-bit binary number
32 'h 12ab_f001         // 32-bit hexadecimal number

整数字面常量是一个 logic 类型的向量(见第 7.4 节),其范围定义为 [n-1:0],其中 n 是常量所占的比特数(如上所述)。若该常量是有符号的,则向量为有符号类型;否则为无符号类型。带位宽的负值字面常量以及带位宽的有符号字面常量,在赋值给 logic 类型的数据对象时,无论目标类型本身是否有符号,均会进行符号扩展。

5.7.2 Real literal constants

实数字面常量(real literal constant number)应符合 IEEE Std 754 标准的规定,该标准是双精度浮点数的 IEEE 标准。实数可用十进制表示法(例如 14.72)或科学计数法(例如 39e8,表示 39 乘以 10 的 8 次方)指定。带小数点的实数,其小数点两侧必须至少各有一位数字。

1.2
0.1
2394.26331
1.2E12 (the exponent symbol can be e or E)
1.30e-2
0.1e-0
23E10
29E-2
236.123_763_e-12 (underscores are ignored)

以下是无效的实数形式,因为它们的小数点两边至少没有一个数字:

.12
9.
4.E3
.2e-7

定点格式(例如 1.2)和指数格式(例如 2.0e10)的默认类型应为实型(real)。

可通过类型转换将实数字面值转换为短实型(shortreal),例如 shortreal’(1.2)。类型转换在 6.24 节中描述。

相关文章:

  • Elasticsearch 常用命令(未完成)
  • MFCLIP模型实现通用扩散人脸伪造检测
  • java集合(八) ---- Vector 类
  • GPU服务器租赁服务商TOP9
  • Acrobat 首选项配置:从注册表到锁定机制
  • 【Photoshop】使用路径和形状制作印章
  • vue父类跳转到子类带参数,跳转完成后去掉参数
  • 多文件,多开发环境配置 Spring boot
  • 精品可编辑PPT | 基于人工智能及大数据的综合智能交通管理平台AI大数据平替智慧交通
  • Java的Arrays.sort():排序算法与优化分析
  • Java单例模式有几种实现方式
  • R2S2:通过现实世界现成的技能空间释放人形机器人的潜力
  • 新手前端开发常见问题之层级问题
  • Node.js特训专栏-基础篇:3. Node.js内置模块的使用
  • 数据结构与算法-线性表-线性表的应用
  • HarmonyOS 5 Cordova有哪些热门插件?
  • vue3 标签页tab切换实现方法
  • 最大闭合子图学习笔记 / P2805 [NOI2009] 植物大战僵尸
  • antd vue a-range-picker如何设置不能选择当前和之后的时间,包含时分秒
  • linux thermal framework(3)_thermal cooling device
  • 快速建站视频/系统设置友情链接有什么作用
  • 公司网站源码 带wap手机站/云优客seo排名公司
  • 电商开发网站公司/西安百度推广优化托管
  • 成都学网站建设/产品推广词
  • seo擦边球网站/商旅平台app下载
  • 网站开发后台数据库怎么搞/长春网站公司哪家好