标签:name -- my0 factory uvm type phase my UVM
3. UVM -- factory机制与平台组件构建
3.1. 什么是factory机制
- UVM工厂机制可以使用户在不更改代码的情况下实现不同对象的替换;
- 工厂是UVM的一种数据结构。它的作用范围是整个平台空间,它有且仅有一个实例化对象 (即单实例类)。它是一个 多态构造器,可仅仅使用一个函数让用户实例化很多不同类型的对象。
- 为了使用一个函数而可以返回多种对象,这些对象必须从一个基类扩展而来。
3.2. uvm factory机制的原理及使用
3.2.1 factory机制的运作步骤
(1). factory注册:一般使用宏
宏 | 注册 |
---|---|
`uvm object utils() | 对 uvm object类 进行注册 |
`uvm_component_utils() | 对 uvm_component类 进行注册 |
`uvm object param utils() | 对 object参数化类 进行注册 |
`uvm component param utils() | 对 component参数化类 进行注册 |
宏的作用如下:
-
为注册的类创建一个代理类:type_id
- 这个类在注册类的内部,起到间接实例化对象的代理作用
- 创建一个注册类的对象并将该对象向factory注册
- type_id内建create函数,该函数的任务是根据替换表创建指定类的对象
-
创建一个静态函数get_type()
-
创建一个函数get_object_type(),非静态
(2). 实例化对象:要使用 静态方法 class_name:type_id:create()
来代替new实例化对象;
create()会按以下步骤执行:
- 调用factory的get函数获取factory对象;
- 以当前所要创建对象的类名为索引,在factory的替换列表中查询该类 该对象是否被替换;
- 如果替换列表中没有相关条目,则调用当前类的new(0函数;如果有相关条目,则调用替换类的new()函数实例化对象。
(3). 根据具体要求向替换表添加替换条目,override;
(4). 在运行仿真时,UVM会根据这两张表自动的实现factory机制;
3.2.2. 使用factory机制需要注意的几点:
- 用户需要向注册表注册。
- 用户需要向替换表添加项目。
- 被替换对象的类型是替换对象类型的基类。
factory机制与override机制
常用的override函数有两个:
set_type_override_by_type()
set_type_override_by_type(original_class_name::get_type(),target_class_name::get_type());
这个函数的作用是将平台中 所有类型 为“original_.class_name”实例化的对象都被替换成类型为“target_class_name”的对象 -- 全部替换 ;
set_inst_override_by_type()
set_inst_override_by_type("original_inst_path", original_class_name::get_type(), target_class_name:get_type());
这个函数的作用是将平台中 指定路径 的类型为“original_class_name”实例化的对象被替换成类型为“target_class_name”的对象 -- 指定替换,路径越具体,替换越明确;
这两个函数存在于component中,并且一般需要在 build_phase()
中调用。
一个简单平台 -- 添加平台组件
- 平台架构调试,可使用:
uvm_top.print_topology;
-
Makefile
#! all comp sim run clean .PHONY: all comp sim run clean TC ?=my_base_test SEED ?=1234 TOP ?=test_top FILELIST ?=../scripts/filelist.f COMP_OPTS += -sverilog +v2k -full64 COMP_OPTS += -kdb -lca COMP_OPTS += +acc +vpi -debug_access+all COMP_OPTS += -timescale=1ns/1ps COMP_OPTS += -ntb_opts uvm-1.2 COMP_OPTS += +libext+.v+.sv+.svh+.incl COMP_OPTS += +plusarg_save COMP_OPTS += -top $(TOP) COMP_OPTS += -F $(FILELIST) SIM_OPTS += +UVM_TESTNAME=$(TC) SIM_OPTS += +UVM_VERBOSITY=UVM_DEBUG##UVM_LOW SIM_OPTS += +UVM_DUMP_CMDLINE_ARGS SIM_OPTS += +UVM_CONFIG_DB_TRACE SIM_OPTS += +UVM_PHASE_TRACE SIM_OPTS += +UVM_OBJECTION_TRACE SIM_OPTS += +ntb_random_seed=$(SEED) SIM_OPTS += +notimingcheck SIM_OPTS += +nospecify SIM_OPTS += +delay_mode_zero COV_OPTS += -cm cond+line+fsm COV_OPTS += -cm_name $(TC) -cm_dir $(TC).vdb DUMP_OPTS += +fsdb+autoflush+all=on DUMP_OPTS += -ucli -i ../scripts/wave.tcl DUMP_OPTS += +fsdbfile+./wave/$(TC)_$(SEED).fsdb all: comp sim comp: mkdir -p ./wave ./log & \ vcs $(COMP_OPTS) \ -l ./log/comp_$(TC)_$(SEED).log sim: ./simv $(SIM_OPTS) \ $(DUMP_OPTS) \ -l ./log/sim_$(TC)_$(SEED).log rpt_cg: urg -dir *.vdb -report cg_report @echo "coverage report generated in ./cg_report" verdi_cg: verdi -cov -covdir *.vdb/ & verdi_db: verdi -dbdir simv.daidir & verdi_f: verdi -f filelist.f & verdi_wave: verdi -ssf ./wave/*.fsdb & run: vcs -R -sverilog $(TC) clean: rm -rf *.log *.vdb *simv* *.h *.key cg_report csrc vdCovLog clean_all: rm -rf *.log *.vdb *simv* *.h *.key cg_report csrc vdCovLog novas* ./log/* ./wave/* verdiLog
-
test_top
//----------------------------------------------- //@ test_top //@ Version : V0.1 //@ Wesley 2022.04.10 //----------------------------------------------- module test_top; import uvm_pkg::*; `include "uvm_macros.svh" import my_test_pkg::*; logic clk = 0; logic reset_n = 0; //interface my_intf vif(); // DUT - a 16550 UART: dut DUT ( ); // clock/reset always #5ns clk = ~clk; initial begin clk = 0; reset_n = 0; repeat(10) @(posedge clk); reset_n = 1; `uvm_info (" TEST_TOP ", $sformatf("clk = 0x%h , resetn = 0x%h", clk, reset_n), UVM_MEDIUM) end // UVM virtual interface handling and run_test() initial begin // run run_test(); end endmodule: test_top
-
my_base_test
//----------------------------------------------- //@ my_base_test //@ Version : V0.1 //@ Wesley 2022.04.10 //----------------------------------------------- `ifndef my_base_test__SV `define my_base_test__SV class my_base_test extends uvm_test; `uvm_component_utils(my_base_test) my_env m_env; extern function new(string name = "my_base_test", uvm_component parent = null); extern function void build_phase(uvm_phase phase); extern function void connect_phase(uvm_phase phase); extern function void end_of_elaboration_phase(uvm_phase phase); extern virtual task run_phase(uvm_phase phase); extern function void report_phase(uvm_phase phase); extern function void final_phase(uvm_phase phase); endclass: my_base_test function my_base_test::new(string name = "my_base_test", uvm_component parent = null); super.new(name, parent); `uvm_info(get_type_name(), "< 000 > : new ", UVM_DEBUG) endfunction: new function void my_base_test::build_phase(uvm_phase phase); super.build_phase(phase); `uvm_info(get_type_name(), "< 001 > : build_phase ", UVM_DEBUG) m_env = my_env::type_id::create("m_env", this); endfunction: build_phase function void my_base_test::connect_phase(uvm_phase phase); super.connect_phase(phase); endfunction: connect_phase function void my_base_test::end_of_elaboration_phase(uvm_phase phase); uvm_top.print_topology; `uvm_info(get_type_name(), "< 003 > : end_of_elaboration_phase ", UVM_DEBUG) endfunction: end_of_elaboration_phase task my_base_test::run_phase(uvm_phase phase); super.run_phase(phase); phase.raise_objection(this); `uvm_info(get_type_name(), "< 005 > : run_phase ", UVM_DEBUG) #100ns; phase.get_objection().set_drain_time(this, 1000); phase.drop_objection(this); endtask: run_phase function void my_base_test::report_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 008 > : report_phase ", UVM_DEBUG) `uvm_info(get_type_name(), "+-----------------------------------------------+", UVM_DEBUG) `uvm_info(get_type_name(), "+- *** UVM TEST PASSED *** -+", UVM_DEBUG) `uvm_info(get_type_name(), "+-----------------------------------------------+", UVM_DEBUG) `uvm_info(get_type_name(), "+-----------------------------------------------+", UVM_DEBUG) `uvm_info(get_type_name(), "+- *** UVM TEST FAILED *** -+", UVM_DEBUG) `uvm_info(get_type_name(), "+-----------------------------------------------+", UVM_DEBUG) endfunction: report_phase function void my_base_test::final_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 009 > : final_phase ", UVM_DEBUG) endfunction: final_phase `endif // my_base_test__SV
-
env
//----------------------------------------------- //@ my_env //@ Version : V0.1 //@ Wesley 2022.04.10 //----------------------------------------------- `ifndef my_env__SV `define my_env__SV class my_env extends uvm_env; `uvm_component_utils(my_env) my0_agent m0_agent; my_scoreboard m_scb; my_reference m_ref; extern function new(string name = "my_env", uvm_component parent = null); extern function void build_phase(uvm_phase phase); extern function void connect_phase(uvm_phase phase); endclass: my_env function my_env::new(string name = "my_env", uvm_component parent = null); super.new(name, parent); `uvm_info(get_type_name(), "< 000 > : new ", UVM_DEBUG) endfunction: new function void my_env::build_phase(uvm_phase phase); super.build_phase(phase); `uvm_info(get_type_name(), "< 001 > : build_phase ", UVM_DEBUG) m0_agent = my0_agent::type_id::create("m0_agent", this); m_scb = my_scoreboard::type_id::create("m_scb", this); m_ref = my_reference::type_id::create("m_ref", this); endfunction: build_phase function void my_env::connect_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 002 > : connect_phase ", UVM_DEBUG) endfunction: connect_phase `endif // my_env__SV
-
agent
//----------------------------------------------- //@ my0_agent //@ Version : V0.1 //@ Wesley 2022.04.10 //----------------------------------------------- `ifndef my0_agent__SV `define my0_agent__SV class my0_agent extends uvm_agent; `uvm_component_utils(my0_agent) my0_driver m0_drv; my0_monitor m0_mon; my0_sequencer m0_seqr; extern function new(string name = "my0_agent", uvm_component parent = null); extern function void build_phase(uvm_phase phase); extern function void connect_phase(uvm_phase phase); endclass: my0_agent function my0_agent::new(string name = "my0_agent", uvm_component parent = null); super.new(name, parent); `uvm_info(get_type_name(), "< 000 > : new ", UVM_DEBUG) endfunction: new function void my0_agent::build_phase(uvm_phase phase); super.build_phase(phase); `uvm_info(get_type_name(), "< 001 > : build_phase ", UVM_DEBUG) m0_drv = my0_driver::type_id::create("m0_drv", this); m0_seqr = my0_sequencer::type_id::create("m0_seqr", this); m0_mon = my0_monitor::type_id::create("m0_mon", this); endfunction: build_phase function void my0_agent::connect_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 002 > : connect_phase ", UVM_DEBUG) endfunction: connect_phase `endif // my0_agent__SV
-
driver
//----------------------------------------------- //@ my0_driver //@ Version : V0.1 //@ Wesley 2022.04.10 //----------------------------------------------- `ifndef my0_driver__SV `define my0_driver__SV class my0_driver extends uvm_driver#(my0_seq_item); `uvm_component_utils(my0_driver) extern function new(string name = "my0_driver", uvm_component parent = null); extern function void build_phase(uvm_phase phase); extern function void connect_phase(uvm_phase phase); extern task run_phase(uvm_phase phase); endclass: my0_driver function my0_driver::new(string name = "my0_driver", uvm_component parent = null); super.new(name, parent); `uvm_info(get_type_name(), "< 000 > : new ", UVM_DEBUG) endfunction: new function void my0_driver::build_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 001 > : build_phase ", UVM_DEBUG) endfunction: build_phase function void my0_driver::connect_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 002 > : connect_phase ", UVM_DEBUG) endfunction: connect_phase task my0_driver::run_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 005 > : run_phase ", UVM_DEBUG) super.run_phase(phase); endtask: run_phase `endif // my0_driver__SV
-
monitor
//----------------------------------------------- //@ my0_monitor //@ Version : V0.1 //@ Wesley 2022.04.10 //----------------------------------------------- `ifndef my0_monitor__SV `define my0_monitor__SV class my0_monitor extends uvm_monitor; `uvm_component_utils(my0_monitor) extern function new(string name = "my0_monitor", uvm_component parent = null); extern function void build_phase(uvm_phase phase); extern function void connect_phase(uvm_phase phase); extern task run_phase(uvm_phase phase); endclass: my0_monitor function my0_monitor::new(string name = "my0_monitor", uvm_component parent = null); super.new(name, parent); `uvm_info(get_type_name(), "< 000 > : new ", UVM_DEBUG) endfunction: new function void my0_monitor::build_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 001 > : build_phase ", UVM_DEBUG) endfunction: build_phase function void my0_monitor::connect_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 002 > : connect_phase ", UVM_DEBUG) endfunction: connect_phase task my0_monitor::run_phase(uvm_phase phase); `uvm_info(get_type_name(), "< 005 > : run_phase ", UVM_DEBUG) endtask: run_phase `endif // my0_monitor__SV
-
sequencer
//----------------------------------------------- //@ my0_sequencer //@ Version : V0.1 //@ Wesley 2022.04.10 //----------------------------------------------- `ifndef my0_sequencer__SV `define my0_sequencer__SV class my0_sequencer extends uvm_sequencer #(my0_seq_item); `uvm_component_utils(my0_sequencer) function new(string name = "my0_sequencer", uvm_component parent = null); super.new(name, parent); `uvm_info(get_type_name(), "< 000 > : new ", UVM_DEBUG) endfunction: new endclass: my0_sequencer `endif // my0_sequencer__SV
-
reference
//----------------------------------------------- //@ my_reference //@ Version : V0.1 //@ Wesley 2022.04.10 //----------------------------------------------- `ifndef my_reference__SV `define my_reference__SV // Step1 : Create a new class that extends from uvm_scoreboard class my_reference extends uvm_component; `uvm_component_utils (my_reference) // Step2a: Declare and create a TLM Analysis Port to receive data objects from other TB components uvm_blocking_get_port #(my0_seq_item) get_port;//exp_port; uvm_analysis_port #(my0_seq_item) ap; //uvm_analysis_export #(my0_seq_item) analysis_export; function new (string name = "my_reference", uvm_component parent); super.new (name, parent); endfunction // Step2b: Instantiate the analysis port, because afterall, its a class object function void build_phase (uvm_phase phase); //ap = new ("ap", this); //get_port = new ("get_port", this); //analysis_export = new ("analysis_export", this); endfunction // Step3: Define other functions and tasks that operate on the data and call them // Remember, this is the main task that consumes simulation time in UVM virtual task run_phase (uvm_phase phase); my0_seq_item tr; endtask // Step4: [Optional] Perform any remaining comparisons or checks before end of simulation virtual function void check_phase (uvm_phase phase); //... endfunction endclass `endif // my_reference__SV
-
scoreboard
//----------------------------------------------- //@ my_scoreboard //@ Version : V0.1 //@ Wesley 2022.04.10 //----------------------------------------------- `ifndef my_scoreboard__SV `define my_scoreboard__SV class my_scoreboard extends uvm_scoreboard; `uvm_component_utils (my_scoreboard) // Step2a: Declare and create a TLM Analysis Port to receive data objects from other TB components uvm_blocking_get_port #(my0_seq_item) get_port; //uvm_analysis_imp_monitor #(my0_seq_item, my_scoreboard) analysis_imp; function new (string name = "my_scoreboard", uvm_component parent); super.new (name, parent); endfunction // Step2b: Instantiate the analysis port, because afterall, its a class object function void build_phase (uvm_phase phase); //get_port = new ("get_port", this); //analysis_imp = new ("analysis_imp", this); endfunction // Step3: Define other functions and tasks that operate on the data and call them // Remember, this is the main task that consumes simulation time in UVM virtual task run_phase (uvm_phase phase); my0_seq_item tr; endtask // Step4: [Optional] Perform any remaining comparisons or checks before end of simulation virtual function void check_phase (uvm_phase phase); //... endfunction endclass `endif // my_scoreboard__SV
标签:name,--,my0,factory,uvm,type,phase,my,UVM 来源: https://www.cnblogs.com/thisway2014/p/16487814.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。