SystemVerilog

维基百科,自由的百科全书
跳转至: 导航搜索
SystemVerilog
编程范型 结构化(设计)
面向对象(验证)
发行时间 2002年  (2002)
最新发行时间 IEEE 1800-2009 / 2009年12月18日;4年前 (2009-12-18)
型態系統 静态、弱类型
啟發語言 VerilogVera
常用文件扩展名 .sv

在现代的集成电路(尤其是超大规模集成电路)的设计和验证流程中,SystemVerilog是一种由Verilog发展而来的硬件描述硬件验证统一语言,前者基本上是2005年版Verilog的扩展,而后者的功能验证特性以面向对象程序设计技术为基础。该语言为电气电子工程师学会1800-2009标准,获得了主流电子设计自动化工具的支持。

发展历史[编辑]

SystemVerilog的历史可以追溯到2002年,当时一个被称为“Superlog”的语言被捐赠给Accellera公司(Verilog的主要支持者)。[1]Synopsys公司捐赠的OpenVera后来发展成为SystemVerilog中硬件验证语言子集。2005年,SystemVerilog获批成为电气电子工程师学会1800-2005标准。[2]当时Verilog作为电气电子工程师学会1364-2005标准尚独立存在。2009年,SystemVerilog与的Verilog进行了合并,成为了新的电气电子工程师学会1800-2009标准,该版本的标准沿用至今。

设计特性[编辑]

对于电路设计工程师来说,SystemVerilog中有大部分内容继承自Verilog,但是也提供了一些增强或者改进的特性。下面的章节主要讲述SystemVerilog的这些特性。

新的数据类型[编辑]

逻辑型变量[编辑]

SystemVerilog定义了一种新的逻辑型(logic)变量。和Verilog中变量的声明类似,以下代码描述了一个32位的逻辑型变量:

logic [31:0] my_var;

在传统的Verilog中,变量主要分为线网型(wire)和寄存器型(reg)两大类型。只有寄存器型变量才能够在过程代码块中被赋值,而线网型变量只能在过程代码块之外被连续赋值。寄存器型变量的过程赋值和线网型变量的连续赋值使用了完全不同的语句结构。在Verilog中,二者的区分比较微妙,以至于有些专业的工程师也在设计中混淆二者。由于always过程代码块不仅可以描述时序逻辑电路,还可以通过将所有寄存器型的输入变量添加到敏感列表来实现纯组合逻辑电路,因此“寄存器型”这个带有时序逻辑意义的术语本身也令人误会。

SystemVerilog增强了寄存器型变量的功能,它可以像Verilog中线网型变量一样由线网(如逻辑门等模块的输出)驱动(这样的线网驱动寄存器的方式在Verilog中是不允许的)。这种增强的变量类型被命名为“逻辑型”,从而避免“寄存器型”在字面上给人带来的误会。在大多数情况中,SystemVerilog中的logic可以替代Verilog中的regwire,但是如果某个某个变量具有多个驱动源,那么就不能使用logic,而要使用严格的wire来定义它。

多维压缩数组[编辑]

这种结构将Verilog中与寄存器、存储器相关的概念进行了合并和扩展。

在Verilog中,变量名称左边的索引被用来表示二进制变量的位宽,Verilog规定它只能是一维的。而这个数组名称右边的索引用来表示以这种位宽变量组成数组的元素个数,因为数组可以是一维数组、二维数组或者多维数组,因此这个索引可以是任意整数。在SystemVerilog中,如果在变量名称左边指定了由高至低的位宽(如8位信号由[7:0表示),则称之为“压缩数组”(packed array,有时也被译为“合并数组”)。压缩数组本身可以是多维的,即变量名称左边可以具有多维索引。如果在变量名称右边指定了数组尺寸,则称之为“非压缩数组”。下面用示例代码表示了一个由二维压缩数组构成的一维非压缩数组:

logic [1:0][2:0] my_pack[32];

在上面的例子里,非压缩数组数组my_pack具有32个元素(这里用到了类似C语言的数组元素个数表示方法,这里也可以写成Verilog中常见的[31:0]形式)。这个非压缩数组每一个元素本身又是压缩数组,即2个位宽为3的逻辑型变量,因此非压缩数组的每一个元素包含六位二进制数的信息。A variable of packed array type maps 1:1 onto an integer arithmetic quantity.

枚举[编辑]

SystemVerilog引入了枚举型变量,它使用一系列有实际字面意义的名称来代表若干变量。如果不进行专门的数据类型转换,一个枚举型变量不能直接赋值给另一个枚举型的变量。过去在Verilog中描述有限状态机常常使用参数(关键字为parameter),而在SystemVerilog中,使用枚举则更为方便。

typedef enum logic [2:0] {
   RED, GREEN, BLUE, CYAN, MAGENTA, YELLOW
} color_t;
 
color_t   my_color = GREEN;
initial $display("The color is %s", my_color.name());

上面的例子使用了typedef来创建了一个新的数据类型名称,从而可以用它来创建一系列枚举数据。枚举类型的数据类型,为位宽为3的逻辑型变量。3位二进制数能够逐一指代六种颜色。使用代码color_t my_color = GREEN;创建了一个新的color_t型变量,其值初始化为六种颜色中的绿色。系统函数$display的作用与Verilog相同,其参数是my_color所属函数name()的返回值,即当前枚举值的ASCII值。

其他新增的数据类型[编辑]

除了基本的逻辑型变量(logic),SystemVerilog正还提供了字节型变量(byte,8位)、短整型变量(shortint,16位)、整型变量(int,32位)和长整型变量(longint64位)、比特型变量(bit,1位,仅具有两个逻辑状态,和逻辑型数据(logic)缺少了未知逻辑(x)和高阻态z)。使用两态逻辑可以提高逻辑仿真速度)。

