Le vent se lève, il faut|

大浪淘沙、

园龄:7年1个月粉丝:49关注:19

日常记录(62)域、phase、TLM

域的自动化

copy

copy 方法的结果如下代码:
首先是注册,注意copy方法的调用者是被赋值的对象,参数是来源的对象。
do_copy是在copy后自动执行的方法,是一个回调函数。

点击查看代码
module taa ();
import uvm_pkg::*;
`include "uvm_macros.svh"
class box extends uvm_object;
// data or class properties
int length=10;
typedef enum bit[3:0] {
BLACK,
WHITE,
RED,
BLUE
} color_t;
color_t color=BLUE;
int width=5;
string name="box_base";
`uvm_object_utils_begin(box)
`uvm_field_int(length, UVM_ALL_ON)
`uvm_field_int(width, UVM_ALL_ON)
`uvm_field_enum(color_t, color, UVM_ALL_ON)
`uvm_object_utils_end
function void do_copy(uvm_object rhs);
length = 100;
endfunction: do_copy
// initialization
function new();
endfunction : new
endclass : box
initial begin
box box1 = new();
box box2 = new();
box1.length = 5;
box1.width = 3;
box2.copy(box1);
box1.print();
box2.print();
end
endmodule
点击查看代码
--------------------------------
Name Type Size Value
--------------------------------
<unnamed> box - @455
length integral 32 'h5
width integral 32 'h3
color color_t 4 BLUE
--------------------------------
--------------------------------
Name Type Size Value
--------------------------------
<unnamed> box - @456
length integral 32 'h64
width integral 32 'h3
color color_t 4 BLUE
--------------------------------

compare

基本原理同copy,但是以下代码自定义了uvm_comparer,然后在compare的过程中将其传入,可修改显示的不匹配个数控制。

点击查看代码
module taa ();
import uvm_pkg::*;
`include "uvm_macros.svh"
class box extends uvm_object;
// data or class properties
int length=10;
typedef enum bit[3:0] {
BLACK,
WHITE,
RED,
BLUE
} color_t;
color_t color=BLUE;
int width=5;
string name="box_base";
`uvm_object_utils_begin(box)
`uvm_field_int(length, UVM_ALL_ON)
`uvm_field_int(width, UVM_ALL_ON)
`uvm_field_enum(color_t, color, UVM_ALL_ON)
`uvm_object_utils_end
endclass : box
initial begin
box box1 = new();
box box2 = new();
uvm_comparer cmpr = new();
cmpr.show_max = 2;
box1.length = 'h5;
box1.width = 'h3;
box2.length = 'h51;
box2.width = 'h11;
if(box2.compare(box1, cmpr)) begin
$info("same");
end else begin
$info("not same");
end
end
endmodule
点击查看代码
UVM_INFO @ 0: reporter [MISCMP] Miscompare for <object>.length: lhs = 'h51 : rhs = 'h5
UVM_INFO @ 0: reporter [MISCMP] Miscompare for <object>.width: lhs = 'h11 : rhs = 'h3
UVM_INFO @ 0: reporter [MISCMP] 2 Miscompare(s) for object @455 vs. @456
Info: "taa.sv", 36: taa: at time 0
not same

print

在调用print的过程中,使用uvm_default_printer,默认为table的形式,可以将其它的printer赋值到uvm_default_printer,实现打印格式控制。

uvm_default_printer
uvm_default_line_printer
uvm_default_tree_printer

此外,同uvm_comparer一样,可以定义uvm_table_printer等,修改其中的knobs.full_name,调用print时候传入,完成打印过程控制。

phase概念

image

内部概念

schedule是包括phase的关联数组
domain内置一个schedule
schedule所属类uvm_schedule和domain所属类uvm_domain都是继承于uvm_phase

编写规范

由于未来可能对run_phase中的reset、configure、main、shutdown的废除,建议使用run_phase,并使用fork-join语句块实现同步。

OVM的历史遗留变量传递

传递方法

不同于uvm的set_config_db,ovm使用set_config_int、set_config_string、get_config_int、get_config_string等方法

隐式get

可能不用get函数也可获得set过的数据。
但是依赖于具体的field_automation、然后需要调用suoer.build_phase,即可匹配同名,自动获取值。

实例代码

以下代码实现了ovm的数值传递。

  • string类型的数据没有注册到automation,是手动set和get的
  • int的val1类型是注册到automation,然后通过调用父类自动get的,因此前后都是100
  • int的val3类型是注册到automation,但是值和字符串的域不一样,无法赋值,只能通过手动方式获取值
    另外,如果get_config_int改成了get_config_string,类型不一致不会报错,但是无法获得值。
