SystemVerilog语言知识介绍

  • 格式:docx
  • 大小:31.31 KB
  • 文档页数:28

SystemVerilog语言知识介绍

SystemVerilog是一种硬件描述与验证语言(HDVL),它基于IEEE 1364-2001 Verilog硬件描述语言(HDL),并对其进行了扩展,包含扩充了C语言数据类型、结构、压缩与非压缩数组、 接口、断言等等,这些都使得SystemVerilog在一个更高的抽象层次上提高了设计建模的能力。SystemVerilog由Accellera开发,它要紧定位在芯片的实现与验证流程上,并为系统级的设计流程提供了强大的连接能力。下面我们从几个方面对SystemVerilog所作的增强进行简要的介绍,期望能够通过这个介绍使大家对SystemVerilog有一个概括性的熟悉。

1. 接口(Interface)

Verilog模块之间的连接是通过模块端口进行的。为了给构成设计的各个模块定义端口,我们务必对期望的硬件设计有一个全面的认识。不幸的是,在设计的早期,我们很难把握设计的细节。而且,一旦模块的端口定义完成后,我们也很难改变端口的配置。另外,一个设计中的许多模块往往具有相同的端口定义,在Verilog中,我们务必在每个模块中进行相同的定义,这为我们增加了无谓的工作量。

SystemVerilog提供了一个新的、高层抽象的模块连接,这个连接被称之接口(Interface)。接口在关键字interface与endinterface之间定义,它独立于模块。接口在模块中就像一个单一的端口一样使用。在最简单的形式下,一个接口能够认为是一组线网。比如,能够将PCI总线的所有信号绑定在一起构成一个接口。通过使用接口,我们在进行一个设计的时候能够不需要首先建立各个模块间的互连。随着设计的深入,各个设计细节也会变得越来越清晰,而接口内的信号也会很容易地表示出来。当接口发生变化时,这些变化也会在使用该接口的所有模块中反映出来,而无需更换每一个模块。下面是一个接口的使用实例:

interface chip_bus; // 定义接口

wire read_request, read_grant;

wire [7:0] address, data;

endinterface: chip_bus

module RAM (chip_bus io, // 使用接口

input clk);

// 能够使用io.read_request引用接口中的一个信号 endmodule

module CPU(chip_bus io, input clk);

...

endmodule

module top;

reg clk = 0;

chip_bus a; // 实例接口

// 将接口连接到模块实例

RAM mem(a, clk);

CPU cpu(a, clk);

endmodule

实际上,SystemVerilog的接口不仅仅能够表示信号的绑定与互连。由于SystemVerilog的接口中能够包含参数、常量、变量、结构、函数、任务、initial块、always块与连续赋值语句,因此SystemVerilog的接口还能够包含内建的协议检查与被使用该接口的模块所共用的功能。

2. 全局声明与语句 在Verilog中,除了一个模块能够作为模块实例引用其他模块外,并不存在一个全局空间。另外,Verilog同意任意数目的顶层模块,因此会产生毫无关联的层次树。

SystemVeriog增加了一个被称之$root的隐含的顶级层次。任何在模块边界之外的声明与语句都存在于$root空间中。所有的模块,不管它处于哪一个设计层次,都能够引用$root中声明的名字。这样,假如某些变量、函数或者其它信息被设计中的所有模块共享,那么我们就能够将它们作为全局声明与语句。全局声明与语句的一个使用实比如下:

reg error _flag; // 全局变量

function compare (...); // 全局函数

always @(error_flag) // 全局语句

...

module test;

chip1 u1 (...)

endmodule

module chip1 (...);

FSM u2 (...);

always @(data)

error_flag = compare(data, expected); endmodule

module FSM (...);

...

always @(state)

error_flag = compare(state,

expected);

endmodule

3. 时间单位与精度

在Verilog中,表示时间的值使用一个数来表示,而不带有任何时间单位。比如:

forever #5 clock = ~clock;

