SystemVerilog是Verilog的扩展,也用作HDL。 Verilog具有reg和wire数据类型来描述硬件行为。 由于硬件验证可能变得更加复杂和苛刻,因此Verilog中的数据类型不足以开发有效的测试平台和测试用例。 因此,SystemVerilog通过添加更多类似C的数据类型来扩展Verilog,以实现更好的封装和紧凑性。下表中详细列出了在systemverilog中可以使用的数据类型:
以char为例,说明(signed) char与unsigned char之间的区别:
【1】在内存中,char与unsigned char没有什么不同,都是一个字节;
【2】唯一的区别是,char的最高位为符号位,因此char能表示-128~128,unsigned char没有符号位,因此能表示0~255,这个好理解,8个bit,最多256种情况,因此无论如何都能表示256个数字。
如何写注释?
//这是单行注释
/ *这是多行注释。SystemVerilog变量可以保存值SystemVerilog变量可以保存值SystemVerilog变量可以保存值SystemVerilog变量可以保存值
由于该行位于块注释符号内,因此它是注释。
* /
/ *另一个多行注释
//在块注释中嵌套一个单行注释就可以了。
但是一个块注释不能嵌套在另一个块注释中。
* /
SystemVerilog变量可以保存值
以下是element/net可以保持的四个状态:
0 | 低电平 |
---|---|
1 | 高电平 |
x or X | 不定态 |
z or Z | 高阻态 |
如何写浮点数和指数?
设置定点格式。例如2.8或指数格式(例如7.2e6);
module tb;
real pi; // 声明为实型(real)
real freq;
initial begin
pi = 3.14; //存储浮点数
freq = 1e6; //存储指数Casting will perform rounding
$display ("Value of pi = %f", pi)Casting will perform rounding;
$display ("Value of pi = %0.3f", pi);
$display ("Value of freq = %0d", freq);
end
endmodule
Simulation Log
ncsim> run
Value of pi = 3.140000
Value of pi = 3.140
Value of freq = 1000000.000000
ncsim: *W,RNQUIE: Simulation is complete.
什么是SystemVerilog字符串?
// 通过使用“”字符,可以将字符串分成多行
//不会在输出中将字符串拆分为多行
// 结果: New York is an awesome place.So energetic and vibrant.
$display ("New York is an awesome place.
So energetic and vibrant.");
// 可以使用“”将字符串拆分为多行显示
"
/* Result:
New York is an awesome place.
So energetic and vibrant.
*/
$display ("New York is an awesome place.
So energetic and vibrant.");
// 要以整数类型存储字符串文字,每个字符将需要8位
byte myLetter = "D";
bit [7:0] myNewLine = "
";
// "Hello World" 有11个字符,每个字符需要8位
bit [8*17:1] myMessage = "Hello World";
string myMessage2 = "Hello World"; // 使用“字符串”数据类型
什么是结构(structures)?
结构表示存储在一起并通过structure变量引用的数据类型的集合。
// 创建一个结构来存储“ int”和“ real”变量
// 给该结构命名“ s_money”并声明为数据类型,以便根据此数类型的名称创建结构变量
typedef struct {
int coins;
real dollars;
} s_money;
// 创建类型为s_money的结构变量
s_money wallet;
wallet = '{5, 19.75}; // 将值分配给结构变量
wallet = '{coins:5, dollars:19.75};
wallet = '{default:0}; // 所有元素均为 0
wallet = s_money'{int:1, dollars:2}; // 为该类型的所有成员分配默认值
// 创建一个可以容纳3个变量的结构,并使用1对其进行初始化
struct {
int A, B, C;
} ABC = '{3{1}}; // A = B = C = 1
// 分配结构数组
s_money purse [1:0] = '{'{2, 4.25}, '{7,1.5}};
什么是固定大小的数组(arrays)?
数组是一个变量,用于在连续位置存储不同的值。
module tb;
// 固定数组的以下两种表示形式相同
// myFIFO and urFIFO have 8 locations where each location can hold an integer value
// 0,1 | 0,2 | 0,3 | ... | 0,7
int myFIFO [0:7];
int urFIFO [8];
//多维数组
// 0,0 | 0,1 | 0,2
// 1,0 | 1,1 | 1,2
int myArray [2][3];
initial begin
myFIFO[5] = 32'hface_cafe;
myArray [1][1] = 7;
//遍历数组中的每个元素
foreach (myFIFO[i])
$display ("myFIFO[%0d] = 0x%0h", i, myFIFO[i]);
// I遍历多维数组中的每个元素
foreach (myArray[i])
foreach (myArray[i][j])
$display ("myArray[%0d][%0d] = %0d", i, j, myArray[i][j]);
end
endmodule
Simulation Log
ncsim> run
myFIFO[0] = 0x0
myFIFO[1] = 0x0
myFIFO[2] = 0x0
myFIFO[3] = 0x0
myFIFO[4] = 0x0
myFIFO[5] = 0xfacecafe
myFIFO[6] = 0x0
myFIFO[7] = 0x0
myArray[0][0] = 0
myArray[0][1] = 0
myArray[0][2] = 0
myArray[1][0] = 0
myArray[1][1] = 7
myArray[1][2] = 0
ncsim: *W,RNQUIE: Simulation is complete.
无效数据类型(void data_type)
void数据类型表示不存在的数据,可以将其指定为函数和任务的返回类型,以指示没有返回值。
function void display ();
$display ("Am not going to return any value");
endfunction
task void display ();
#10 $display ("Me neither");
endtask
real到int的转换
通过将real(实数型)舍入为最接近的int(整数型)而不是将其截断,将实数转换为整数。 如果小数部分正好是0.5,则将四舍五入为零。 可以使用强制转换或系统任务来指定显式转换。 直接将实值分配给整数类型也将舍入而不是截断。
// Casting will perform rounding
int'(2.0 * 3.0)
shortint'({8'hab, 8'hef})
// Using system tasks will truncate
integer $rtoi ( real_val )
real $itor ( int_val)
SystemVerilog logic and bit
4-state data types
除零(0)和一(1)之外还可以具有不定态(X)和高阻抗(Z)值的类型称为四态类型。 请注意,reg只能像在Always和Initial这样的过程块中被驱动,而wire数据类型只能在assign语句中被驱动。 SystemVerilog引入了一种新的4状态数据类型,称为logic,可以在过程块和连续的赋值语句中进行驱动。 但是,必须将具有多个驱动程序的信号声明为线型(例如wire),以便SystemVerilog可以解析最终值。
logic
module tb;
logic [3:0] my_data; //声明一个4位logic类型变量
logic en; // 声明一个1位logic类型变量
initial begin
$display ("my_data=0x%0h en=%0b", my_data, en); // logic类型的默认值为X
my_data = 4'hB; // logic datatype can be driven in initial/always blocks
$display ("my_data=0x%0h en=%0b", my_data, en);
#1;
$display ("my_data=0x%0h en=%0b", my_data, en);
end
assign en = my_data[0]; // logic datatype can also be driven via assign statements
endmodule
Simulation Log
ncsim> run
my_data=0xx en=x
my_data=0xb en=x
my_data=0xb en=1
ncsim: *W,RNQUIE: Simulation is complete.
2态数据类型x;
在典型的验证测试平台中,在很多情况下我们并不需要所有四个值(0、1,x,z),例如在对具有指定数据包长度的标头的网络数据包进行建模时。 通常是一个数字,但不是X和Z。SystemVerilog添加了许多新的2状态数据类型,这些数据类型只能存储并具有0或1的值。这将有助于更快的仿真,占用更少的内存并且在某些设计中是首选的样式。
当四态值转换为二态值时,任何未知或高阻抗位均应转换为零。
最重要的2状态数据类型是在测试平台中最常使用的位。 位类型的变量可以是0或1,代表单个位。 应该提供从MSB到LSB的范围,以使其表示并存储多个位。
bit
module tb;
bit var_a; // 声明类型为“ bit”的1位变量
bit [3:0] var_b;
logic [3:0] x_val; //声明“logic”类型的4位变量
initial begin
// “bit”数据类型的初始值为0
$display ("Initial value var_a=%0b var_b=0x%0h", var_a, var_b);
// 分配新值并显示变量以查看其获取新值
var_a = 1;
var_b = 4'hF;
$display ("New values var_a=%0b var_b=0x%0h", var_a, var_b);
//如果为“bit”类型变量分配的值大于它可以容纳的值,则最左边的位将被截断。在这种情况下,var_b只能容纳4位,因此'h481a被截断,var_b截断后仅剩'ha;
var_b = 16'h481a;
$display ("Truncated value: var_b=0x%0h", var_b);
// 如果logic类型或任何4状态变量将其值赋给“bit”类型变量,则X和Z将转换为0
var_b = 4'b01zx;
$display ("var_b = %b", var_b);
end
endmodule
Simulation Log
ncsim> run
Initial value var_a=0 var_b=0x0
New values var_a=1 var_b=0xf
Truncated value: var_b=0xa
var_b = 0100
ncsim: *W,RNQUIE: Simulation is complete.
参考文献:
【1】https://editor.csdn.net/md?articleId=104438622