Q: 下面的用法对吗?
a = b ? a++ : a+2;
A : 上述用法错误,无法生效,VCS不会报错。
a = a++ 这种无法生效,可以if else分开写
if(b==1)
a++;
else
a = a+2;
Q: 声明了port可以不connect吗?
A:对于analysis_port可以,但对于像uvm_blocking_put_port这种一对一的port声明不连接是会报error
Q: sub env的一些建议
A: scoreboard 放在sub env 的外面,方便管控
//top env
function void top_env::build_phase(uvm_phase phase);
...
if(top_cfg.scb_on)begin
top_scb = top_scoreboard::type_id::create("top_scb",this);
top_scb.cfg = top_cfg;
end
endfunction
function void top_env::connect_phase(uvm_phase phase);
...
if(top_cfg.scb_on)begin
sub_env.o_src_agt.monitor.ap.connect(top_scb.tx_trans_fifo.analysis_export);
sub_env.o_vip.ap.connect(top_scb.rx_trans_fifo.analysis_export);
end
endfunction
Q: 在task 或者function中调用assert的注意点
A:参考下面的写法(在assert后面加上else 分支打印error 信息)
assert (a != e) else if (!disable_error) $error("ERROR ....");
Q:verdi 中如何查看信号在一段时间的上升沿个数?
A :先用两个maker 框出一段时间,然后点菜单栏中view -> signal Event Report
如下写法:
//top.sv
initial begin
int rand_q[$] = {1,2,3};
force top.dut_i.a = rand_q[0];
end
上述写法会报error,force 语句不能用在queue成员上;解法如下
//top.sv
initial begin
int rand_q[$] = {1,2,3};
int tmp_value;
tmp_value = rand_q[0];
force top.dut_i.a = tmp_value;
end
在module 中声明的task 和function均为static,如需多次使用建议声明称automatic。
task automatic delay_ns(real val);
integer idx = 0;
while(idx < val)begin
#1ns;
idx++;
end
endtask
Q: 如何查看当前文件的timescale?
A: $printtimescale [ (hierarchical_name) ]; 如果不填hierarchical_name,则打印current scope的timescale.
initial begin
$printtimescale();
end
Q: 如何打印当前信息所在的文件和行数呢?
A:
initial begin
$display("we at %s in line %0d",`__FILE__,`__LINE__);
end
Q: 如何返回字符串?
A:
string s;
s = $psprintf("%s",message);
Q : SV中wait 和@的区别?
A :
wait(event.triggered()) 为电平敏感
当event被触发时,它的状态使event.triggered 一直保持为true.event 无法清除event.triggered的状态;
所以在使用wait(event.triggered())时一定要确保在下次等待前时间可以向前推进;
优点:在wait 和trigger同时发生时,能wait到;
缺点 :在线程多次通知的场景下不一定可以使用;
@event 为边沿敏感
优点:在线程多次通知的场景下可以使用;
缺点:在wait 和trigger同时发生时,能wait不到;
下面是wait hang住的例子:
forever begin
wait(handshake.triggered());
end
这是一个zero delay loop !!!
Q: 如何把打印信息写入文件?
integer log_file
log_file = $fopen($sformatf(“sram%0d_buffer.log”,cc_id),”a+”);
$fwrite(log_file,”%0t”,$realtime);
$fclose(log_file);
Q : 内嵌约束中local::的用法?
A: 在使用内嵌约束时 randomize()with{CONSTRAINT},约束体中的变量名的查找顺序默认是从被随机化对象开始查找的,但如果调用randomize()的函数局部域(local scope)中也有同名变量,那就需要使用local::来显式声明该变量来源于外部函数。
local::只表示域,并不代表句柄,所以可用local::this表示调用randomize()函数的对象。
Argument Passed by Reference cannot be used within fork-join_any/join_none
(在fork join_any/join_none中不能对ref 变量赋值)
The problem is when you pass variable by reference, you have no information about what kind of storage class the variable belongs to in order to be able to extend it's lifetime. You only have the reference to a generic variable type that matches the type of the reference.
A : task可以传递handle,可以把变量定义在cfg class中,传递到task中
class classA
//object that contains the control variables
logic my_variabl;
endclass: classA
class yourclass; //class or another task
classA my_class;
my_class=new();//create object
taskA(my_class);
my_class.my_variabl=0;
task A (input classA my_class);
fork
begin
@my_class.my_variabl;
my_class.my_variabl=1;
end
join_none
endtask;
endclass: yourclass
code习惯其实也算是防御性工作,只是防御的是自己。总结了几条防呆措施:
第一条就是慎用带符号的变量;第二条是警惕浮点数与整数的算术计算;第三条是不要吝惜bit位宽,除了用来给到寄存器的,统统给到32位;第四条是慎用while循环;第五条是警惕"==",条件判断时最好写成"if(3 == a)",此时如果不慎写成"if(3=a)"会报错,反过来"if(a=3)"则不会报错。