点击查看代码
module set_config_variable;
import uvm_pkg::*;
`include "uvm_macros.svh"
class comp1 extends uvm_component;
int val1 = 1;
string str1 = "null";
int val2 = 123;
`uvm_component_utils_begin(comp1)
`uvm_field_int(val1, UVM_ALL_ON)
`uvm_field_int(val2, UVM_ALL_ON)
`uvm_component_utils_end
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
`uvm_info("SETVAL", $sformatf("val1 is %d before get", val1), UVM_LOW)
`uvm_info("SETVAL", $sformatf("val2 is %d before get", val2), UVM_LOW)
`uvm_info("SETVAL", $sformatf("str1 is %s before get", str1), UVM_LOW)
get_config_string("str1", str1);
/* get_config_int("val3", val2); */
`uvm_info("SETVAL", $sformatf("val1 is %d after get", val1), UVM_LOW)
`uvm_info("SETVAL", $sformatf("val2 is %d after get", val2), UVM_LOW)
`uvm_info("SETVAL", $sformatf("str1 is %s after get", str1), UVM_LOW)
endfunction
endclass
class test1 extends uvm_test;
`uvm_component_utils(test1)
comp1 c1;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
uvm_component::print_config_matches = 1;
set_config_int("c1", "val1", 100);
set_config_string("c1", "str1", "comp1");
set_config_int("c1", "val3", 11);
c1 = comp1::type_id::create("c1", this);
endfunction
endclass
initial begin
run_test("test1");
end
endmodule

信息打印

信息打印控制

以下代码实现了打印信息的控制过程。
对于写入文件,建立好文件,然后调用set_report_default_file。
然后通过控制函数,实现对打印信息的控制过程。控制函数会有很多很多。

点击查看代码
module object_report;
import uvm_pkg::*;
`include "uvm_macros.svh"
class test1 extends uvm_test;
integer f;
`uvm_component_utils(test1)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
f = $fopen("logfile", "w");
set_report_default_file(f);
set_report_severity_action(UVM_INFO, UVM_DISPLAY | UVM_LOG);
set_report_severity_action(UVM_WARNING, UVM_DISPLAY | UVM_LOG);
set_report_severity_action(UVM_ERROR, UVM_DISPLAY | UVM_LOG | UVM_COUNT);
set_report_severity_action(UVM_FATAL, UVM_DISPLAY | UVM_LOG | UVM_STOP);
set_report_verbosity_level(UVM_LOW);
endfunction
task run_phase(uvm_phase phase);
uvm_report_info("RUN", "info1", UVM_MEDIUM);
uvm_report_info("RUN", "info2", UVM_LOW);
uvm_report_warning("RUN", "warning1", UVM_LOW);
uvm_report_error("RUN", "error1", UVM_LOW);
uvm_report_error("RUN", "error2", UVM_HIGH);
uvm_report_error("RUN", "error3", UVM_LOW);
endtask
function void report_phase(uvm_phase phase);
$fclose(f);
endfunction
endclass
initial begin
run_test("test1");
end
endmodule

打印前控制的HOOK

如下:
默认UVM_LOW以下打印,然后是UVM_CALL_HOOK使能。、

点击查看代码
module report_hook;
import uvm_pkg::*;
`include "uvm_macros.svh"
class test1 extends uvm_test;
integer f;
`uvm_component_utils(test1)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
set_report_severity_action(UVM_ERROR, UVM_DISPLAY | UVM_CALL_HOOK);
set_report_verbosity_level(UVM_LOW);
endfunction
task run_phase(uvm_phase phase);
uvm_report_info("RUN", "info1", UVM_MEDIUM);
uvm_report_info("RUN", "info2", UVM_LOW);
uvm_report_warning("RUN", "warning1", UVM_LOW);
uvm_report_error("RUN", "error1", UVM_LOW);
uvm_report_error("RUN", "error2", UVM_HIGH);
uvm_report_error("RUN", "error3", UVM_LOW);
endtask
function bit report_hook(string id, string message, int verbosity, string filename, int line);
uvm_report_info("RPTHOOK", $sformatf("%s : %s", id, message), UVM_LOW);
return 1;
endfunction
function bit report_error_hook(string id, string message, int verbosity, string filename, int line);
uvm_report_info("ERRHOOK", $sformatf("%s : %s", id, message), UVM_LOW);
return 1;
endfunction
endclass
initial begin
run_test("test1");
end
endmodule

image

uvm组件

driver的seq

uvm_seq_item_pull_port seq_item_port

uvm_algorithm_comparator

更高端的通用比较类,需要实现compare、conver2string、transform函数。

双向通信