结构体和联合体[编辑]

这两种数据类型和C语言中的结构体联合体类似。在SystemVerilog中,与这两种数据类型相关的增强特性为压缩属性(packed)和标签属性(tagged)。压缩属性使得mapped 1:1 onto a packed array of bits,而标签属性允许跟踪当前联合体中实际被使用的成员。这些结构占据了连续的存储空间。

typedef struct packed {
    bit [10:0]  expo;
    bit         sign;
    bit [51:0]  mant;
} FP;
 
FP     zero = 64'b0;

条件、选择语句的唯一性和优先性[编辑]

当条件、选择语句的路径分支较为复杂时,设计人员稍不留意就可能造成代码所描述的行为违背设计人员预计的优先级别,或者被判断的表达式同时满足多个分支条件,从而在仿真过程中产生无规律结果。

为此,SystemVerilog增强了条件、选择语句的功能,允许设计人员为这分支流程的执行设置特别的约束。在多级条件、选择语句中使用关键字unique,可以限定有且只有一个分支可能被执行到,否则将产生一个警告。而关键字priority则指出某些分支路径具有更高的优先级。过去,在传统的Verilog中,要实现类似的功能,设计人员需要在可综合代码中附带一些特殊的注释(例如: // synopsys full_case parallel_case)来通知逻辑综合工具产生正确的分支逻辑电路。不过,注释并非SystemVerilog代码的正式组成部分,它们只是在逻辑综合过程被特定的工具读取,而不严谨的注释很可能造成综合后电路与综合前仿真结果不同的情况。

过程代码[编辑]

Verilog中的过程代码可以描述时序逻辑电路,也可以描述组合逻辑电路,这一点容易造成概念的混淆,如果代码不严谨,逻辑综合很可能推断出锁存器,从而产生不符合预期的硬件模型。SystemVerilog除了继续支持原来Verilog中的老式过程结构alwaysinitial,还在原有always基础上针对组合逻辑电路触发器锁存器设计了专用的always结构。虽然它们显得不够通用,但是三类硬件模型的差异得到了明确地区分,避免使用老式always时容易出现的锁存器推断:

  • always_comb:用于组合逻辑电路(相当于Verilog中对所有输入变量电平敏感的always,但always_comb无需手动列出所有输入变量,系统会自动识别);
  • always_ff:用于触发器及相关的时序逻辑电路(相当于Verilog中对某个或某几个信号有效跳变沿敏感、并带有信号储存特性的always);
  • always_latch:用于锁存器级相关的时序逻辑电路(相当于Verilog中对某个或某几个信号电平敏感、并带有信号储存特性的的always)。

三种专用的always结构在使用时会检查设计代码是否符合对应硬件模型的特征。如果设计人员在过程代码中描述了与对应硬件不符合的行为(例如在always_latch的敏感列表中添加了定時器訊號的上升沿),那么系统会发出警告。这是SystemVerilog种专用型过程结构的优越之处。

下面的例子使用always_comb来描述组合逻辑电路。在SystemVerilog中无需像Verilog中描述组合逻辑电路那样写出敏感列表,always_comb会告诉逻辑综合工具这是一个组合逻辑电路,因此系统会默认对所有输入信号的电平敏感。在表示组合逻辑电路的过程代码中,一般使用阻塞赋值。

always_comb begin
    tmp = b * b - 4 * a * c;
    no_root = (tmp < 0);
end

逻辑综合工具会将always_ff推断为同步时序逻辑,这里需要写明对什么信号的什么边缘(上升或者下降)敏感。在表示时序逻辑电路的过程代码中,一般使用非阻塞赋值。

always_ff @(posedge clk)
    count <= count + 1;

逻辑综合工具还会将always_latch推断为电平敏感的锁存器电路,对输入信号的电平敏感,但是具有信号储存特性:

always_latch
    if (en) q <= d;

接口[编辑]

对于小型的设计,Verilog设计人员可以使用端口(port)来简洁地描述模块与外部环境的连接情况。不过,在规模较大、抽象层次较多的设计中,处于枢纽地位的模块往往具有大量连线与外界的连通。为此,SystemVerilog引入了接口(interface)的概念,这个概念一方面减少了大量需要声明的端口名称,另一方面,它还方便设计人员将某些相关信号的通道作为一捆相对独立的线网组,这样就使复杂的设计更加简单、明晰。另一个概念是modport,它显示了逻辑连接的方向。例如:

interface intf;
  logic a;
  logic b;
  modport in (input a, output b);
  modport out (input b, output a); 
endinterface
 
module top;
  intf i ();
  u_a m1 (.i1(i));
  u_b m2 (.i2(i));
endmodule
 
module u_a (intf.in i1);
endmodule
 
module u_b (intf.out i2);
endmodule

验证特性[编辑]

随着集成电路集成规模的不断提高,电路的复杂程度也越来越大。在这种情况下,设计验证在整个设计流程中所占用的时间越来越高。SystemVerilog在Verilog基础上增加了许多专门针对验证的特性,使其成为一种杰出的硬件验证语言。下面所提到的验证代码通常是不可综合的,它们的作用主要体现在测试平台的搭建过程中。

新的数据类型[编辑]

SystemVerilog引入了专门的字符串型变量,用关键字string表示,例如:

string s1 = "Hello";
string s2 = "world";
string p = ".?!";
string s3 = {s1, ", ", s2, p[2]}; // 字符串的拼接
$display("[%d] %s", s3.len(), s3); // 仿真结果显示为:“[13] Hello, world!”

除了在设计中使用静态数组,SystemVerilog还提供了动态数组、关联数组(associative array)和队列(queues):

int cmdline_elements; // # elements for dynamic array
int da[];       // 动态数组
int ai[int];    // 以整数位索引的关联数组
int as[string]; // 以字符串为索引的关联数组
int qa[$];      // 队列
 
initial begin
    cmdline_elements = 16;
    da = new[ cmdline_elements ]; // 为da数组分配16个元素
end

动态数组的行为和非压缩数组相似,不过它允许仿真在运行时动态分配元素个数(正如上面例子所示)。压缩数组部分的元素个数(以往称之为“位宽”)必须在编译的时候已知(通过由常数或常数表达式直接确定),而非压缩数组的动态大小则可以在程序运行时,由另一个运行中的程序变量进行初始化,这样就可以在运行中根据所需改变数组的大小。

[编辑]

SystemVerilog为验证代码的编写提供了面向对象程序设计的模型。

含约束的随机化[编辑]

随机化的产生[编辑]

控制约束条件[编辑]

断言[编辑]

覆盖[编辑]

同步化[编辑]

对经典Verilog的改进[编辑]

验证和综合软件[编辑]

SystemVerilog的设计验证能力在芯片设计领域已经得到了广泛的应用。三大电子设计自动化工具供应商(CadenceMentor GraphicsSynopsys)已在它们的混合语言仿真系统中添加了对SystemVerilog的支持。虽然没有哪一个仿真系统能够声称自己完全支持SystemVerilog语言参考手册(Language Reference Manual, LRM)里介绍的所有语言结构,因此要改善测试平台的互操作相当困难,但是推进跨平台兼容性的研究开发工作已经在进行。2008年,Cadence和Mentor发布了开放验证方法学英语Open Verification Methodology(后来发展为统一验证方法学),这一方法学主要包括开放源代码类库以及支持可重用测试平台、开发验证IP核的预置格式。Synopsys在启动其验证方法学手册(Verification Methodology Manual, VMM)前率先公布了SystemVerilog类库。许多第三方提供商则开始推出基于SystemVerilog的验证IP核。

相关条目[编辑]

参考文献[编辑]

  1. ^ Rich, D. The evolution of SystemVerilog. IEEE Design and Test of Computers. 
  2. ^ IEEE approves SystemVerilog, revision of Verilog. EE Times. 2005-11-03 [2013-07-14]. 

外部链接[编辑]

IEEE 标准文献[编辑]

教程[编辑]

标准开发[编辑]

语言延伸[编辑]

  • Verilog AUTOs - An open-source meta-comment system to simplify maintaining Verilog code.