从这一句中我们无法推断5代表的是5ns? 5ps? 还是其他。Verilog的时间单位与精度是作为每一个模块的属性,并使用编译器指令`timescale来设置。使用这种方法具有固有的缺陷,由于编译器指令的执行依靠于源代码的编译顺序,编译器总是将它遇到的最后一个`timescale设置的时间单位与精度作为之后的标准。那么,假如有些模块之前没有使用`timescale设置时间单位与精度,这就有可能出现同一个源代码的不一致仿真会出现不一致结果的情况。

SystemVerilog为了操纵时间单位加入了两个重要的增强。首先,时间值能够显式地指定一个单位。时间单位能够是s、ms、ns、ps或者fs。时间单位作为时间值的后缀出现。比如:

forever #5ns clock = ~clock;

其次,SystemVerilog同意使用新的关键字(timeunits与timeprecision)来指定时间单位与精度。这些声明能够在任何模块中指定,同时也能够在$root空间中全局指定。时间单位与精度务必是10的幂,范围能够从s到fs。比如:

timeunits 1ns;

timeprecision 10ps;

4. 抽象数据类型

Verilog提供了面向底层硬件的线网、寄存器与变量数据类型。这些类型代表了4态逻辑值,通常用来在底层上对硬件进行建模与验证。线网数据类型还具有多个强度级别,同时能够为多驱动源的线网提供解析功能。

SystemVerilog包含了C语言的char与int数据类型,它同意在Verilog模型与验证程序中直接使用C与C++代码。Verilog PLI不再需要集成总线功能模型、算法模型与C函数。SystemVerilog还为Verilog加入了几个新的数据类型,以便能够在更抽象的层次上建模硬件。  char:一个两态的有符号变量,它与C语言中的char数据类型相同,能够是一个8位整数(ASCII)或者short int(Unicode);

 int:一个两态的有符号变量,它与C语言中的int数据类型相似,但被精确地定义成32位;

 shortint:一个两态的有符号变量,被精确地定义成16位;

 longint:一个两态的有符号变量,它与C语言中的long数据类型相似,但被精确地定义成64位;

 byte:一个两态的有符号变量,被精确地定义成8位;

 bit:一个两态的能够具有任意向量宽度的无符号数据类型,能够用来替代Verilog的reg数据类型;

 logic:一个四态的能够具有任意向量宽度的无符号数据类型,能够用来替代Verilog的线网或者reg数据类型,但具有某些限制;

 shortreal:一个两态的单精度浮点变量,与C语言的float类型相同;

 void:表示没有值,能够定义成一个函数的返回值,与C语言中的含义相同。 SystemVerilog的bit与其他数据类型同意用户使用两态逻辑对设计建模,这种方法对仿真性能更有效率。由于Verilog语言没有两态数据类型,因此许多仿真器都通过将这种功能作为仿真器的一个选项提供。这些选项不能够在所有的仿真器之间移植,而且在需要时用三态或者四态逻辑的设计中强制使用两态逻辑还具有副作用。SystemVerilog的bit数据类型能够极大改进仿真器的性能,同时在需要的时候仍然能够使用三态或者四态逻辑。通过使用具有确定行为的数据类型来代替专有的仿真器选项,两态模型能够在所有的SystemVerilog仿真器间移植。

SystemVerilog的logic数据类型比Verilog的线网与寄存器数据类型更加灵活,它使得在任何抽象层次上建模硬件都更加容易。logic类型能够下列面的任何一种方法赋值:

 通过任意数目的过程赋值语句赋值,能够替代Verilog的reg类型;

 通过单一的连续赋值语句赋值,能够有限制地替代Verilog的wire类型;

 连接到一个单一原语的输出,能够有限制地替代Verilog的wire类型;

由于logic数据类型能够被用来替代Verilog的reg或者wire(具有限制),这就使得能够在一个更高的抽象层次上建模,同时随着设计的不断深入能够加入一些设计细节而不必改变数据类型的声明。logic数据类型不可能表示信号的强度也不具有线逻辑的解析功能,因此logic数据类型比Verilog的wire类型更能有效地仿真与综合。

5. 有符号与无符号限定符

缺省情况下,Verilog net与reg数据类型是无符号类型,integer类型是一个有符号类型。Verilog-2001标准同意使用signed关键字将无符号类型显式地声明成有符号类型。SystemVerilog加入了相似的能力,它能够通过unsigned关键字将有符号数据类型显式地声明成有无符号数据类型。比如:

int unsigned j;

值得注意的是unsigned在Verilog中是一个保留字,但并没有被Verilog标准使用。

6. 用户定义的类型

Verilog不同意用户定义新的数据类型。SystemVerilog通过使用typedef提供了一种方法来定义新的数据类型,这一点与C语言类似。用户定义的类型能够与其它数据类型一样地使用在声明当中。比如:

typedef unsigned int uint; uint a, b;

一个用户定义的数据类型能够在它的定义之前使用,只要它首先在空的typedef中说明,比如:

typedef int48; // 空的typedef,在其他地方进行完整定义

int48 c;

7. 枚举类型

在Verilog语言中不存在枚举类型。标识符务必被显式地声明成一个线网、变量或者参数并被赋值。SystemVerilog同意使用类似于C的语法产生枚举类型。一个枚举类型具有一组被命名的值。缺省情况下,值从初始值0开始递增,但是我们能够显式地指定初始值。枚举类型的例子如下:

enum {red, yellow, green} RGB;

enum {WAIT=2’b01, LOAD, DONE} states;

我们还能够使用typedef为枚举类型指定一个名字,从而同意这个枚举类型能够在许多地方使用。比如:

typedef enum {FALSE=1’b0, TRUE} boolean;

boolean ready;

boolean test_complete;

8. 结构体与联合体