点击查看代码
module tlm_transport;
import uvm_pkg::*;
`include "uvm_macros.svh"
class itrans extends uvm_transaction;
int id;
int data;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
class otrans extends uvm_transaction;
int id;
int data;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
endclass
class comp1 extends uvm_component;
uvm_blocking_transport_port #(itrans, otrans) bt_port;
`uvm_component_utils(comp1)
function new(string name, uvm_component parent);
super.new(name, parent);
bt_port = new("bt_port", this);
endfunction
task run_phase(uvm_phase phase);
itrans itr;
otrans otr;
int trans_num = 6;
for(int i=0; i<trans_num; i++) begin
itr = new("itr", this);
itr.id = i;
itr.data = 'h10 + i ;
this.bt_port.transport(itr, otr);
`uvm_info("TRSPT", $sformatf("put itrans id: 'h%0x , data: 'h%0x | get otrans id: 'h%0x , data: 'h%0x ",
itr.id, itr.data, otr.id, otr.data), UVM_LOW)
end
endtask
endclass
class comp2 extends uvm_component;
uvm_blocking_transport_imp #(itrans, otrans, comp2) bt_imp;
`uvm_component_utils(comp2)
function new(string name, uvm_component parent);
super.new(name, parent);
bt_imp = new("bt_imp", this);
endfunction
task transport(itrans req, output otrans rsp);
rsp = new("rsp", this);
rsp.id = req.id;
rsp.data = req.data << 8;
endtask
endclass
class env1 extends uvm_env;
comp1 c1;
comp2 c2;
`uvm_component_utils(env1)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
c1 = comp1::type_id::create("c1", this);
c2 = comp2::type_id::create("c2", this);
endfunction: build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
c1.bt_port.connect(c2.bt_imp);
endfunction: connect_phase
endclass
class test1 extends uvm_test;
`uvm_component_utils(test1)
env1 env;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
env = env1::type_id::create("env", this);
endfunction
endclass
initial begin
run_test("test1");
end
endmodule
// UVM_INFO @ 0: reporter [RNTST] Running test test1...
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h0 , data: 'h10 | get otrans id: 'h0 , data: 'h1000
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h1 , data: 'h11 | get otrans id: 'h1 , data: 'h1100
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h2 , data: 'h12 | get otrans id: 'h2 , data: 'h1200
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h3 , data: 'h13 | get otrans id: 'h3 , data: 'h1300
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h4 , data: 'h14 | get otrans id: 'h4 , data: 'h1400
// UVM_INFO @ 0: uvm_test_top.env.c1 [TRSPT] put itrans id: 'h5 , data: 'h15 | get otrans id: 'h5 , data: 'h1500

TLM2.0

特点

双向通信,支持blocking和nonblocking两种方式。

blocking方式需要在一次传输过程中request和response,实现方法为:b_transport,对应任务:

task b_transport(trans, delay)

nonblocking方式将request和response分为两个独立的单向传输,两个传输整体视为一个传输过程。
实现方法为:nb_transport_fw, nb_transport_bw。
对应函数:

function uvm_tlm_sync_e nb_transport_fw(trans, p, delay);
function uvm_tlm_sync_e nb_transport_bw(trans, p, delay);

trans:uvm_tlm_generic_payload类,唯一的trans
p为:做状态同步的部分
fw:request发送通道
bw: response发送通道
delay: uvm_til_time类,标定延迟时间

端口

端口是继承于uvm_port_base的,
image

blocking方式的代码

