IEEE Standard(1)--Conventions
本文最后更新于:Wednesday, September 30th 2020, 8:01 pm
1、Overview
1.1 Convention
shall: 用于法定的要求(mandatory requirement)
may: 用于可选的特性(optional feature)
1.2 Syntactic description
BNF描述方法(Backus-Naur Form):
基本结构为:
::=
::=:被定义为的意思“ ”: 双引号表示字符串,也就是终结符,不能再被定义。- 在双引号外的字代表着语法部分;
基本类型 ::= 字符串 | 数字 | 布尔,其中字符串、数字、布尔具体是什么,由下面的规则定义(递归)<>:尖括号里的内容表示必选内容;[...]: 表示可选。{...}:表示重复;实例:AB ::= "a" {"b"}表示:AB由一个a加上任意数量(包括0个)个b组成(...): 表示分组,用来控制优先级;AX ::= "a" ("m"|"n")表示:AX由一个a加上m或者n组成(*...*): 注释,说明性文本,不表示任何语法。
小写单词,一些包含下划线的:语法目录(syntactic categories)
module_declaration粗体:保留字、操作符、标点符号
module=>;竖条|分割可选单元。如果它以粗体形式出现,它才表示自己。
unary_operator ::= + | - | ! | ~ | & | ~& | |(或) | ~|(或非) | ^ | ~^ | ^~(都表示同或)
方括号[…]包含可选项。
input_declaration ::= input [range] list_of_variables;花括号
{}除非以粗体出现,它才表示自己,否则表示重复。重复从左到右进行,和左递归等效。list_of_param_assignments ::= param_assignment { , param_assignment }
list_of_param_assignments ::=
param_assignment| list_of_param_assignment , param_assignment
任何目录的名字以斜体开头,等效于没有斜体部分的目录名。斜体部分只是为了传达
semantic information。
正文中当一个term被定义时使用斜体;在例子,文件名,常量特别时0,1,x和z的值时使用
constant-width字体(等宽字体)
2、Lexical convention
2.1、Lexical tokens
Verilog HDL source file shall be a stream of lexical tokens. A
lexical tokensshall consist of one or more characters.
verilog源文件应该是一连串语法标记,一个语法标记由一个或多个字符组成。
源文件中tokens的位置是随意的,也就是说:除了token分隔符,空格和换行不应该有特殊意义,转义字符除外。
有如下几种语法标记
- White space
- Comment
- Operator
- Number
- String
- Identifier
- Keyword
2.2、White space
white space应该包含:用于空格、制表符、换行符和格式提要的字符。这些字符应该被忽略除了当它们用于分割其他语法标记(tokens)。但是blanks和tabs被认为是有意义的字符在字符串中。
2.3、Comments
- 单行注释
// - 块注释:
/*….*/
2.4、Operators
操作符可以是单个,双个或三个字符的序列,并被用在表达式中。Clause5将讨论表达式中操作符的使用。
单目运算符(Unary operators):在操作数(operand)的左边
双目运算符(Binary operators):在两个操作数中间
三木运算符(Triple operator or conditional operator): 有两个操作符字符分割三个操作数(a? x: y)
2.5、Numbers
Constant numbers可以被指定为integer constant或者real constant
2.5.1、Integer constant
有两种表达方式:
- 简单的十进制数:a sequence of digits of 0 through 9。开头可以加上
+或者-(被视为有符号的整数) - 指定基码(d,h,o,b):可选的
位宽+'(ASCII 0x27)+基码+digits- 位宽:非零无符号十进制数
- 基码:大小写不敏感;前面可选s指示是否为有符号数(没有s时默认为unsigned integers)
'与基码中间不能有空格。⭐digits: 应该紧跟着基码,前面也可以有空格。a-f不区分大小写s不影响指定的位模式,只改变解释方式。❓
- 负数用补码表示
- x代表
unknown value;z代表high-impedance value(x应该设为4bit对于h的基码,3bit对于o的基码;z同理) - 如果无符号数位宽小于指定位宽,那么用0填充;如果无符号数最左边的位是x或z;那么用x或z填充。如果无符号位宽大于指定,那么应该从左边截断到指定位宽。
- 没有指定位宽的数字至少为
32位;对于高位是x或者z的没有位宽无符号常数应位扩展到包含该常数的表达式的大小。❓ ?是z的替代字符。在高阻值不需要注意时,可用?来增加可读性。- 在十进制常数中,无符号数不能包含任何x,z,?;除非只有一个digit,指示其中每一位都是x或者z。
_下划线在数字的任何位置都是合法的,除了第一个字符。下划线是没有意义的 ,只是为了分割长的数字提高可读性。
1 | |
1 | |
1 | |
1 | |
2.5.2、Real constants
real constants用IEEE Std 754-1985,双精度浮点数表示
有两种表示方法:
- 十进制表示:14.72
- 科学计数法:39e8(表示39乘以10的8次方)
注意:带有小数点的实数至少在小数点两边各有一位。
.12 9. 4.E3 .2e-7 都是不合法的
2.5.3、Convertion
实数向整数转化:四舍五入到最近的整数,而不是截断。
当一个实数被赋值给整数时:进行隐士转化(implicit conversion)
四舍五入规则:away from zero
- -1.5 转化为-2;1.5转化为2
2.6、Strings
字符串是一个字符序列,用(“ “)括起来,包含在一行中。字符串可以用作表达式的操作数;赋值时被当成无符号整数常数,一个8-bit的ASCII值对应一个字符。
2.6.1、String variable declaration
字符串变量是
reg类型,宽度=字符个数*8
1 | |
2.6.2、String manipulation
字符串可以用Verilog的操作符进行操纵。被操纵的值是8bit ASCII值序列
1 | |
- 当变量占用空间大于所分配的空间时,值向右调整,最左边用0填充,与处理非字符串的值一样。
- 当占用空间大于分配空间时,字符串还是向右调整,最左边的截断。
2.6.3 Special characters in strings
有些字符只有前面加上
escape character它们才能在字符串里面使用

