这个问题的起源是在阅读SV的LRM的时候,发现里面有一些看起来很奇怪的语句。
附录中也介绍了这种语法的描述形式叫做BNF范式,那么什么是BNF范式呢?
BNF 全称为 Backus-Naur Form,是一种用于描述上下文无关文法(CFG)的形式语法表示方法。它在计算机科学中被广泛应用于编程语言、通信协议和文件格式等领域。
在 BNF 中,语法规则由一个非终结符符号
<non-terminal> ::= <replacement>
和一组右侧的候选规则组成。每个规则的形式为:
其中,<non-terminal>
表示一个非终结符号,尖括号用于表示非终结符号。<replacement>
是一个由一个或多个终结符号和非终结符号构成的字符串。这个字符串规定了如何用一个非终结符号来“替换”它自己。等号“ ::=”表示被定义为,两边可以看作是“等同于”。
BNF 范式的优点是能够清晰准确地表达语法规则,且与语言无关,因此便于被转化成计算机程序。此外,它还具有严格的正则结构,使得它能够方便地进行软件化处理和自动分析。因此,在编程语言的设计和实现、语法分析和编译等领域,BNF 范式被广泛应用。
下面是一个简单的 BNF 范式的样例,表示一个整数的表达式可以由数字或加减号和表达式组成:
<expression> ::= <number> | <expression> "+" <expression> | <expression> "-" <expression>
<number> ::= "0" | "1" | "2" | ... | "9"
在LRM的附录中有如下补充说明:
systemverilog源代码的语法派生自起始符号source_text。库映射文件的语法派生自起始符号library_text。使用如下约定:
1.关键字与符号使用红色文本
2.句法类别使用非粗体文本
3.竖线(|或号)分割可选内容
4.方括号([ ])包含可选项
5.花括号({ })包含的内容可以重复0次或更多次
需要注意的是systemverilog的语法并不单纯使用BNF范式进行描述。LRM中提供了更多的语法及语义的详细描述。
在附录中module被定义如下:
module_declaration ::=
module_nonansi_header [ timeunits_declaration ] { module_item }
endmodule [ : module_identifier ]
| module_ansi_header [ timeunits_declaration ] { non_port_module_item }
endmodule [ : module_identifier ]
| { attribute_instance } module_keyword [ lifetime ] module_identifier ( .* ) ;
[ timeunits_declaration ] { module_item } endmodule [ : module_identifier ]
| extern module_nonansi_header
| extern module_ansi_header
对于
{ attribute_instance } module_keyword [ lifetime ] module_identifier ( .* ) ;
[ timeunits_declaration ] { module_item } endmodule [ : module_identifier ]
基于上面的规则可以知道,其中一定会有的是:
module_keyword module_identifier ( .* ) ; endmodule
module_keyword的定义是:
module_keyword ::= module | macromodule
module_identifier实际上就是module名,后跟( .* );,最后要加上endmodule
可选的部分有:
{ attribute_instance } 指的是sv中的一种机制,可以用于指定对象、语句和语句组的属性,这些属性可以用于各种工具,包括模拟器,用于控制工具的操作或者行为。这些属性被称为attributes。
[ lifetime ] 的定义是lifetime ::= static | automatic ,对于module默认是static。
[ timeunits_declaration ] 定义的是仿真时间单位/时间精度。
{ module_item } 这玩意指的是module内部能装的东西,太多了先不展开。
[ : module_identifier ] 可以理解为是module块的命名,一般取module名
上面还有两个module_nonansi_header和module_ansi_header是什么捏?在LRM的23.2.1 Module header definition部分有描述,指的是modue头的两种定义形式,non-ANSI header和ANSI header,我觉得属于茴类问题,就不展开了。