目录
第二章
real 、 shortreal 数据类型
字符串文本与字符串类型
字符串函数:
len()
putc()
getc()
toupper()
tolower()
compare()
icompare()
substr(int i, int j)
atoi(), atohex(), atooct(), atobin()
atoreal()
结构体与联合体(struct union)
结构体
联合体union
浅拷贝与深拷贝
第六章 随机化
随机数函数
随机或禁止随机个别变量
随机化句柄数组
program
第七章 线程及线程间的通信
循环里的fork...join_none 解析_Future Chaser的博客-CSDN博客
第二章
real 、 shortreal 数据类型
real数据类型来自于Verilog-2001,与C语言中的double数据类型相同。shortreal数据类型是一个SystemVerilog数据类型,与C语言中的float数据类型相同。
double : 双精度数,64位,有15位小数。
shortreal : 单精度数,32位,有6位小数。
字符串文本与字符串类型
- 字符串文本是一个压缩数组(宽度是8位的整数倍),是以对应的ascii码值存储,每个字母对应一个字节。
- 一个字符串文本可以赋值到一个整数类型。如果尺寸不同,它会进行右调整,并且在必要的时候在左侧进行截短或者在左侧填补0。
byte c = "A"; // 将c赋值为”A” bit [10:0] a = "\x41"; // 将a赋值为’b000_0100_0001 bit [1:4][7:0] h = "hello"; // 将h赋值为”ello”
- 一个字符串文本可以被赋值到一个非压缩字节数组。如果尺寸不同,它会进行左调整。
- string类型的变量具有任意的长度,它们可以动态地改变大小以便容纳任意字符串。但不能送给到整型压缩数组变量。
字符串函数:
len()
function int len():
- str.len()返回字符串的长度,也就是字符串中字符的数目(不包括任何终结字符)。
- 如果str是"",那么str.len()返回0。
putc()
task putc(int i, string s) task putc(int i, byte c)
- str.putc(i, c)将str中的第i个字符替换成指定的integral值;
- str.putc(i, s)将str中的第i个字符替换成s中的第一个字符;
- s可以是赋值为一个字符串的任何表达式;
- putc不会改变str的尺寸,如果i < 0或i >= str.len(),那么str不会发生改变;
注意:str.putc(j, x)在语义上等价于str[j] = x。
getc()
function int getc(int i)
- str.getc(i)返回str中的第i个字符的ASCII码值;
- 如果i < 0或i >= str.len(),那么str.getc(i)返回0;
注意:x = str.getc(i)在语义上等价于x = str[j]。
toupper()
function string toupper()
- str.toupper()返回一个字符串并将str中的字符转换成大写形式;
- str不会发生变化;
tolower()
function string tolower()
- str.tolower()返回一个字符串并将str中的字符转换成小写形式;
- str不会发生变化;
compare()
function int compare(string s)
- str.compare (s)将str与s进行比较,就像ANSI C strcmp函数一样,并且包含嵌入的空字节
icompare()
function int icompare(string s)
- str.icompare(s)将str与s进行比较,就像ANSI C strcmp函数一样,但这种比较是大小写敏感的并且包含嵌入的空字节;
substr(int i, int j)
function int substr(int i, int j)
- str.substr (i, j)返回一个由str中位置i到位置j之间的字符组成的一个新的字符串;
- 如果i < 0, j < i, 或者j >= str.len(),那么substr()返回""(空字符串)。
atoi(), atohex(), atooct(), atobin()
function integer atoi() function integer atohex() function integer atooct() function integer atobin()
- str.atoi()返回一个str中由ASCII码字符表示的十进制数。例如:
str = “123”; int i = str.atoi(); // 将i赋值为123
在转换过程中会扫描所有的前几位阿拉伯数字以及下划线字符(_),只要遇到任何其它字符或到达字符串的结尾则停止扫描。它不会分析整数文本的完整语法(符号、尺寸、撇号、基)。
- str.atohex()将字符串解释成十六进制数;
- str.atooct()将字符串解释成八进制数;
- str.atobin()将字符串解释成二进制数;
atoreal()
function real atoreal()
- str.atoreal()返回一个str中由ASCII码字符表示的实数。
转换过程会分析实数常量的Verilog语法。只要它遇到与这个语法不一致的任何字符,或到达字符串的尾部则停止扫描。如果没有遇到阿拉伯数字则返回0。
3.7.11 itoa() - IEEE SystemVerilog 3.1a 语言参考手册 - 开发文档 - 文江博客
结构体与联合体(struct union)
结构体
- 一个结构体可以作为一个整体赋值,并且可以作为一个整体向/从一个函数或任务传递。
- 一个压缩结构体包含了位域,它们在存储器中被无缝地压缩在一起。这也就意味着,它们可以方便地转换到位向量,或从位向量转换。一个非压缩结构体具有独立于实现的压缩形式,通常与C编译器相匹配。
- 与压缩数组类似,在使用算术和逻辑操作符时,一个压缩结构体可以当作一个整体使用。第一个指定的成员成为最高有效位,后续的成员以降序排列。结构体在声明的时候可以使用packed关键字,根据期望的算术行为,packed关键字之后可以跟着signed或unsigned关键字。缺省情况下,结构体是无符号的,unpacked。
- 只要压缩结构体内的数据类型存在4态数据类型,那么整个结构体就被当作是4态数据类型,并且其中的任何2态成员都会使用强制类型转换进行转换。压缩结构体的一个或更多的位可以使用[n-1:0]的编号方法来选择,就好像它是一个压缩数组一样。
- 非整数数据类型(例如real和shortreal)以及非压缩数组不允许在压缩结构体或压缩联合体中使用。
- 在非压缩结构体中不允许使用符号,可以unsigned
联合体union
- 一个压缩联合体所包含的成员只能是压缩结构体、压缩数组或者是整数数据类型,并且所有的成员必须具有相同的尺寸(而对于一个非压缩联合体,其成员可以具有不同的尺寸)。这就可以保证你可以读回作为另外一个成员写入的联合体成员。
- 在使用算术和逻辑操作符时,一个压缩联合体可以当作一个整体使用,并且它的行为由signed或unsigned关键字确定。如果没有显式指明signed或unsigned关键字,那么它缺省是unsigned的。
- 如果一个压缩联合体包含了2态成员和4态成员,那么整个联合体是4态的。此时,如果读取2态成员,那么它具有一个隐式的4态到2态的转换;如果写入2态成员,则具有一个隐式的2态到4态的转换。
- 不允许对联合体变量名直接赋值或其他操作
- 默认unpacked 。无论压缩还是非压缩,成员都共用内存。
- 联合体中声明中具有限定词tagged的联合体声明为标签联合体,它是一个类型检查的联合体。一个普通的(不带有标签的)联合体可以使用一个成员类型的值进行更新,而以另外一个成员类型进行读取,这有可能成为类型漏洞。一个标签联合体既储存了成员值也储存了一个标签,也就是说,使用额外的位来表示当前的成员名字。标签和值仅仅能够通过一个静态的类型检查标签联合体表达式来一起更新。成员值仅仅可以通过与当前标签值一致的类型来读取(也就是成员名)。这样,我们就不可能以一种类型来存储值,而以另外一种类型来错误地解释成员的各位。
参考SV手册
浅拷贝与深拷贝
p126 5.15
简易复制(shallow copy) :
使用new操作符复制。src -= new() ; dst = new src。使用new操作符复制一个对象的时候,他不会调用你自己的new函数。只有变量的值和句柄会被复制。
深拷贝:
为引用的句柄调用构造函数。首先创建一个新的对象(开辟新的空间),再将目标对象的成员变量值拷贝给新对象的成员。如下,对底层对象中也写一个copy函数。
module tb;
typedef class Statistics;
class Transaction;bit [8:0] addr,crc,data[8];Statistics stats;static int count = 0;int id;function new();stats = new();id = count++;endfunctionfunction Transaction copy;copy = new();copy.addr = addr;copy.crc = crc;copy.data = data;copy.stats = this.stats.copy();endfunction endclass class Statistics;int unsigned s;int unsigned t;function Statistics copy();Statistics t = new();t.s = s;t.t = this.t;return t;endfunction endclass
initial beginTransaction t,t1;t = new();t.addr = 'h1111;t.crc = 1;t.stats.s = 'd10;t.stats.t = 'd20;t1 = t.copy();t1.crc = 0;t1.stats.t = 'd30;$display($sformatf("t.addr = %0b;\nt.crc = %0b;\nt.stats.t = %0d;\nt.stats.s = %0d",t.addr,t.crc,t.stats.t,t.stats.s));$display($sformatf("t.count = %0d",t.count));$display($sformatf("\nt1.addr = %0b;\nt1.crc = %0b;\nt1.stats.t1 = %0d;\nt1.stats.s = %0d",t1.addr,t1.crc,t1.stats.t,t1.stats.s));$display($sformatf("t1.count = %0d",t1.count));
end endmodule
第六章 随机化
受约束的随机测试法CRT
类.约束名.contraint_mode(0) 关闭约束
pre or post randomize 函数只能调用其他函数,不能调用消耗时间的任务。
随机数函数
- $random() 平均分布,返回32位有符号随机数;
- $urandom() 平均分布,返回32位无符号随机数;
- $urandom_range() 在指定范围内的平均分布;
范围在[min,max] ,闭区间。如果参数列表的上限小于下限,系统会自动调换。
- $dist_exponential 指数衰落
- $dist_normal 钟型分布
- $dist_poisson 泊松分布
- $dist_uniform 平均分布
随机或禁止随机个别变量
p155 156
constraint c_valid {length > 0;payload.size == length;
}
使用p.c_valid.length.rand_mode(0) 禁止其随机,单独设置值。一般不这么用,直接以等式的方式随机。
p.randomize(length);随机某个变量
随机化句柄数组
p168
如果产生多个随机对象,需要建立随机句柄数组。和整数数组不同,需要在随机化前分配所有的元素,因为随机求解器不会创建对象。
随机的注意事项
constraint中不能用begin end
program
加入program是为了解决tb与rtl信号可能产生的竞争冒险现象。program和module的四个区别:
- module 中可以定义program,反之不行。
- module不可以调用program中的function task,反之可以。
- program中不能例化其他module interface program,也不能包含always块。
- program是inactive时域进行,module是active时域进行。