uvm_event的变量传递
uvm_event可以传递变量,但是变量需要为uvm_object类型,对于package,建议类型向下转换,直接传递uvm_object,并在另一端解析
https://www.edaplayground.com/x/RhYc
module testbench;
class class1 extends uvm_object;
`uvm_object_utils(class1)
int a;
function new(string name = "class1");
super.new(name);
endfunction
endclass
initial begin
class1 copy;
uvm_event event1;
event1=uvm_event_pool::get_global("event000");
copy = class1::type_id::create("copy");
copy.a = 10;
#1;
event1.trigger(copy);
$display("start trigger");
end
initial begin
class1 copy;
uvm_object copy1;
uvm_event event1;
event1=uvm_event_pool::get_global("event000");
$display("start wait");
event1.wait_trigger_data(copy1);
$cast(copy, copy1);
$display("get a %0d", copy.a);
end
initial begin
#10;
end
endmodule
输出:
start wait
start trigger
get a 10
查看软链接的指向
使用readlink命令,-f 选项可以递归跟随给出文件名的所有符号链接
readlink /usr/bin/awk ----> 其实这个还是一个符号连接
grep只打印匹配的数据
使用-o命令
grep -o 按照正则表达式只打印匹配的数据
grep -o 'sh[0-9]\{6\}' infile
grep -o 'sz[0-9]\{6\}' infile
并行进程的串行化--构建进程池
注意中途引入了变量k,该变量k替换了变量i,使得数字真正递增,直接使用变量i,,将导致每个进程中的a的值变成10,且进程池中没有信息。
刚创建完毕后,进程打印的结果队列是空的,等到队列启动后,进程队列才有数据。
随后将所有进程队列挂起,逐个恢复进程,等进程执行完毕后再执行下一个进程。
module testbench();
class a;
function new();
endfunction
process proc_queue[10];
task start();
int i;
int a;
for(i = 0; i< 10; i ++) begin
int k = i;
fork begin
proc_queue[k] = process::self();
#10;
a = k;
$display("%0d", a);
$display("time %t", $time);
end join_none
end
$display("qqqq %p", proc_queue);
for (i = 0; i < 10; i ++)
wait( proc_queue[i] != null );
for (i = 0; i < 10; i ++)
proc_queue[i].suspend();
$display("qqqq %p", proc_queue);
for(i = 0; i< 10; i ++) begin
proc_queue[i].resume();
proc_queue[i].await();
end
endtask
endclass
initial begin
a xx= new();
xx.start();
#30;
end
endmodule
输出结果:
qqqq '{null, null, null, null, null, null, null, null, null, null}
qqqq '{{ ref to class process}, { ref to class process}, { ref to class process}, { ref to class process}, { ref to class process}, { ref to class process}, { ref to class process}, { ref to class process}, { ref to class process}, { ref to class process}}
0
time 10
1
time 20
2
time 30
3
time 40
4
time 50
5
time 60
6
time 70
7
time 80
8
time 90
9
time 100
UVM动态复位问题
-
a wait_for_grant on sequencer for sequence has been killed
原因:存在item位于driver的仲裁队列中未被清除
处理:对于支持动态复位的VIP,跳入reset_phase后,立刻调用seqr.stop_sequences()将item从driver队列中删掉。防止item的存在。
https://blog.csdn.net/qiuzhongyu123/article/details/121498199 -
Item_done() called with no outstanding requests. Each call to item_done() must be paired with a previous call to get_next_item()
原因:对于支持动态复位的vip,其driver的驱动过程在main_phase中,直接从main_phase跳转到reset_phase的时候,其driver中的item_done未执行,而又开始了新的事务。
处理:在复位信号拉动以后跳转到reset_phase,然后在reset_phase中需要立刻调用stop_sequences。对于不支持动态复位的VIP,跳入reset_phase后,需要延时,等到item被处理完毕,整个队列中没有数据,再象征性执行stop_sequences。
最后,在reset_phase中取消复位。执行后续的phase。
https://verificationacademy.com/forums/t/doing-x-stop-sequences-is-causing-this-uvm-fatal-item-done-called-with-no-outstanding-requests-each-call-to-item-done-must-be-paired-with-a-previous-call-to-get-next-item/38457
VIP动态复位注意事项
-
AXI的VIP配置,有两种方式,默认会补发,如有需要,改成全部清空
svt_axi_port_configuration::reset_type = EXCLUDE_UNSTARTED_XACT (default value)
复位将终止事务,而已经存在于driver中的事务被暂停,等到复位取消后继续发送
svt_axi_port_configuration::reset_type reset_type = RESET_ALL_XACT
复位将终止事务,而已经存在于driver中的事务被清空,等到复位取消后继续发送 -
APB-VIP的复位
需要在base_test中调用其reset方法,否则在中途动态复位,可能报告意料之外的问题
task reset_phase(uvm_phase phase);
phase.raise_objection(this, "Resetting regmodel");
regmodel.reset();
phase.drop_objection(this);
endtask
- AXI stream的复位特性
有些VIP是不支持动态复位的,但是仍然需要调试出复位的场景,则需要手动实现复位。
不支持动态复位,可能意味着其driver使用run_phase而不是main_phase,并不会实现phase跳转。
因此,在复位的时候,需要跳转到reset_phase后,等待一段时间,保证其item_done执行结束,再开始执行诸如stop_sequences的函数。