2.7、Identifiers,keywords,and system names
标识符用于给一个对象独一无二的名字,使得它们能呗引用。
简单的标识符:字母,数字,$, _组成。开头只能是字母或者下划线。(_bus, wan$li)
实现的时候标识符有最大长度,它的限制应该至少为1024个字符。如果一个标识符长度超过这个,系统应该报错。
2.7.1 Escaped identifiers
转义标识符以反斜杠\开始,以white space(space, tab,newline)结束。它们提供了在标识符中包含任何可打印字符的方法(33(!)-126(~);$21_h$-$7E_h$)。
前导反斜杠和结尾的空白字符都不算标识符的一部分,因此,\cpu3被认为和cpu3一样。
1 | |
2.7.2 Keywords
关键字是先前定义好的非转义标识符,它们被用来定义语言结构。关键字前面加上转义字符不被解释为关键字

2.7.3 System tasks and functions❓
美元符号()开头的名字被解释为系统任务或者系统函数。
1 | |
2.7.4 Compiler directives
`(ASICC value 0x60)字符引导用于实现编译器指令的语言结构;,一个描述文件中的编译器指令可以控制多个描述文件中的编译行为。
`identifier 编译器指令结构在以下两种地方定义
- 标准标识符编译器指令
- 由软件实现定义的附加’标识符编译器指令。
任何有效的标识符,包括已经在除此构造之外的上下文中使用的关键字,都可以用作编译器指令名
1 | |
2.8、Attributes
随着使用Verilog HDL作为源代码的仿真器以外的工具的激增(proliferation); Verilog引入一种机制:用于指定关于HDL源代码中对象、语句和语句组的属性,这些属性可被各种工具(包括模拟器)使用,以控制工具的操作或行为。这些属性被称作
attribute. 本小节将介绍: 可以用于指定属性的语法机制。
1 | |
attribute_instance:1、作为声明,模块项目,语句或者端口连接的前缀。2、运算符或在一个表达式中Verilog函数名的后缀
如果没有给属性指派值,那么值默认为1;如果对相同的language element定义多个相同的属性名字,那么最后一个属性值将被使用;工具可以在这种情况下给个warning。
nesting of attribute instances 不被允许;用包含属性实例的常量表达式(constant expression that contains an attribute instance)去给属性赋值是不合法的。
2.8.1 Examples
范例1:给case语句贴上属性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17(* full_case, parallel_case *)
case (foo)
<rest_of_case_statement>
or
(* full_case=1 *)
(* parallel_case=1 *) // Multiple attribute instances also OK
case (foo)
<rest_of_case_statement>
or
(* full_case, // no value assigned;默认为1
parallel_case=1 *)
case (foo)
<rest_of_case_statement>范例2:给模块定义加属性
1
2(* optimize_power *)
module mod1 (<port_list>);范例3:给模块实例加属性
1
2(* optimize_power=0 *)
mod1 synth1 (<port_list>);范例4:给reg声明加属性
1
2
3
4(* fsm_state *) reg [7:0] state1;
(* fsm_state=1 *) reg [3:0] state2, state3;
reg [3:0] reg1; // this reg does NOT have fsm_state set
(* fsm_state=0 *) reg [3:0] reg2; // nor does this one范例5:给操作符加属性
1
2a = b ? (* no_glitch *) c : d;
a = b + (* mode = "cla" *) c;2.8.2 Syntax(省略)
本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!