本章节介绍所有SV数据类型。
1.1 整数类型 integer data type
整数类型可以被分为两种,二值(2-state)和四值(4-state)。同样也可以分为有符号(signed)和无符号(unsigned)。
(整数数据类型)
1.1.1 integer,int,longint,shortint,logic,byte,reg
int, longint, shortint都是二值有符号整数类型。
integer是四值有符号型。
reg和logic是四值无符号型。
注意:bit,logic,reg 是自定义位宽的。
module datatype1;
integer a; //4 state - 32 bit signed
int b; //2 state - 32 bit signed
shortint c; //2 state - 16 bit signed
longint d; //2 state - 64 bit signed
logic [7:0] A1; //4-state - unsigned ‘logic’
logic signed [7:0] sl1; //4-state - signed ‘logic’
byte bl1; //2-state signed ‘byte’
reg [7:0] r1; //4-state - unsigned ‘reg’initial
begin
a = 'h xxzz_ffff; //integer - 4 state - 32 bit signed
b = -1; //int - 2 state - 32 bit signed
c = 'h fxfx; //shortint - 2 state - 16 bit signed
d = 'h ffff_xxxx_ffff_zzzz; //longint - 2 state - 64 bit signed
A1 = -1 ; //signed assignment to unsigned 'logic’
sl1 = -1; //signed assignment to signed 'logic'
bl1 = -1; //signed byte
r1 = 8'b xzxz_0101; //'reg' - unsigned 4-state
endinitial
begin #10;
$display("a = %h b = %h c = %h d = %h", a, b, c, d);
$display("A1 = %0d sl1=%0d bl1 = %0d r1 = %b",A1,sl1,bl1,r1);
#10 $fnish(2);
endendmodule
仿真结果
Simulation log:
a = xxzzffff b = ffffffff c = f0f0 d = ffff0000ffff0000
A1 = 255 sl1= -1 bl1 = -1 r1 = xzxz0101
V C S S i m u l a t i o n R e p o r t
1.1.2 有符号型 & 无符号型
module top;
logic [7:0] r1;
logic signed [7:0] sr1;
initial begin
r1 = -2;
$display($stime,,,"r1=%d",r1);
sr1 = -2;
$display($stime,,,"sr1=%d",sr1);
r1 = r1+1;
$display($stime,,,"r1=%d",r1);
sr1 = sr1+1;
$display($stime,,,"sr1=%d",sr1);
end
endmodule
Simulation log:
# run –all
# 0 r1=254
# 0 sr1= -2
# 0 r1=255
# 0 sr1= -1
可以看到,这里的logic可以被声明成有符号或者无符号。同样的,wire和ports也可以声明为signed。不过,默认logic,reg,wire,inputs和outputs为unsigned无符号的。
1.2 real 类型
real类型一般包含三种,real,shortreal,realtime。
注意,以下三种不适用real类型。
边沿事件posedge negedge edge;位选或者部分选引用;向量的位选或部分选引用的实数索引表达式。
1.2.1 类型转变函数
从real or shortreal转变成integer,bit的方法。
module datatype1;
real real1, real2, real3;
integer i1;
bit [63:0] bit1;
initial begin
real1 = 123.45;
i1 = $rtoi(real1); // real2integer $rtoi(),r means real, i means integer
real2 = $itor(i1); // integer2real $itor()
bit1 = $realtobits (real1); // $realtobits()
real3 = $bitstoreal(bit1); // $bitstoreal()
end
initial begin
#10;
$display("real1 = %f real2 = %f i1=%0d",real1,real2,i1);
$display("bit1 = %b real3=%f",bit1,real3);
#10 $fnish(2);
end
endmodule
real1 = 123.450000
i1=123
real2 = 123.000000
bit1 = 0100000001011110110111001100110011001100110011001100110011001101
real3=123.450000
V C S S i m u l a t i o n R e p o r t
1.3 Nets
线网类型主要用于连接,例如逻辑门的连接。没有存储功能,只是简单的驱动或者接收逻辑信号。
1.3.1 wire 和tri
wire 用于单gate驱动或者连续驱动赋值。
tri类型可用于多个驱动器驱动网络的情况。
关于tri,举个例子:图中有两个drivers ,同时驱动tri的Znet。当Aenb为1的时候,Bufif1驱动A;当Bend为0时,bufif0驱动B。
当Aenb=1,Benb=0时,Znet发生竞争导致不定态 x。当Aenb=0,Benb=1时,两个drivers都不使能,Znet为高阻状态z。Znet 是一种分解型网络。 它将通过两个(或更多)驱动器解析驱动值并产生正确的结果。注意这里与reg和logic 的不同,与未解析类型的“reg”或“logic”类型形成对比(当多个驱动程序从同时运行的逻辑进程驱动时,它们将导致竞争)
1.3.2 未解析型wire :uwire(了解即可)
wire和 tri都允许多个驱动源。 但是,如果想将“wire”限制为仅单个驱动程序怎么办? 如果想在多个驱动源驱动wire时看到错误怎么办? 这就是unresolved的“uwire”类型出现的原因。声明未解析的线的关键字是“uwire”。 它是一种未解析或单驱动wire用于仅允许单个驱动源的网络。 将 uwire 连接到多个驱动源是错误的。 将uwire连接到双向开关也是错误的。
1.4 static,automatic,local变量
1.4.1 static和local的区别:
static int n;
// Static variable – outside ‘module’ – globally declared visible to all modules/scopes that follow.
module vars;
int n;
//Local variable - Module level - visible to all scopes below
initial begin
n = 2;
$display("module level ‘n’ = %0d",n);
end
initial begin : init2
int n; //Local - Block level
n = 3;
$display("block level ‘n’ = %0d",n);
$unit::n = 4; //Static Global
$display("Statically declared ‘n’ = %0d",$unit::n);
end
initial begin //hierarchical reference to local variable
$display("init2.n = %0d", init2.n);
end
endmodule
module next;
//Static variable 'n' is visible in the module 'next'
initial begin
$display("Statically declared 'n' in module 'next' = %0d",$unit::n);
end
endmodule
module level ‘n’ = 2
block level ‘n’ = 3
Statically declared ‘n’ = 4
init2.n = 3
Statically declared 'n' in module 'next' = 4
V C S S i m u l a t i o n R e p o r t
在这个例子中,首先在module外部定义了一个静态变量n,这使n对每个module都可见(类似于全局变量)。&unit::n=4 是对静态变量n赋值,可以看到next里的n是4。
1.4.2 automatic和static的区别
automatic在每次进入block时都会initialized初始化,但static不会,会保留上次的赋值。
module autovars;
initial begin
for (int i=0; i<2; i++) begin
automatic int loop3 = 0; // executes every loop
for (int j=0; j<2; j++) begin
loop3++;
$display("loop3=%0d",loop3);
end
end // loop3 = 1 2 1 2
for (int i=0; i<2; i++) begin
static int loop2 = 0; // executes once at time zero
for (int j=0; j<2; j++) begin
loop2++;
$display("loop2=%0d",loop2);
end
end // loop2 = 1 2 3 4
end
endmodule : autovars
1.5 枚举类型
枚举类型变量可以被声明成没有数据类型或者数值的,默认类型位int。
enum {red, green, blue} light1, light2;
enum logic [1:0] { IDLE = 2’b00,
READ = 2’b01,
WRITE = 2’b10,
RMW = 2’b11,
ILLEGAL = ‘x } current_state, next_state;
always @(posedge clk, negedge reset)
if (!reset) current_state <= IDLE;
else current_state = next_state;
always @* begin
…
case (current_state)
IDLE : if (rdy) next_state = READ;
READ : if (go) next_state = WRITE;
…
endcase
end
↑ 一段不完整的例子,应该可以解释enum的用法了。用的时候一般要声明句柄哦!
1.6 用户自定义类型
typedef enum {NO, YES} boolean;
boolean myvar1, myvar2; //声明
module tdef;
typedef integer unsigned u_integer;
typedef enum {RED, GREEN, BLUE} rgb;
typedef bit [7:0] ubyte;
u_integer uI = 32'h face_cafe;
u_integer uI1 = 32'h cafe_face;
rgb rgb_i = GREEN;
rgb rgb_i1 = BLUE;
ubyte cnt = 8'hFF;
initial begin
$display ("rgb_i=%s rgb_i1=%s uI=0x%0h uI1=0x%0h cnt=%0d",
rgb_i.name( ), rgb_i1.name( ), uI, uI1, cnt);
end
endmodule
Simulation log:
rgb_i=GREEN rgb_i1=BLUE uI=0xfacecafe uI1=0xcafeface cnt=255
V C S S i m u l a t i o n R e p o r t
1.7 事件(event)数据类型
-> 用于trigger processes(边沿敏感)
wait 要调用内建方法trigger(电平敏感)wait (eventName.triggered);
module et;
event e1, e2, e3;
initial begin
#10;
fork
-> e1;
-> e2;
-> e3;
join
end
always @(e1)
$display("event e1 triggered at time %0t",$time);
always @(e2)
$display("event e2 triggered at time %0t",$time);
always @(e3)
$display("event e3 triggered at time %0t",$time);
endmodule
Simulation log:
event e1 triggered at time 10
event e2 triggered at time 10
event e3 triggered at time 10
V C S S i m u l a t i o n R e p o r t
1.8 数据casting
将一个数据类型转换成另一个类型。
module Cast;
real rNum;
int iNum;
string s1 = "hello";
logic [7:0] A1;
logic signed [7:0] A2;
initial begin
rNum = (2.3 * 3.2);
//real to int casting
$display("\n real to int casting");
iNum = int'(rNum); // or iNum = int'(2.3 * 3.2);
//lose precision
$display("real value is %f", rNum);
$display("int value is %0d",iNum);
$display("\n Signed casting");
iNum = -10;
rNum = signed'(iNum);
$display("real value is %f", rNum);
$display("int value is %0d",iNum);
$display("\n Unsigned casting");
iNum = -10;
rNum = unsigned'(iNum);
$display("real value is %f", rNum);
$display("int value is %0d", iNum);
A1 [0 +: 8] = unsigned'(-4); //A1 = A1[7:0]
A2 = signed'(4'b1100);
$display("\n A1 = %b A2 = %0d", A1, A2);
//String to int casting
$display("\n String to int casting");
iNum = int'(s1);
$display("String s1 = %0p int iNum=%0d",s1,iNum);
end
endmodule
Simulation log:
real to int casting
real value is 7.360000
int value is 7
Signed casting
real value is -10.000000
int value is -10
Unsigned casting
real value is 4294967286.000000
int value is -10
A1 = 11111100 A2 = -4
String to int casting
String s1 = "hello" int iNum=1701604463
V C S S i m u l a t i o n R e p o r t