点击查看代码
module tlm2_socket;
import uvm_pkg::*;
`include "uvm_macros.svh"
class comp1 extends uvm_component;
uvm_tlm_b_initiator_socket b_ini_skt;
`uvm_component_utils(comp1)
function new(string name, uvm_component parent);
super.new(name, parent);
b_ini_skt = new("b_ini_skt", this);
endfunction
task run_phase(uvm_phase phase);
byte unsigned data[] = {1, 2, 3, 4, 5, 6, 7, 8};
uvm_tlm_generic_payload pl = new("pl");
uvm_tlm_time delay = new("delay");
pl.set_address('h0000F000);
pl.set_data_length(8);
pl.set_data(data);
pl.set_byte_enable_length(8);
pl.set_write();
delay.incr(0.3ns, 1ps);
`uvm_info("INITRSP", $sformatf("initiated a trans at %0d ps", $realtime()), UVM_LOW)
b_ini_skt.b_transport(pl, delay);
endtask
endclass
class comp2 extends uvm_component;
uvm_tlm_b_target_socket #(comp2) b_tgt_skt;
`uvm_component_utils(comp2)
function new(string name, uvm_component parent);
super.new(name, parent);
b_tgt_skt = new("b_tgt_skt", this);
endfunction
task b_transport(uvm_tlm_generic_payload pl, uvm_tlm_time delay);
`uvm_info("TGTTRSP", $sformatf("received a trans at %0d ps", $realtime()), UVM_LOW)
pl.print();
#(delay.get_realtime(1ps));
pl.set_response_status(UVM_TLM_OK_RESPONSE);
`uvm_info("TGTTRSP", $sformatf("completed a trans at %0d ps", $realtime()), UVM_LOW)
pl.print();
endtask
endclass
class env1 extends uvm_env;
comp1 c1;
comp2 c2;
`uvm_component_utils(env1)
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
super.build_phase(phase);
c1 = comp1::type_id::create("c1", this);
c2 = comp2::type_id::create("c2", this);
endfunction: build_phase
function void connect_phase(uvm_phase phase);
super.connect_phase(phase);
c1.b_ini_skt.connect(c2.b_tgt_skt);
endfunction: connect_phase
endclass
class test1 extends uvm_test;
`uvm_component_utils(test1)
env1 env;
function new(string name, uvm_component parent);
super.new(name, parent);
endfunction
function void build_phase(uvm_phase phase);
env = env1::type_id::create("env", this);
endfunction
task run_phase(uvm_phase phase);
super.run_phase(phase);
phase.raise_objection(this);
#1us;
phase.drop_objection(this);
endtask
endclass
initial begin
run_test("test1");
end
endmodule

运行命令

vcs -sverilog -R -ntb_opts uvm-1.1 -timescale="1ps/1ps" taa.sv

运行结果:

点击查看代码
UVM_INFO @ 0: reporter [RNTST] Running test test1...
UVM_INFO taa.sv(22) @ 0: uvm_test_top.env.c1 [INITRSP] initiated a trans at 0 ps
UVM_INFO taa.sv(35) @ 0: uvm_test_top.env.c2 [TGTTRSP] received a trans at 0 ps
-------------------------------------------------------------------------------
Name Type Size Value
-------------------------------------------------------------------------------
pl uvm_tlm_generic_payload - @505
address integral 64 'hf000
command uvm_tlm_command_e 32 UVM_TLM_WRITE_COMMAND
response_status uvm_tlm_response_status_e 32 UVM_TLM_INCOMPLETE_RESPONSE
streaming_width integral 32 'h0
data darray(byte) 8 -
[0] byte 8 'h01 x
[1] byte 8 'h02 x
[2] byte 8 'h03 x
[3] byte 8 'h04 x
[4] byte 8 'h05 x
[5] byte 8 'h06 x
[6] byte 8 'h07 x
[7] byte 8 'h08 x
extensions aa(obj,obj) 0 -
-------------------------------------------------------------------------------
UVM_INFO taa.sv(39) @ 300: uvm_test_top.env.c2 [TGTTRSP] completed a trans at 300 ps
-------------------------------------------------------------------------
Name Type Size Value
-------------------------------------------------------------------------
pl uvm_tlm_generic_payload - @505
address integral 64 'hf000
command uvm_tlm_command_e 32 UVM_TLM_WRITE_COMMAND
response_status uvm_tlm_response_status_e 32 UVM_TLM_OK_RESPONSE
streaming_width integral 32 'h0
data darray(byte) 8 -
[0] byte 8 'h01 x
[1] byte 8 'h02 x
[2] byte 8 'h03 x
[3] byte 8 'h04 x
[4] byte 8 'h05 x
[5] byte 8 'h06 x
[6] byte 8 'h07 x
[7] byte 8 'h08 x
extensions aa(obj,obj) 0 -
-------------------------------------------------------------------------
UVM_INFO /home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.1/base/uvm_objection.svh(1273) @ 1000000: reporter [TEST_DONE] 'run' phase is ready to proceed to the 'extract' phase
--- UVM Report Summary ---
** Report counts by severity
UVM_INFO : 5
UVM_WARNING : 0
UVM_ERROR : 0
UVM_FATAL : 0
** Report counts by id
[INITRSP] 1
[RNTST] 1
[TEST_DONE] 1
[TGTTRSP] 2
$finish called from file "/home/synopsys/vcs-mx/O-2018.09-1/etc/uvm-1.1/base/uvm_root.svh", line 439.
$finish at simulation time 1000000
posted @   大浪淘沙、  阅读(259)  评论(0编辑  收藏  举报
历史上的今天:
2019-02-24 蚂蚁森林自动收能量的最新脚本
评论
收藏
关注
推荐
深色
回顶
收起
点击右上角即可分享
微信分享提示