2.10.3 联合(union)
(待续)
3.5.2 从函数中返回一个数组
(待续)
4.3 激励时序
(待续)
4.4 接口的驱动和采样
(待续)
4.8 SystemVerilog断言
(待续)
5.14.2 在任务中修改句柄
1、当你想修改参数的值的时候,需要在方法的参数前面加上ref关键词,尤其是句柄。(ref参数有一个好处是在任务里可以对其进行修改而且修改结果对调用它的函数随时可见)
修改句柄——对句柄使用new()
修改对象——将对象的变量重新赋值
若你想在方法中修改句柄,那么必须加ref,若只是修改对象,可以不用加ref。
不加ref,方法对句柄的修改在主程序中不可见,也就不知道句柄被new()了,调用该句柄的对象时会失败,因为在主程序中该句柄仍然是null。
不加ref修改对象是可以的,如下例,主程序中new()创建了一个对象,而句柄是指向对象的指针,传递的是句柄,transmit中也指向了对象,所以transmit中可以对该对象进行修改。
Task transmit(Transcation t);
Cbbus.rx_data <= t.data;
t.stats.startT = $time; //在任务中,改变了对象
endtask
trancation t;
initilal beign
t = new();
t.addr = 42;
transmit(t);
end
2、当你想创建多个对象时,应该在循环中,new()多个对象,而不是先new()对象再循环发送事物。
5.15 对象的复制
1.使用new操作符复制一个对象——简易复制(shallow copy)
你定义的任何new()函数都不会被调用。
Transaction src,dst;
src = new() //
dst = new src //复制
局限:如果类中包含一个指向另外一个类的句柄,那么只有最高一级的对象被new复制(包括该句柄),下层的对象都不会被复制。这样会出现意想不到的错误。当前类中变量和句柄被复制,这样两个句柄都指向另外一个类的对象statistic,但是statistic没有被复制。如果其中一个transaction对象,修改了statistic对象值,会影响到另一个transaction看到statistic的值。
6.3.2 检查随机化(randomize)的结果
除了使用断言来检查随机化的结果,还可以宏定义一个语句来进行检查,输出有用的错误信息,并结束仿真。
绿皮书的英文版中很多地方用的这个来检查。
6.4 约束
约束块可以像类外的方法定义一样,定义在类的外面
class C;
rand int x;
constraint c1; //隐式形式
extern constraint c2; //显式形式
endclass
constraint C::c1{
x inside {
0,1};}
constraint C::c2{
x >= 0;}
如果使用约束原型的隐式形式,则对应的外部约束块可以有,也可以没有,没有则为空约束。
如果使用约束原型的显式形式,则必须有对应的外部约束块,没有的话会报错。
6.4.7 条件约束和相等约束
a -> b //(!a || b)
当a为true时,b必为true;
当a为false时,b可能为true,也可能为false。
可以正推也可以反推。
a和b可以是表达式,判断其为true或false即可。
例:
rand bit a,b;
constraint c{
`(a==1)`->(b==1);}
如果在上例中再加入一个约束{b==0}
,那么可知约束c中(b==1)
是false的,可以推出(a==1)
也是false的,则a应该为0。
如果加入的约束是{b==1}
,那么可知约束c中(b==1)
是true的,可以推出(a==1)
可能是true的,也可能是false的,则a可能为0或1。
也可见书中例6.25和例6.26。
a <-> b //相等约束
当a为true时,b也为true;
当a为false时,b也为false,
6.5 解的概率
(待续)
6.13.5 产生具有唯一元素值的随机数组
为什么例6.59中的数组没有使用rand,而例6.61的数组使用了rand?
其原因可能是上例中使用的是固定数组,只能随机化其内容,而其内容又是通过randc辅助类来产生的,故不用rand来修饰数组;下例中使用的是动态数组,可以对其长度或内容进行随机化,所以使用rand来修饰。
为什么例6.59使用的是pre_randomize,而例6.61使用的是post_randomize?
上例中LittleUniqueArray类中没有rand变量,randomize()不会成功,若使用post_randomize()来将随机值赋给数组元素是不会执行的,因此在pre_randomize()中进行赋值;而下例中有rand变量,randomize()会成功,若在pre_randomize()中进行赋值,randomize()后会将其覆