Vous êtes sur la page 1sur 39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

info@cluelogic.com

Welcome to ClueLogic

ClueLogic

Search...

Provi d i n g t h e c l u es to solve your verication problems

Search

Menu
Home

Services

Events

ClueBlog

About

ClueLogic > UVM > UVM Tutorial for Candy Lovers 9. Register Abstraction

UVM Tutorial for Candy Lovers 9. Register Abstraction


October 29, 2012

Keisuke Shimizu

Last Updated on November 6, 2016


This post will explain how to use the UVM Register Abstraction Layer (RAL) to generate register transactions. The gure below shows the verication platform used for this
post. Among other things, the jelly_bean_reg_block, the jelly_bean_reg_adapter, and the jelly_bean_reg_predictor are the classes used for the register abstraction.

Verication Platform
The gure below shows the diagram of the RAL-related classes. The standard UVM classes are shown in pink, while the jelly-bean classes are shown in light blue. The diagram
looks busy, but bear in mind that I will explain each jelly-bean class one by one.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

1/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

2/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

Diagram of the Jelly-Bean-Register Related Classes

Register Denitions
In the previous posts, the DUT had no accessible registers. We are going to add the registers that hold jelly-bean recipe information and its taste. We will also add a command
input port to the DUT so that we can write a jelly-bean recipe to the register and read its taste. The gure below shows the register denition of the DUT.

DUT Registers
The source code of the DUT (jelly_bean_taster) is shown below. When the command input is WRITE, the values of flavor, color, sugar_free, and sour input ports are written
to the RECIPE register (line 22 to 25). When the command input is READ, the TASTE register is read out and the taste output is driven accordingly (line 27).
1 modulejelly_bean_taster(jelly_bean_if.slave_mpjb_slave_if);
2 importjelly_bean_pkg::*;
3
4 reg[2:0]flavor;
5 reg[1:0]color;
6 regsugar_free;
7 regsour;
8 reg[1:0]command;
9 reg[1:0]taste;
10
11initialbegin
12flavor=0;
13color=0;
14sugar_free=0;
15sour=0;
16command=0;
17taste=0;
18end
19
20always@(posedgejb_slave_if.clk)begin
21if(jb_slave_if.command==jelly_bean_types::WRITE)begin
22flavor<=jb_slave_if.flavor;
23color<=jb_slave_if.color;
24sugar_free<=jb_slave_if.sugar_free;
25sour<=jb_slave_if.sour;
26endelseif(jb_slave_if.command==jelly_bean_types::READ)begin
27jb_slave_if.taste<=taste;
28end
29end
30
31always@(posedgejb_slave_if.clk)begin
32if(jb_slave_if.flavor==jelly_bean_types::CHOCOLATE&&
33jb_slave_if.sour)begin
34taste<=jelly_bean_types::YUCKY;
35endelseif(jb_slave_if.flavor!=jelly_bean_types::NO_FLAVOR)begin
36taste<=jelly_bean_types::YUMMY;
37end
38end
39endmodule:jelly_bean_taster

Register Model
The model of the RECIPE register is dened by extending the uvm_reg class. Each eld of the register is dened as a uvm_reg_field (line 4 to 7). The elds are congured in the
build function. Note that the name, build, is used for convenience. Do not confuse it with the build_phase of the uvm_component because the uvm_reg is not a
uvm_component.
1 classjelly_bean_recipe_regextendsuvm_reg;
2 `uvm_object_utils(jelly_bean_recipe_reg)
3
4 randuvm_reg_fieldflavor;
5 randuvm_reg_fieldcolor;
6 randuvm_reg_fieldsugar_free;
7 randuvm_reg_fieldsour;
8
9 constraintflavor_color_con{
10flavor.value!=jelly_bean_types::NO_FLAVOR;
11flavor.value==jelly_bean_types::APPLE
12>color.value!=jelly_bean_types::BLUE;

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

3/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

13flavor.value==jelly_bean_types::BLUEBERRY
14>color.value==jelly_bean_types::BLUE;
15flavor.value<=jelly_bean_types::CHOCOLATE;
16}
17
18functionnew(stringname="jelly_bean_recipe_reg");
19super.new(.name(name),.n_bits(7),.has_coverage(UVM_NO_COVERAGE));
20endfunction:new
21
22virtualfunctionvoidbuild();
23flavor=uvm_reg_field::type_id::create("flavor");
24flavor.configure(.parent(this),
25.size(3),
26.lsb_pos(0),
27.access("WO"),
28.volatile(0),
29.reset(0),
30.has_reset(1),
31.is_rand(1),
32.individually_accessible(0));
33
34color=uvm_reg_field::type_id::create("color");
35color.configure(.parent(this),
36.size(2),
37.lsb_pos(3),
38.access("WO"),
39.volatile(0),
40.reset(0),
41.has_reset(1),
42.is_rand(1),
43.individually_accessible(0));
44
45sugar_free=uvm_reg_field::type_id::create("sugar_free");
46sugar_free.configure(.parent(this),
47.size(1),
48.lsb_pos(5),
49.access("WO"),
50.volatile(0),
51.reset(0),
52.has_reset(1),
53.is_rand(1),
54.individually_accessible(0));
55
56sour=uvm_reg_field::type_id::create("sour");
57sour.configure(.parent(this),
58.size(1),
59.lsb_pos(6),
60.access("WO"),
61.volatile(0),
62.reset(0),
63.has_reset(1),
64.is_rand(1),
65.individually_accessible(0));
66endfunction:build
67endclass:jelly_bean_recipe_reg

The model of the TASTE register is similarly dened.


1 classjelly_bean_taste_regextendsuvm_reg;
2 `uvm_object_utils(jelly_bean_taste_reg)
3
4 randuvm_reg_fieldtaste;
5
6 functionnew(stringname="jelly_bean_taste_reg");
7 super.new(.name(name),.n_bits(2),.has_coverage(UVM_NO_COVERAGE));
8 endfunction:new
9
10virtualfunctionvoidbuild();
11taste=uvm_reg_field::type_id::create("taste");
12taste.configure(.parent(this),
13.size(2),
14.lsb_pos(0),
15.access("RO"),
16.volatile(1),
17.reset(0),
18.has_reset(1),
19.is_rand(1),
20.individually_accessible(1));
21endfunction:build
22endclass:jelly_bean_taste_reg

Register Block
The jelly_bean_reg_block contains the two registers created above and denes a register map.
1
2
3
4

classjelly_bean_reg_blockextendsuvm_reg_block;
`uvm_object_utils(jelly_bean_reg_block)

randjelly_bean_recipe_regjb_recipe_reg;

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

4/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

5 randjelly_bean_taste_regjb_taste_reg;
6 uvm_reg_mapreg_map;
7
8 functionnew(stringname="jelly_bean_reg_block");
9 super.new(.name(name),.has_coverage(UVM_NO_COVERAGE));
10endfunction:new
11
12virtualfunctionvoidbuild();
13jb_recipe_reg=jelly_bean_recipe_reg::type_id::create("jb_recipe_reg");
14jb_recipe_reg.configure(.blk_parent(this));
15jb_recipe_reg.build();
16
17jb_taste_reg=jelly_bean_taste_reg::type_id::create("jb_taste_reg");
18jb_taste_reg.configure(.blk_parent(this));
19jb_taste_reg.build();
20
21reg_map=create_map(.name("reg_map"),.base_addr(8'h00),
22.n_bytes(1),.endian(UVM_LITTLE_ENDIAN));
23reg_map.add_reg(.rg(jb_recipe_reg),.offset(8'h00),.rights("WO"));
24reg_map.add_reg(.rg(jb_taste_reg),.offset(8'h01),.rights("RO"));
25lock_model();//finalizetheaddressmapping
26endfunction:build
27
28endclass:jelly_bean_reg_block

Register Adapter
The jelly_bean_reg_adapter class provides two functions to convert between a uvm_reg_bus_op and a jelly_bean_transaction. The reg2bus function converts a
uvm_reg_bus_op into a jelly_bean_transaction, whereas the bus2reg function converts a jelly_bean_transaction back to a uvm_reg_bus_op.

The uvm_reg_adapter is a uvm_object, not a uvm_component.

Advanced Topic: Even though a uvm_sequence is a uvm_sequence_item, you cannot let the reg2bus() function create a uvm_sequence and return it. This is because when a
register is read/written, the uvm_reg_map calls uvm_sequence_base::start_item() passing the object returned by the reg2bus(), but the start_item() does not expect a
uvm_sequence. This will cause a fatal error. For more details, please see Register Access Methods.

1 classjelly_bean_reg_adapterextendsuvm_reg_adapter;
2 `uvm_object_utils(jelly_bean_reg_adapter)
3
4 functionnew(stringname="");
5 super.new(name);
6 supports_byte_enable=0;
7 provides_responses=0;
8 endfunction:new
9
10virtualfunctionuvm_sequence_itemreg2bus(constrefuvm_reg_bus_oprw);
11jelly_bean_transactionjb_tx
12=jelly_bean_transaction::type_id::create("jb_tx");
13
14if(rw.kind==UVM_READ)jb_tx.command=jelly_bean_types::READ;
15elseif(rw.kind==UVM_WRITE)jb_tx.command=jelly_bean_types::WRITE;
16elsejb_tx.command=jelly_bean_types::NO_OP;
17if(rw.kind==UVM_WRITE)
18{jb_tx.sour,jb_tx.sugar_free,jb_tx.color,jb_tx.flavor}=rw.data;
19returnjb_tx;
20endfunction:reg2bus
21
22virtualfunctionvoidbus2reg(uvm_sequence_itembus_item,
23refuvm_reg_bus_oprw);
24jelly_bean_transactionjb_tx;
25
26if(!$cast(jb_tx,bus_item))begin
27`uvm_fatal(get_name(),
28"bus_itemisnotofthejelly_bean_transactiontype.")
29return;
30end
31
32rw.kind=(jb_tx.command==jelly_bean_types::READ)?UVM_READ:UVM_WRITE;
33if(jb_tx.command==jelly_bean_types::READ)
34rw.data=jb_tx.taste;
35elseif(jb_tx.command==jelly_bean_types::WRITE)
36rw.data={jb_tx.sour,jb_tx.sugar_free,jb_tx.color,jb_tx.flavor};
37rw.status=UVM_IS_OK;
38endfunction:bus2reg
39
40endclass:jelly_bean_reg_adapter

Register Predictor
http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

5/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

The register predictor updates the values of the register model based on observed bus transactions. As the jelly-bean register predictor is not involved with any kind of
extended features, the uvm_reg_predictor is used as is.
typedefuvm_reg_predictor#(jelly_bean_transaction)jelly_bean_reg_predictor;

Agent
The jelly_bean_agent instantiates the jelly_bean_reg_adapter (line 35).
1 classjelly_bean_agentextendsuvm_agent;
2 `uvm_component_utils(jelly_bean_agent)
3
4 uvm_analysis_port#(jelly_bean_transaction)jb_ap;
5
6 jelly_bean_agent_configjb_agent_cfg;
7 jelly_bean_sequencerjb_seqr;
8 jelly_bean_driverjb_drvr;
9 jelly_bean_monitorjb_mon;
10jelly_bean_reg_adapterjb_reg_adapter;
11
12functionnew(stringname,uvm_componentparent);
13super.new(name,parent);
14endfunction:new
15
16functionvoidbuild_phase(uvm_phasephase);
17super.build_phase(phase);
18
19if(!uvm_config_db#(jelly_bean_agent_config)::get(.cntxt(this),
20.inst_name(""),
21.field_name("jb_agent_cfg"),
22.value(jb_agent_cfg)))begin
23`uvm_error("jelly_bean_agent","jb_agent_cfgnotfound")
24end
25
26jb_ap=new(.name("jb_ap"),.parent(this));
27if(jb_agent_cfg.active==UVM_ACTIVE)begin
28jb_seqr=jelly_bean_sequencer::type_id::create(.name("jb_seqr"),
29.parent(this));
30jb_drvr=jelly_bean_driver::type_id::create(.name("jb_drvr"),
31.parent(this));
32end
33jb_mon=jelly_bean_monitor::type_id::create(.name("jb_mon"),
34.parent(this));
35jb_reg_adapter=jelly_bean_reg_adapter::type_id::create(.name("jb_reg_adapter"));
36endfunction:build_phase
37
38functionvoidconnect_phase(uvm_phasephase);
39super.connect_phase(phase);
40
41jb_mon.jb_if=jb_agent_cfg.jb_if;
42if(jb_agent_cfg.active==UVM_ACTIVE)begin
43jb_drvr.seq_item_port.connect(jb_seqr.seq_item_export);
44jb_drvr.jb_if=jb_agent_cfg.jb_if;
45end
46jb_mon.jb_ap.connect(jb_ap);
47endfunction:connect_phase
48endclass:jelly_bean_agent

Environment Conguration
The jelly_bean_env_config has a handle to the jelly_bean_reg_block so that the jelly_bean_env can access the register model.
1 classjelly_bean_env_configextendsuvm_object;
2 `uvm_object_utils(jelly_bean_env_config)
3
4 bithas_jb_agent=1;
5 bithas_jb_sb=1;
6
7 jelly_bean_agent_configjb_agent_cfg;
8 jelly_bean_reg_blockjb_reg_block;
9
10functionnew(stringname="");
11super.new(name);
12endfunction:new
13endclass:jelly_bean_env_config

Environment
The jelly_bean_env instantiates the jelly_bean_agent and the jelly_bean_reg_predictor (line 28 to 31), then connects register-related objects:
Firstly, in the connect_phase(), the set_sequencer() function associates the jelly-bean sequencer and the register adapter with the register map (line 45 and 46). The
set_sequencer() must be called before starting the sequence based on a uvm_reg_sequence. A register block may have more than one register map.
Secondly, the register map and the register adapter are associated with the register predictor (line 49 and 50). The register predictor will use the register map and the register
adapter to convert a jelly_bean_transaction back to a register operation.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

6/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

Lastly, the register predictor is connected to the agent to subscribe the jelly_bean_transactions from the agent (line 51).
1 classjelly_bean_envextendsuvm_env;
2 `uvm_component_utils(jelly_bean_env)
3
4 jelly_bean_env_configjb_env_cfg;
5 jelly_bean_agentjb_agent;
6 jelly_bean_fc_subscriberjb_fc_sub;
7 jelly_bean_scoreboardjb_sb;
8 jelly_bean_reg_predictorjb_reg_predictor;
9
10functionnew(stringname,uvm_componentparent);
11super.new(name,parent);
12endfunction:new
13
14functionvoidbuild_phase(uvm_phasephase);
15super.build_phase(phase);
16if(!uvm_config_db#(jelly_bean_env_config)::get
17(.cntxt(this),
18.inst_name(""),
19.field_name("jb_env_cfg"),
20.value(jb_env_cfg)))begin
21`uvm_fatal(get_name(),"jb_env_cfgnotfound")
22end
23
24uvm_config_db#(jelly_bean_agent_config)::set(.cntxt(this),
25.inst_name("jb_agent*"),
26.field_name("jb_agent_cfg"),
27.value(jb_env_cfg.jb_agent_cfg));
28jb_agent=jelly_bean_agent::type_id::create(.name("jb_agent"),
29.parent(this));
30jb_reg_predictor=jelly_bean_reg_predictor::type_id::create(.name("jb_reg_predictor"),
31.parent(this));
32if(jb_env_cfg.has_jb_sb)begin
33jb_sb=jelly_bean_scoreboard::type_id::create(.name("jb_sb"),
34.parent(this));
35end
36jb_fc_sub=jelly_bean_fc_subscriber::type_id::create(.name("jb_fc_sub"),
37.parent(this));
38endfunction:build_phase
39
40functionvoidconnect_phase(uvm_phasephase);
41super.connect_phase(phase);
42jb_agent.jb_ap.connect(jb_fc_sub.analysis_export);
43jb_agent.jb_ap.connect(jb_sb.jb_analysis_export);
44if(jb_env_cfg.jb_reg_block.get_parent()==null)begin//ifthetoplevelenv
45jb_env_cfg.jb_reg_block.reg_map.set_sequencer(.sequencer(jb_agent.jb_seqr),
46.adapter(jb_agent.jb_reg_adapter));
47end
48jb_env_cfg.jb_reg_block.reg_map.set_auto_predict(.on(0));
49jb_reg_predictor.map=jb_env_cfg.jb_reg_block.reg_map;
50jb_reg_predictor.adapter=jb_agent.jb_reg_adapter;
51jb_agent.jb_ap.connect(jb_reg_predictor.bus_in);
52endfunction:connect_phase
53
54endclass:jelly_bean_env

Base Test
The base test instantiates a jelly_bean_reg_block (line 16 and 17) and stores its handle in the jelly_bean_env_config (line 19 and 20).
1 classjelly_bean_base_testextendsuvm_test;
2 `uvm_component_utils(jelly_bean_base_test)
3
4 jelly_bean_envjb_env;
5 jelly_bean_env_configjb_env_cfg;
6 jelly_bean_agent_configjb_agent_cfg;
7 jelly_bean_reg_blockjb_reg_block;
8
9 functionnew(stringname,uvm_componentparent);
10super.new(name,parent);
11endfunction:new
12
13functionvoidbuild_phase(uvm_phasephase);
14super.build_phase(phase);
15
16jb_reg_block=jelly_bean_reg_block::type_id::create("jb_reg_block");
17jb_reg_block.build();
18
19jb_env_cfg=jelly_bean_env_config::type_id::create("jb_env_cfg");
20jb_env_cfg.jb_reg_block=jb_reg_block;
21
22jb_agent_cfg=jelly_bean_agent_config::type_id::create("jb_agent_cfg");
23
24if(!uvm_config_db#(virtualjelly_bean_if)::get(.cntxt(this),
25.inst_name(""),
26.field_name("jb_if"),
27.value(jb_agent_cfg.jb_if)))begin

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

7/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

28`uvm_error("jelly_bean_test","jb_ifnotfound")
29end
30
31jb_env_cfg.jb_agent_cfg=jb_agent_cfg;
32
33uvm_config_db#(jelly_bean_env_config)::set(.cntxt(null),
34.inst_name("*"),
35.field_name("jb_env_cfg"),
36.value(jb_env_cfg));
37jb_env=jelly_bean_env::type_id::create(.name("jb_env"),
38.parent(this));
39endfunction:build_phase
40
41virtualfunctionvoidstart_of_simulation_phase(uvm_phasephase);
42super.start_of_simulation_phase(phase);
43uvm_top.print_topology();
44endfunction:start_of_simulation_phase
45
46endclass:jelly_bean_base_test

Sequence without Register Abstraction


We have created all the components by now and we are ready to create a register sequence. But before doing that, lets create a regular sequence without using the register
abstraction for comparison. The jelly_bean_sequence is a sequence to generate a sour-green-apple jelly bean. The body of the sequence creates a jelly_bean_transaction
which will be used by the driver to do pin wiggling.
1 classjelly_bean_sequenceextendsuvm_sequence#(jelly_bean_transaction);
2 `uvm_object_utils(jelly_bean_sequence)
3
4 functionnew(stringname="");
5 super.new(name);
6 endfunction:new
7
8 taskbody();
9 jelly_bean_transactionjb_tx;
10jb_tx=jelly_bean_transaction::type_id::create(.name("jb_tx"),
11.contxt(get_full_name()));
12start_item(jb_tx);
13jb_tx.flavor=jelly_bean_types::APPLE;
14jb_tx.color=jelly_bean_types::GREEN;
15jb_tx.sugar_free=0;
16jb_tx.sour=1;
17finish_item(jb_tx);
18endtask:body
19endclass:jelly_bean_sequence

Sequence Using Register Abstraction


The jelly_bean_reg_sequence is another sequence to generate a sour-green-apple jelly bean, but using the register abstraction. This sequence is extended from the
uvm_reg_sequence class so that we can use the convenience functions such as write_reg() and read_reg(). The body of the sequence writes a recipe (line 23) to the RECIPE
register, then reads back its taste from the TASTE register (line 24). Note that we do not create a jelly_bean_transaction in the sequence. The register adapter will convert
the register operations into the corresponding jelly_bean_transactions.
1 classjelly_bean_reg_sequenceextendsuvm_reg_sequence;
2 `uvm_object_utils(jelly_bean_reg_sequence)
3
4 functionnew(stringname="");
5 super.new(name);
6 endfunction:new
7
8 virtualtaskbody();
9 jelly_bean_reg_blockjb_reg_block;
10jelly_bean_types::flavor_eflavor;
11jelly_bean_types::color_ecolor;
12bitsugar_free;
13bitsour;
14uvm_status_estatus;
15uvm_reg_data_tvalue;
16
17$cast(jb_reg_block,model);
18flavor=jelly_bean_types::APPLE;
19color=jelly_bean_types::GREEN;
20sugar_free=0;
21sour=1;
22
23write_reg(jb_reg_block.jb_recipe_reg,status,{sour,sugar_free,color,flavor});
24read_reg(jb_reg_block.jb_taste_reg,status,value);
25endtask:body
26
27endclass:jelly_bean_reg_sequence

Register Test
The jelly_bean_reg_test creates a jelly_bean_reg_sequence we have just created and starts the sequence (line 12 to 15).

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

8/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

1 classjelly_bean_reg_testextendsjelly_bean_base_test;
2 `uvm_component_utils(jelly_bean_reg_test)
3
4 functionnew(stringname,uvm_componentparent);
5 super.new(name,parent);
6 endfunction:new
7
8 taskmain_phase(uvm_phasephase);
9 jelly_bean_reg_sequencejb_reg_seq;
10
11phase.raise_objection(.obj(this));
12jb_reg_seq=jelly_bean_reg_sequence::type_id::create(.name("jb_reg_seq"),
13.contxt(get_full_name()));
14jb_reg_seq.model=jb_reg_block;
15jb_reg_seq.start(.sequencer(jb_env.jb_agent.jb_seqr));
16
17#100ns;
18phase.drop_objection(.obj(this));
19
20endtask:main_phase
21endclass:jelly_bean_reg_test

Simulation
Lets look at a simulation result. The simulation successfully generated a sour-green apple and read back its taste from the DUT.
1 UVM_INFOjb3.sv(727)@30:uvm_test_top.jb_env.jb_sb[jelly_bean_scoreboard]Youhaveagoodsenseoftaste.
2
3 NameTypeSizeValue
4
5 jb_txjelly_bean_transaction@7929
6 flavorjelly_bean_types::flavor_e3APPLE
7 colorjelly_bean_types::color_e2GREEN
8 sugar_freeintegral1'h0
9 sourintegral1'h1
10commandjelly_bean_types::command_e2WRITE
11tastejelly_bean_types::taste_e2NO_TASTE
12
13
14UVM_INFOjb3.sv(727)@60:uvm_test_top.jb_env.jb_sb[jelly_bean_scoreboard]Youhaveagoodsenseoftaste.
15
16NameTypeSizeValue
17
18jb_txjelly_bean_transaction@7928
19flavorjelly_bean_types::flavor_e3NO_FLAVOR
20colorjelly_bean_types::color_e2NO_COLOR
21sugar_freeintegral1'h0
22sourintegral1'h0
23commandjelly_bean_types::command_e2READ
24tastejelly_bean_types::taste_e2YUMMY
25

I hope this tutorial helped you to understand the UVM Register Abstraction.

Getsourcecode
You can view and run the code on EDA Playground.
Share this:

LinkedIn 10

Facebook

Google

Twitter

Email

Print

Like this:

Like
Bethefirsttolikethis.

UVM

uvm_reg, uvm_reg_adapter, uvm_reg_block, uvm_reg_eld, uvm_reg_predictor, uvm_reg_sequence

UVM Tutorial for Candy Lovers 8. Congurations

UVM Tutorial for Candy Lovers 10. Inside Candy Factory

100 thoughts on UVM Tutorial for Candy Lovers 9. Register Abstraction


Jeremy says:
February 5, 2013 at 12:22 pm

I am interested in how you create your diagrams: are the block diagrams from visio or some other tool? Also, the class hierarchy looks like the dot-language.
Am I correct? If so, is this automatically generated (e.g. from within NaturalDocs?).

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

9/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
Reply

Keisuke Shimizu says:


February 6, 2013 at 10:00 am

Hi Jeremy,
Yes, I used Visio to draw the block diagrams. For the class diagrams, I used UMLGraph. UMLGraph takes Java les and generates the class diagrams in
dot language. I wrote UVM classes (but only skeletons) in Java. For the sequence diagrams, I used Web sequence diagrams, another tool I like.

Reply

haykp says:
October 26, 2016 at 5:01 am

Is the arrow direction from jelly_bean_recipie_reg to uvm_reg_map correct?


Shouldnt it be vice versa, meaning that uvm_reg_map depends on jelly_bean_recipie_reg?

Reply

Keisuke Shimizu says:


November 6, 2016 at 2:59 pm

You are right. I have xed the class diagram. Thank you for pointing this out.

Reply

Anand Kola says:


February 26, 2013 at 2:09 am

Hi,
I Am Anand, Trying to model UVM RAL Model for my IP by following your example.
I am following your blog, It was very useful for me to understand & trying to mimic same in my environment, Here i am facing following problem:
* When i am setting the sequencer & adapter, like
env_cfg0.reg_block.reg_map.set_sequencer( .sequencer(apb_env0.master.sequencer), .adapter(adapter0) )
says, null pointer at this line.
I am having a virtual sequence to control multiple interfaces in my env.
Could you help me out to x the above issue.
Let me know you if require further details to understand the issue better.
Thanks in advance
Regards,
Anand

Reply

Keisuke Shimizu says:


February 26, 2013 at 9:32 pm

Hi Anand,
I am glad that my blog was useful.
Regarding the null pointer problem, I am not sure which object is null by just looking at the line. Have you instantiated the
apb_env0.master.sequencer and the adapter0? If you could paste more lines and/or the error message, I might be able to gure out.

Reply

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

10/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

Anand Kola says:


February 26, 2013 at 10:51 pm

Hi Shimizu,
I could gure out problem in the above line, As i was not calling the reg_block.build(), it was reporting null pointer error.
Now i am deviating problem statement to uvm_reg_sequence level, where i am casting model with reg_block, i am getting null pointer access.

errormsg:
ncsim:*E,TRNULLID:NULLpointerdereference.
File:my_reg_seq_lib.sv,line=21,pos=12
Scope:worklib.$unit_0x37a3bb58::my_reg_seq@14758_4.body
=====================sourcecode====================================
//my_reg_seq.sv
classmy_reg_seqextendsuvm_reg_sequence
`uvm_object_utils(my_reg_seq)
c3a_reg_blockreg_block
uvm_status_estatus
uvm_reg_data_tvalue
externfunctionnew(stringname="my_reg_seq")
virtualtaskbody()
$cast(reg_block,model)//line21
reg_block.intr_en_reg.write(status,'h10)
reg_block.intr_en_reg.read(status,value)
endtask:body
endclass:my_reg_seq
//virtual_seq.sv
classmy_virtual_seqextendsuvm_sequence
`uvm_object_utils(my_virtual_seq)
c3a_reg_blockreg_block
//RALSeq.
c3a_reg_seqreg_seq0
//myipSequences
my_traffic_gen_seqtraffic_gen_seq
//virtualseq.bodydefinition
virtualtaskbody()
`uvm_do_on_with(reg_seq0,p_sequencer.apb_mst_seqr,{reg_seq0.model==reg_block})
`uvm_do_on(traffic_gen_seq,p_sequencer.c3a_seqr)
endtask:body
endclass:my_virtual_seq
//base_test.sv
classmy_base_testextendsuvm_test
`uvm_component_utils(my_base_test)
my_top_envtop_env0
my_top_env_configtop_config0
c3a_reg_blockreg_block
virtualfunctionvoidbuild_phase(uvm_phasephase)
super.build_phase(phase)
reg_block=c3a_reg_block::type_id::create("reg_block",this)
reg_block.build()
top_config0=my_top_env_config::type_id::create("top_config0",this)
top_config0.reg_block=reg_block

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

11/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
uvm_config_db#(my_top_env_config)::set(

.cntxt(this),

.inst_name("*"),

.field_name("top_cfg0"),

.value(top_config0)

top_env0=my_top_env::type_id::create(

.name("top_env0"),

.parent(this)

endfunction:build_phase
endclass:my_base_test
//base_test.sv
classmy_ral_testextendsmy_base_test
`uvm_component_utils(my_ral_test)
my_virtual_seqv_reg_seq0
virtualfunctionvoidbuild_phase(uvm_phasephase)
super.build_phase(phase)
v_reg_seq0=my_virtual_seq::type_id::create("v_reg_seq0",this)
v_reg_seq0.reg_block=reg_block
endfunction:build_phase
//Startthevirtualsequenceonvirtualsequencer
taskrun_phase(uvm_phasephase)
v_reg_seq0.start(

.sequencer(top_env0.virtual_seqr)

endtask:run_phase
endclass:my_ral_test
=========================================================
Thanks and Regards,
Anand

Reply

Anand Kola says:


February 27, 2013 at 1:31 am

sorry, the error was pointing at line no.22


i,e reg_block.intr_en_reg.write(status, h10)

Reply

Anand Kola says:


February 27, 2013 at 4:03 am

I could x the issue..,now it is working:) !!


Thank you once again..
Thanks and Regards,
Anand

Reply

Keisuke Shimizu says:


February 27, 2013 at 8:11 am

Good to hear that it is working.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

12/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
Reply

Manjunath says:
March 13, 2013 at 11:24 pm

What was the issue Anand? Is it that you cannot pass an object via uvm_do_on_with??

Reply

Anand Kola says:


March 17, 2013 at 11:44 pm

No that was not the problem Manjunath, I forgot to call the build() method of reg_block in the env.
so what happened was when i am trying to access the registers inside the reg_seq to perform write/read operations, i was getting null pointer access.
Hope you got the problem statement
Thanks,
Anand Kola

Reply

sivaji says:
March 26, 2013 at 10:51 pm

Hi,
I need help in getting the functional coverage for register model. I generated Register model package and covergroups for each register using the Register
Assistant tool from Mentor Graphics. Small code snippet for single register covergroup as shown below:

Classregister0_regextendsuvm_reg
`uvm_object_utils(register0_reg)
randuvm_reg_fieldport
randuvm_reg_fieldack
randuvm_reg_fieldresponse
Covergroupc1
port:coverpointport.value[4:0]
ack:coverpointack.value[5:0]
response:coverpointresponse.value[1:0]
endgroup
functionnew(stringname="")
super.new(name,build_coverage(UVM_CVR_FIELD_VALS))
add_coverage(build_coverage(UVM_CVR_FIELD_VALS))
if(has_coverage(UVM_CVR_FIELD_VALS)
c1=new()
endfunction
virtualfunctionvoidsample_values()
super.sample_values()
if(get_coverage(UVM_CVR_FIELD_VALS))
c1.sample()
endfunction
virtualfunctionvoidbuild()
port=uvm_reg_field::type_id::create("port")
ack=uvm_reg_field::type_id::create("ack")
response=uvm_reg_field::type_id::create("response")
port.configure()

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

13/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
ack.configure()
response.configure()
endfunction
endclass

In the base test class, I have written the following code:

functionvoidproj_test_base::build_phase(uvm_phasebuild)
//Registermodel
uvm_reg::include_coverage("*",UVM_CVR_FIELD_VALS)
proj_rm=proj_reg_block::type_id::create("proj_rm")
proj_rm.build()
endfunction
In the makele, I used the following command:

vsimctb_memcoveragedo"runacoveragesavecov.ucdbvcoverreporthtmlcov.ucdbq"
But, Questasim tool was not able to generate any UCDB les related to coverage.
Is there any code should be written to get the Register coverage? Please help me
Thanks,
Sivaji

Reply

Keisuke Shimizu says:


March 27, 2013 at 4:52 pm

Hi Sivaji,
I dont have access to Mentors tools, so I might be wrong, but did you call the proj_rm.sample_values() from your testbench to sample the register
values?
Keisuke

Reply

Sivaji says:
March 29, 2013 at 4:58 am

I tried by calling proj_rm.sample() from my testbench, but no le generated related to coverage.


Please suggest me, if there is any option.

Reply

Gayathri Shanmugam says:


September 25, 2013 at 4:46 am

Hi,
I have multiple bus interfaces in the testbench, i control sequences through common virtual sequencer. Now i need to incorporate RAL at this bus virtual
sequencer level. How to do that ? ie. using a single generic adaptor for all interfaces.

Reply

Keisuke Shimizu says:


September 26, 2013 at 11:02 am

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

14/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
September 26, 2013 at 11:02 am

Hi Gayathri,
I assume your DUT has two bus interfaces (bus_A and bus_B) and you can access the registers in the DUT through the bus_A and the bus_B. If that is
the case, I would suggest:
1. Create a register block (I call it reg_block) as usual.
2. Create two register maps (reg_map_A and reg_map_B) in the register block using create_map(). The reg_map_A denes the address map of the
registers using the bus_A, while the reg_map_B denes the address map of the registers using the bus_B.
3. Create two register adapters (reg_adapter_A and reg_adapter_B). The reg_adapter_A converts a register operation into a bus_A transaction,
while the reg_adapter_B converts a register operation into a bus_B transaction.
4. Associate the register adapters to the register maps using set_sequencer() so that the reg_map_A will use the reg_adapter_A and the reg_map_B
will use the reg_adapter_B.
5. In your virtual sequence, specify which register map to use. For example, if you want to read reg_X through bus_A, do
reg_block.reg_X.read(status,value,.map(reg_block.reg_map_A)).
Let me know if you need further clarication.

Reply

Ranji says:
February 10, 2015 at 2:03 am

Hi Keisuke,
In the above case what happens if both drivers initiate a write transaction to same register with dierent address map, Which transaction
will get a priority? Is testbanch has to be smart enough to do arbitration, If so then in which component/object we need code this arbitration
logic?

Reply

Keisuke Shimizu says:


February 14, 2015 at 6:04 pm

If you write the same register from two drivers, there is a race condition. Either your virtual sequence or upper protocol need to
take care of it if arbitration is required.

Reply

S says:
March 6, 2014 at 12:01 am

Hi Keisuke,
If I have to write more than 2 registers in the reg2bus or bus2reg methods under same condition, like in adapter class,

virtualfunctionvoidbus2reg(uvm_sequence_itembus_item,
refuvm_reg_bus_oprw)
jelly_bean_transactionjb_tx
...
...

rw.kind=(jb_tx.command==jelly_bean_types::READ)?UVM_READ:UVM_WRITE
if(jb_tx.command==jelly_bean_types::READ)
rw.data=jb_tx.taste
>//*WANTTOWRITEANOTHERREGISTERHERE*//
elseif(jb_tx.command==jelly_bean_types::WRITE)
rw.data={jb_tx.sour,jb_tx.sugar_free,jb_tx.color,jb_tx.flavor}
rw.status=UVM_IS_OK
endfunction:bus2reg

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

15/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
In that case, how do we manage with rw.data value for two registers ?
How can we dene a bunch of registers that adopt the similar properties and are to be written under same condition. Eg: During reset phase.
Thank You..!
S

Reply

Keisuke Shimizu says:


March 7, 2014 at 10:47 am

As far as I know, you cannot associate a bus_item to more than one rw in the bus2reg. If all you need is to set some values to multiple registers, you
could do:

uvm_regregs[$]
uvm_status_estatus
your_reg_block.get_registers(regs)
foreach(regs[i])regs[i].set(some_value)
your_reg_block.update(status)
As all your registers are the descendants of uvm_reg, you can set the some_value without knowing the actual type of the registers (the beauty of
polymorphism). Let me know if I did not answer your question.

Reply

S says:
March 8, 2014 at 7:42 pm

Thank you very much Keisuke..!


That solves my puzzle..!

Reply

Keisuke Shimizu says:


March 8, 2014 at 9:36 pm

You are welcome.

Reply

Zhu YH says:
August 25, 2014 at 6:17 pm

Hi,
I was wondering that the reg_adapter may be better not to included in agent, instead it may be included in reg model. the adapter looks more close to reg
model. Am I right?

Reply

Keisuke Shimizu says:


August 30, 2014 at 10:57 am

The idea behind the reg adapter is to convert a generic uvm_reg_bus_op to/from a specic bus transaction. For example, the jelly_bean_reg_adapter
converts a uvm_reg_bus_op to/from a jelly_bean_transaction, but you might want to create another adapter for like gummy_bear_transaction
later. Since the adapter is dependent of underlying bus transaction, I put it in the agent.

Reply

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

16/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

abhishek gupta says:


September 17, 2014 at 9:35 pm

I am using Register model in my project, now I have to create an adaptor class. But the problem is to convert the bus_sequence_item into reg_item, I have to
see what is value already set in the registers according to which the conversion have to be done. I cant take handle of conguration in apaptor class because
its an object. What is the possible solution for this.

Reply

Keisuke Shimizu says:


September 21, 2014 at 1:03 pm

I am not sure if I fully understand your question, but your agent that creates the adapter can pass the handle to the conguration object after the
agent creates the adapter.

Reply

abhishek gupta says:


September 21, 2014 at 11:03 pm

Thank you for your time Keisuke.


Passing handle will work, but I was thinking if there is something similar to uvm_cong_db :: get which is for components and not objects, to
make it(adapter) more independent.
My concern is that in one of the registers there are elds which tells how the data is distributed on the data line, it can be either serial or
staggered and other such things. Now when the further transactions take place, I have to convert the data and store in register accordingly.

Reply

Keisuke Shimizu says:


September 27, 2014 at 10:41 am

Although the uvm_reg_adapter is a uvm_object, we can still use the uvm_config_db. For example, we could create a new
conguration setting in a test like:

uvm_config_db#(jelly_bean_env_config)::set(.cntxt(null),
.inst_name("jb_reg_adapter"),
.field_name("jb_env_cfg"),
.value(jb_env_cfg))
Then, in the jelly_bean_reg_adapter, we could get the value by:

uvm_config_db#(jelly_bean_env_config)::get(.cntxt(null),
.inst_name(get_name()),
.field_name("jb_env_cfg"),
.value(jb_env_cfg))
Note that since the uvm_reg_adapter is not a uvm_component, it does not have a hierarchical name. Thus, we used null as the
context. The get can nd jb_env_cfg as long as the inst_name matches.

Reply

Vittal says:
September 20, 2014 at 7:05 am

Hi Keisuke,
I was wondering why in reg2apb() function of uvm_reg_adapter we have arguments with const ref uvm_reg_bus_op, what is the signicance of using const ref
there !! Similarly in bus2reg() why only ref is enough .. Plase explain

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

17/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
Best Regards,
Vittal

Reply

Keisuke Shimizu says:


September 21, 2014 at 1:44 pm

purevirtualfunctionuvm_sequence_itemreg2bus(constrefuvm_reg_bus_oprw)
Since the uvm_reg_bus_op is a structure, not a class handle, each member of the structure will be copied (pass by value) when it is passed as an
argument to a function. To avoid the expensive copy, ref (pass by reference) is used, and to protect the rw from being modied by the reg2bus, const
is also used.

purevirtualfunctionvoidbus2reg(uvm_sequence_itembus_item,refuvm_reg_bus_oprw)
Unless ref is used, the caller of bus2reg wont see the change of rw because pass by value is the default mechanism for passing arguments to
functions. You cannot use const here because you need to modify the rw.

Reply

Kousik says:
September 29, 2014 at 5:17 am

Hi,
Thanks for your useful tutorial. I am new in UVM. I want to know the meaning and importance of $cast( jb_reg_block, model ) this statement.what is this
model? .
Regards,
Kousik

Reply

Keisuke Shimizu says:


September 30, 2014 at 9:53 pm

The model is a property of uvm_reg_sequence class (the base class of the jelly_bean_reg_sequence). The model holds the register block abstraction
the uvm_reg_sequence executes on. We used our jb_reg_block as the model (please see the line 14 of jelly_bean_reg_test). Since the type of
model is uvm_reg_block, we needed the $cast(jb_reg_block,model) to access the properties specic to the jb_reg_block, such as
jb_recipe_reg and jb_taste_reg.

Reply

Pratik says:
November 3, 2014 at 9:00 pm

Hi Keisuke,
Great Article.
I have one problem regarding Explicit Prediction method.
I have created RAL Model for my UART Protocol and I made necessary connections for that.
Everything is working ne.
But the problem is, when is use explicit prediction method, the mirror value is not being updated.
In Auto prediction, Its working Fine.
For Explicit prediction, do I need to add some extra code to update the mirror value of registers.
Please help me, I am struggling with this problem.

Reply

Keisuke Shimizu says:


November 4, 2014 at 11:34 pm

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

18/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
November 4, 2014 at 11:34 pm

Check the connection between your analysis port and the bus_in of your predictor. Does your monitor call write to the analysis port? Also check
whether the bus2reg function of your adapter is called.

Reply

ROHAN says:
January 8, 2015 at 9:50 pm

Hi Keisuke,
Can you explain how Predict method works ?

Reply

Keisuke Shimizu says:


January 25, 2015 at 6:19 pm

The predict method is used to update the mirrored value of the register model. Please see Register Access Methods for more detail.

Reply

Hagai says:
February 4, 2015 at 1:30 pm

Hi Keisuke,
First of all, thank you for this page that makes order in all these uvm objects and how they work together.
In my verication environment, the reads and writes of registers are done using a UART agent. The problem is that for each write or read of a register I need to
generate multiple uart_trans items, because each register access consists of an entire message (header, command, address and data, and checksum).
What is the way to associate the reg_adaptor with such a mechanism? will I need then a virtual agent that will process the UART transactions in a transaction
layer?
Thanks

Reply

Keisuke Shimizu says:


February 14, 2015 at 4:49 pm

I am glad to hear that my blog was useful. For your UART, I would create a class that groups together the uart_trans like:
classuart_trans_groupextendsuvm_sequence_item;
//
uart_transtrans[];
//
endclass

The trans array will hold UART header, command, address, data, etc. Then, I would dene the reg2bus function that converts a register read/write
into this class and lls the trans array.
For the driver side, I would create a layered sequencer; one to process the uart_trans_group and the other to process the uart_trans in the group.
The downstream sequencer runs a sequence that breaks down a uart_trans_group into multiple uart_trans.
Similarly for the predictor side, I would create a layered monitor; one to monitor UART signals and the other to group the uart_trans. There might be
a better solution. I welcome any suggestions.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

19/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

Reply

ROHAN says:
February 8, 2015 at 9:33 pm

Hi Keisuke,
Can you explain how mirror value gets updated during explicit prediction?

Reply

Keisuke Shimizu says:


February 14, 2015 at 12:09 pm

The steps 5 and 6 of How the write() method works and the steps 7 and 8 of How the read() method works might answer your question.

Reply

ROHAN says:
February 17, 2015 at 8:16 pm

Thanks for the reply I have one more doubt how UVM_IS_X status is used ?.

Reply

Keisuke Shimizu says:


March 22, 2015 at 9:27 am

You can set rw.status=UVM_HAS_X in the bus2reg function of your reg adapter if the bus data contains X. But as far as I know, the RAL treats
UVM_HAS_X as UVM_IS_OK, so there is no dierence whether you use UVM_HAS_X or not.

Reply

L says:
August 21, 2015 at 11:17 am

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

20/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
August 21, 2015 at 11:17 am

Hi Keisuke,
Do you consider this is a bug in uvm? Why not x uvm source code to handle x detection in register checking?
BTW, thanks for the great work!

Reply

Chitlesh says:
May 7, 2015 at 5:44 am

Hi Keisuke, what is the software you are using to generate those wonderful diagrams ?

Reply

Keisuke Shimizu says:


May 9, 2015 at 9:29 am

I used UMLGraph to generate the class diagram. I used Microsoft Visio for the rest.

Reply

Rui Huang says:


May 30, 2015 at 11:12 pm

Hi Keisuke,
Can you explain a little about how the address of a register is get passed to a driver in a memory based system?
I mean in the reg_map which I snipped as following, since really_bean_taster is not address based conguration system, the addresses of the two register dont
used in your example, but for a complex real application, how the address of the registers is transferred/passed to a driver?
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
reg_map.add_reg( .rg( jb_recipe_reg ), .oset( 8h00 ), .rights( WO ) );
reg_map.add_reg( .rg( jb_taste_reg ), .oset( 8h01 ), .rights( RO ) );
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Thanks,
Rui Huang

Reply

Keisuke Shimizu says:


September 6, 2015 at 5:44 pm

To make the address availble on the bus, dene the address in the transaction:
1
2
3
4

classjelly_bean_transactionextendsuvm_sequence_item;
randbit[7:0]addr;
//...
endclass:jelly_bean_transaction

Then, assign the addr in the functions of the reg adapter:


1 classjelly_bean_reg_adapterextendsuvm_reg_adapter;
2 virtualfunctionuvm_sequence_itemreg2bus(constrefuvm_reg_bus_oprw);
3 //...
4 jb_tx.addr=rw.addr;
5 endfunction:reg2bus
6
7 virtualfunctionvoidbus2reg(uvm_sequence_itembus_item,refuvm_reg_bus_oprw);
8 //...
9 rw.addr=jb_tx.addr;
10endfunction:bus2reg
11endclass:jelly_bean_reg_adapter

Based on the base-address (8'h00) and the oset (8'h00 or 8'h01) dened in the jelly_bean_reg_block, you will see either 8'h00 (jb_recipe_reg)
or 8'h01 (jb_taste_reg) on the address bus.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

21/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
Reply

Gautam says:
June 14, 2015 at 3:19 am

Hi Keisuke,
I have been following you tutorial for some time now. Thanks for all the eort you have put into this tutorial. It is very benecial for people like me.
I just started going through this tutorial. I have a few questions.
1) I am not able to understand how register modelling is helpful. I see that here the register values in register block follow the value in the designs register. I
am not able to gure out where the comparison for correctness is done.
2) Also I see in the tutorial source you have provided tutorial_9.sv https://github.com/cluelogic/uvm-tutorial-for-candy-lovers/blob/master/src/tutorial_9.sv ,
you have coded a scoreboard component. In the class diagram it is missing. Is it required here?
3) Under what circumstances do we use a register model?
4) The reg predictor class, is it for predicting expected register values?
Regards,
Gautam

Reply

Keisuke Shimizu says:


September 6, 2015 at 2:47 pm

1. Register data comparison is usually done outside of the RAL (you read a register and compare it against the expected value).
2. The diagram shows the classes related to the RAL only.
3. Any verications that access registers. Tests become more reusable because the user does not need to know the address, eld location, or
underlying bus that accesses the registers.
4. The reg predictor itself does not predict the register value. It takes a bus transaction, converts it to a register item, and updates the register
model.

Reply

Jatin says:
June 15, 2015 at 9:07 am

How to write register sequences for UVM Register Model?


What would be the desired and mirrored values w.r.t. read & write access methods?

Reply

Keisuke Shimizu says:


July 18, 2015 at 4:01 pm

The jelly_bean_reg_sequence is an example of register sequences. Both read and write methods update the desired and the mirrored values.
Please see how the read method works and how the write method works for more detail.

Reply

Arul Nesan says:


August 29, 2015 at 4:42 am

Hi Mr.Keisuke Shimizu, I have basic doubt. In RAL based sequence of READ (i.e Auto predict mode, not explicit prediction ) how the read data got updated into
the Register models ??? Thanks in advance for your graphical answer :).

Reply

Keisuke Shimizu says:


September 5, 2015 at 2:19 pm

When the auto-predict mode is set, the read() task will call the do_predict() function to update the mirrored value, etc. before the task returns the
read data.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

22/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

Reply

Sudhish says:
October 12, 2015 at 1:26 am

Hi,
I am trying to make use of the RAL generated coverage at the full chip level. From monitor I am collecting data, and using base address and oset I am getting
register name(get_reg_by_oset). I am facing issue in the next step, if I try to use write method of the register I am getting error saying sequencer not set, so I
tried using sample method of the register in couple of ways that is also not worked. Could you please help me to resolve this issue.
thanks
Sudhish

Reply

Keisuke Shimizu says:


October 25, 2015 at 10:05 am

Did you call your_reg_map.set_sequencer()? If you could paste the snippet of your code, I might be able to help.

Reply

Tejas T V says:
December 4, 2015 at 10:51 pm

Hi Keisuke Shimizu,
First of all thank you for this wonderful blog, helped a lot in understanding and developing a RAL model.
I have a simple memory interface, in which
* Write & Read takes one clk to update-to and read-out from memory.
* o_read_data is the memory output with o_data_vld (and its working as expected for the given address)
* Whereas on the RAL side, the o_read_data is always having the value zero, though I am sampling its value when risign_edge of o_data_vld,
hence
I always get the data mismatch UVM_ERROR for predictor-mirror. and also for .read operation I will have the read_value zero.

Transaction

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

23/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

classreg_access_type
typedefenumbit[1:0]{NO_OPERATION,READ,WRITE}access_types
endclass:reg_access_type

classreg_access_response_type
typedefenumbit[1:0]{NO_OPERATION,READ,WRITE}access_types
endclass:reg_access_response_type

classmy_transactionextendsuvm_sequence_item
randcbit[07:0]wr_addr
randcbit[15:0]wr_data
randcbit[07:0]rd_addr
randcbit[15:0]rd_data
randcbitrd_en
randcbitwr_en
randreg_access_type::access_typescommand
reg_access_response_type::access_typesotp_command

`uvm_object_utils_begin(my_transaction)

`uvm_field_int(wr_addr,UVM_ALL_ON)

`uvm_field_int(wr_data,UVM_ALL_ON)

`uvm_field_int(rd_addr,UVM_ALL_ON)

`uvm_field_int(rd_data,UVM_ALL_ON)

`uvm_field_enum(reg_access_type::access_types,command,UVM_ALL_ON)
`uvm_field_enum(reg_access_response_type::access_types,otp_command,UVM_ALL_ON)

`uvm_object_utils_end

functionnew(stringname="")
super.new(name)
endfunction:new
endclass:my_transaction

Monitor

taskrun_phase(uvm_phasephase)
forever
begin
@(posedgev_if.o_data_vld)
begin
`uvm_info(get_type_name(),"atrising_edgeofo_data_vld",UVM_DEBUG)
my_txn.otp_command=reg_access_response_type::READ
my_txn.rd_data=v_if.o_rd_data
AP_mon.write(my_txn)
`uvm_info(get_type_name(),"sampledo_rd_data",UVM_DEBUG)
end
end
endtask:run_phase

Hereisthecodeofbus2regconversion

virtualfunctionvoidbus2reg(uvm_sequence_itembus_item,refuvm_reg_bus_oprw)

if(!$cast(my_txn,bus_item))

begin

`uvm_fatal("my_transaction","Providedbus_itemisnotofthecorrecttype")

return

end

//INFORMTHEUVM_KINDWITHUSERREAD/WRITETYPE

rw.kind=(my_txn.otp_command==reg_access_response_type::READ)?UVM_READ:UVM_WRITE

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

24/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

if(my_txn.otp_command==reg_access_response_type::READ)

begin

rw.data=my_txn.rd_data

rw.addr=my_txn.rd_addr

end

elseif(my_txn.otp_command==reg_access_response_type::WRITE)

begin

rw.data=my_txn.wr_data

rw.addr=my_txn.wr_addr

end

rw.status=UVM_IS_OK

endfunction:bus2reg

endclass:reg_adapter

Hereisthecodeofreg2busconversion

virtualfunctionuvm_sequence_itemreg2bus(constrefuvm_reg_bus_oprw)

my_transactionmy_txn

my_txn=my_transaction::type_id::create("my_txn")

if(rw.kind==UVM_READ)

elseif(rw.kind==UVM_WRITE)

else

//FORWRITE,

if(rw.kind==UVM_WRITE)

my_txn.wr_data=rw.data

my_txn.wr_addr=rw.addr

my_txn.command=reg_access_type::READ
my_txn.command=reg_access_type::WRITE
my_txn.command=reg_access_type::NO_OPERATION

if(rw.kind==UVM_READ)

my_txn.rd_addr=rw.addr

//RETURNTHEUSERTRANSACTION

returnmy_txn

endfunction:reg2bus

Please help me out in resolving this issue.


Thank you,
Tejas T V

Reply

Keisuke Shimizu says:


December 5, 2015 at 1:19 pm

Did you see the correct o_rd_data value in your monitor? It seems that the o_rd_data has not changed @(posedgev_if.o_data_vld). Can you
try something like this to avoid the race?
//monitor
foreverbegin
@(posedgev_if.clk);
if(v_if.o_data_vld)begin
my_txn.otp_command=reg_access_response_type::READ;
my_txn.rd_data=v_if.o_rd_data;
AP_mon.write(my_txn);
end
end

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

25/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
Reply

Tejas T V says:
December 7, 2015 at 11:19 am

Hi Keisuke,
I have tried with your suggestion, but still I see a problem here, RAL is comparing the data before the valid data is seen in the monitor.

[test]
classmy_reg_testextendsmy_test_base
`uvm_component_utils(my_reg_test)

//REGISTERMODEL
uvm_reg_mapreg_map
my_reg_blockreg_block
stringreg_name
bit[15:0]reg_data
bit[15:0]read_data
bit[15:0]rst_data
uvm_status_eop_status

functionnew(stringname,uvm_componentparent)
super.new(name,parent)
endfunction:new

taskrun_phase(uvm_phasephase)
seq=my_sequence::type_id::create("seq")
rst=assert_rst::type_id::create("rst")
phase.raise_objection(this,"teststartsnow")

h_env.h_env_cnfg.h_reg_block.STATUS_CONTROL_REG.RAJ.set(3'h7)

h_env.h_env_cnfg.h_reg_block.STATUS_CONTROL_REG.update(op_status,.path(UVM_FRONTDOOR),.map(reg_map),.parent(nu
#20//waitfor2clks
h_env.h_env_cnfg.h_reg_block.STATUS_CONTROL_REG.RAJ.predict(3'h7)

h_env.h_env_cnfg.h_reg_block.STATUS_CONTROL_REG.RAJ.mirror(op_status,.check(UVM_CHECK),.path(UVM_FRONTDOOR),.m
phase.drop_objection(this,"testendsnow")
endtask:run_phase

endclass:my_reg_test
[monitor]
taskrun_phase(uvm_phasephase)
@(posedgev_if.clk)
begin
@(posedgev_if.o_data_vld)
begin

`uvm_info(get_type_name(),$sformatf("o_data_vld::%0d,o_rd_data::%0d",v_if.o_data_vld,v_if.o_rd_data),UVM_
my_txn.rd_addr=v_if.i_rd_addr
AP_mon.write(my_txn)
`uvm_info(get_type_name(),"sampledvlddata",UVM_LOW)
end
end
endtask:run_phase
[log]
#UVM_INFO@0:reporter[RNTST]Runningtestmy_reg_test...

#UVM_ERRORverilog_src/uvm1.0p1/src/reg/uvm_reg.svh(2892)@255:reporter[RegModel]Register"STATUS_CONTROL_REG"va

#UVM_INFOverilog_src/uvm1.0p1/src/reg/uvm_reg.svh(2902)@255:reporter[RegMem]fieldRAJmismatchread=3'h0mirror

#UVM_INFO../tb/agent/monitor.svh(64)@265:uvm_test_top.h_env.h_agt.h_mntr[monitor]o_data_vld::1,o_rd_data::

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

26/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
#UVM_INFO../tb/agent/monitor.svh(67)@265:uvm_test_top.h_env.h_agt.h_mntr[monitor]sampledvlddata

#UVM_INFOverilog_src/uvm1.0p1/src/base/uvm_objection.svh(1116)@1255:reporter[TEST_DONE]'run'phaseisreadyto

Reply

Keisuke Shimizu says:


December 7, 2015 at 10:38 pm

It seems that the mirror() returns too soon, even before the monitor sees the transaction on the bus. Do you use the auto-predict mode? If so, check
if your driver returns the read value to the sequencer correctly.

Reply

David Ellis says:


November 2, 2016 at 3:42 pm

Do not use @(posedge v_if.o_data_vld)


. in monitor..

fork
foreverbegin
@(posedgev_if.clk)//waitforaclockedge
if(v_if.o_data_vld)begin//wasthevalidassertedthisclock?

//grabthedataandmakeatxntoAP_monanddisp
end
end
join

(if you want this task to end, you can quit out of the forever loop once you see your txn..but I assume your monitor would just run till the phase was
terminated.)
Note that this will show up at the next clock edge to when the valid is present. This is when any hardware might sample it anyway, so that should
be reasonable.
If you were to go to gate level, the timing of the valid and data relative to clock might be such that it would not become valid immediately after the
rising edge of the clock.
I recommend you look into clocking blocks as part of your interface as well. And use the clocking vars and clocking events instead of the interface
wires if you ever plan on this working with gate level delays in your RTL (DUT).
By way of explanation,
your code:

@(posedgev.if.clk)//waitforaclockedge(evenXto1'b1woulddoattime0ifithappenedtostartata
begin//decorationreally...

@(posedgev_if.o_data_vld)//ok,nowthatclockisgood,nextedgeonvalid(manyclockslater?)....
begin//againwhy?
//doyourstuff...

Please dont take this as a criticism. my comments are just information, not putdowns.
Im an architect and RTL designer, not really much of a validator but I am learning .. thanks,

Reply

Jay says:
December 9, 2015 at 2:12 am

Hi Keisuke Shimizu,
I am trying to implement RAL model UVM env by taking your example as reference. But I am getting following error.
Can you please look into it and help me.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

27/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
UVM_WARNING /lin_tools/synopsys/vcs_mx_J-2014.12-sp3/etc/uvm/reg/uvm_reg_sequence.svh(137) @ 0: uvm_test_top.env.sagent.ssp_seqr@@s_seq
[REG_XLATE_NO_SEQR] Executing RegModel translation sequence on sequencer uvm_test_top.env.sagent.ssp_seqr does not have an upstream sequencer
dened. Execution of register items available only via direct calls to do_rw_access
Thanks,
Jay

Reply

Jay says:
December 9, 2015 at 4:48 am

Hi Keisuke
I solved the above mentioned issue. It was mistake. My sequence was extended from uvm_reg_sequence and I was calling super.body in actual body
method of sequence. I removed it. It works ne. Thanks for your blog. Great Help
I am not aware of internal details of uvm_reg_sequence. If possible can you explain why body method is present in uvm_reg_sequence, if it is
required, Why cant I use super.body.
Thanks in Advance.

Reply

Keisuke Shimizu says:


December 13, 2015 at 3:45 pm

The uvm_reg_sequence can be used as two ways. One way is as the base class of a user-dened register sequence as you did. The other way
is as a register-to-bus-transaction translator. If the upstream sequencer (reg_seqr) is specied, the body method of the uvm_reg_sequence
gets a uvm_reg_item from the reg_seqr and converts it to a jelly_bean_transaction (see the gure below).

The reason you must not call super.body() in a user-dened sequence is that the translation logic mentioned above will execute otherwise.

Reply

Neha says:
March 16, 2016 at 7:05 am

Hi,
Though this is not a reply, but I could not nd a switch to post a question.
It is related to the user dened uvm_reg_sequence.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

28/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
Consider a case where a register eld is written followed by another write to same register but to a dierent eld.
Now, two things can be done:
1. If these are back to back accesses, they can be clubbed to a single write on bus interface. This intelligence has to be built in user
extended uvm_reg_sequence?
2. If these two writes are not back to back, so user_reg_sequence (extended from uvm_reg_sequence) has to do read-modify-write.
Is that correct? Or, is it taken care by some magic in uvm?

Reply

Keisuke Shimizu says:


March 19, 2016 at 5:14 pm

You can control how the elds are written. For example, if you want to combine the two writes to one, you could do:
uvm_status_estatus;

your_reg.field1.set(value1);
your_reg.field2.set(value2);
your_reg.update(status);

Or, if you want two separate writes, you could do:


uvm_status_estatus;

your_reg.field1.write(status,value1);
your_reg.field2.write(status,value2);

In the latter case, if the target bus supports byte-enable and the eld is the only eld in a byte lane, then only the eld is
written. Otherwise, the entire register is written using the mirrored values of the other elds. So, you dont have to use
Read-Modify-Write if you think mirrored values are good enough. I hope I answered your questions.

Jonathan says:
December 9, 2015 at 3:41 am

Hi Simizu san,
I would like to know how can i dene a register which has Read Only access type for BUS_A and WRitable access type for BUS_B. Is it possible to create a map
that overwrites the default access type congured in the register?. How can this be done?. is it with the add_reg function to the register map?.
I came to this problem with the register assistant from Mentor. This tool generates the systemverilog registermodel classes automatically for you from excel
tables where the registers are described. However, this tool doesnt allow you to dene dierent access type for individual register maps. The register maps
can only have dierent address osets but not dierent access types. Makes this sense or is it a tool limitation?. Any idea?
Thanks in advance

Reply

Keisuke Shimizu says:


December 13, 2015 at 4:24 pm

You should be able to set dierent accessibility when you do add_reg() as you mentioned. For example, you could do:
1 classjelly_bean_recipe_regextendsuvm_reg;
2 virtualfunctionvoidbuild();
3 flavor=uvm_reg_field::type_id::create("flavor");
4 flavor.configure(this,3,0,"RW",0,0,1,1,0);//set"RW"tothefield
5 //...
6 endclass:jelly_bean_recipe_reg
7
8 classjelly_bean_reg_blockextendsuvm_reg_block;
9 randjelly_bean_recipe_regjb_recipe_reg;
10uvm_reg_mapreg_map_a;//registermapforBUS_A
11uvm_reg_mapreg_map_b;//registermapforBUS_B
12
13virtualfunctionvoidbuild();
14jb_recipe_reg=jelly_bean_recipe_reg::type_id::create("jb_recipe_reg");
15//...
16reg_map_a.add_reg(jb_recipe_reg,8'h00,.rights("RO"));//readonly
17reg_map_b.add_reg(jb_recipe_reg,8'h00,.rights("RW"));//writable
18//...
19endclass:jelly_bean_reg_block

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

29/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
The register model restricts the accessibility based on the rights argument of the add_reg() on top of the eld access policy.
Unfortunately, I dont have access to the tool you mentioned, so I dont know if this is a tool limitation or not.

Reply

Tejas T V says:
December 10, 2015 at 3:00 am

Hi Keisuke,
No I am not using auto-predict mode.

[env]
typedefuvm_reg_predictor#(my_transaction)reg_predictor
importagent_pkg::*

classmy_envextendsuvm_env
`uvm_component_utils(my_env)

env_config

h_env_cnfg

agent

h_agt

//REGPREDICTOR
reg_predictorh_predictor
//NEW
functionnew(stringname,uvm_componentparent)
super.new(name,parent)
endfunction:new

functionvoidbuild_phase(uvm_phasephase)
super.build_phase(phase)

//GETTHEENVCONFIGURATIONHANDLEFORCONFIG_DB
if(!uvm_config_db#(env_config)::get
(.cntxt(this),.inst_name(""),.field_name("h_env_cnfg"),.value(h_env_cnfg)))
begin
`uvm_fatal(get_name(),"h_env_cnfgnotfound")
end
//ASSIGNTHEAGENTCONFIGFROMENVCONFIGURATION
uvm_config_db#(agent_config)::set
(.cntxt(this),.inst_name("h_agt*"),.field_name("h_agt_cnfg"),.value(h_env_cnfg.h_agt_cnfg))
h_agt=agent::type_id::create("h_agt",this)
h_predictor=reg_predictor::type_id::create("h_predictor",this)

`uvm_info(get_full_name(),"AGENTCREATIONDUETOSWITCH",UVM_DEBUG)

`uvm_info(get_type_name(),"build",UVM_DEBUG)
endfunction:build_phase
functionvoidconnect_phase(uvm_phasephase)
super.connect_phase(phase)

//
if(h_env_cnfg.h_reg_block.get_parent()==null)
begin
h_env_cnfg.h_reg_block.reg_map.set_sequencer(.sequencer(h_agt.h_seqr),.adapter(h_agt.h_adapter))
end
h_env_cnfg.h_reg_block.reg_map.set_auto_predict(.on(0))
h_predictor.map=h_env_cnfg.h_reg_block.reg_map

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

30/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
h_predictor.adapter=h_agt.h_adapter
h_agt.AP_in_agt.connect(h_predictor.bus_in)

`uvm_info(get_type_name(),"connect",UVM_DEBUG)
endfunction:connect_phase

endclass:my_en
Reply

Keisuke Shimizu says:


December 13, 2015 at 2:06 pm

Does your driver use get_next_item()/item_done() or get()/put(rsp)? If the latter, do you set the provides_responses to 1 in your register
adapter?

Reply

Tejas T V says:
December 14, 2015 at 1:35 am

I am using get_next_item and item_done and I have not made use of response port.(is this causing early execution of bus2reg ?).
and my provides_responses is always zero(set during the construction of adapter class, and not modifying there after)

[adapter]
//NEW
functionnew(stringname="reg_adapter")
super.new()
supports_byte_enable=0
provides_responses=0
endfunction:new
[driver]
taskrun_phase(uvm_phasephase)
forever
begin
`uvm_info(get_type_name(),"****Requestingforanitem(txn)****",UVM_DEBUG)
seq_item_port.get_next_item(txn)
`uvm_info(get_type_name(),"****Receivedanitem(txn)****",UVM_DEBUG)
@(v_if.cb)
if(txn.command==reg_access_type::READ)
begin
v_if.cb.i_rd_en<=1'b1
v_if.cb.i_rd_addr<=txn.rd_addr
@(v_if.cb)
v_if.cb.i_rd_en<=1'b0
end
elseif(txn.command==reg_access_type::WRITE)
begin
v_if.cb.i_wr_en<=1'b1
v_if.cb.i_wr_addr<=txn.wr_addr
v_if.cb.i_wr_data<=txn.wr_data
@(v_if.cb)
v_if.cb.i_wr_en<=1'b0
end
`uvm_info(get_type_name(),"****Driventheinputs(txn)****",UVM_DEBUG)
seq_item_port.item_done(txn)
`uvm_info(get_type_name(),"****Informingthesequence,Iamdone()****",UVM_DEBUG)

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

31/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
end
endtask:run_phase
Reply

Keisuke Shimizu says:


December 20, 2015 at 6:32 pm

The driver must set the txn.rd_data value before calling the item_done().

Reply

Tejas T V says:
January 1, 2016 at 3:27 am

Can you please explain why driver has to set the txn.rd_data ? as it is DUTs output and it shall be monitored by a monitor
?

Keisuke Shimizu says:


January 10, 2016 at 12:20 pm

The mirror task compares the data returned from the driver against the mirrored value regardless of the prediction
mode.

Tejas T V says:
January 30, 2016 at 2:10 am

Thank you, this resolved my problem.


but please clarify the below doubts,
1. If the mirror function compares the returned transaction from driver, why we connect the monitor ap to predictors
bus_in implementation port ?
2. Shouldnt be driver independent of slaves response ? why not monitor tells the predictor the valid transaction ?

Keisuke Shimizu says:


March 6, 2016 at 2:17 pm

1. The monitor is used to capture all transactions on the bus, not just user-initiated register accesses, to keep the
register model up to date.
2. I am afraid I fully understand your question, but the monitor cannot tell which transactions correspond to userinitiated register accesses.

Sasha says:
February 17, 2016 at 1:43 am

Hi
I am Sasha and I am having the same issue as Tejas T V reported while ago. The mirror() task starts comparison before the
bus monitor collects the transaction on the bus. As result, I get this error model.reg_xxx value read from DUT
(0x0000000000000000) does not match mirrored value (0x00000000f0031060). However, I clearly see the correct data
was read back and captured by the monitor. Also, the mirrored value has been updated with the correct data, but
somehow this two processes are not synced.
My driver use get_next_item()/item_done() for handshaking with the sequencer. Also, in my register adapter I do not use
provides_responses.
What should I change in order to make the mirror() pass?
Thank you

Keisuke Shimizu says:


February 21, 2016 at 2:14 pm

Does your driver set the read value to the transaction before calling item_done()?

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

32/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

Sasha says:
February 22, 2016 at 12:01 am

I did as you suggested, now mirror() method works ne.


Thank you very much

Keisuke Shimizu says:


February 22, 2016 at 8:11 am

Im glad to hear it worked. Thanks.

shraga says:
February 2, 2016 at 4:20 am

Hi,
First, Thanks for yours blog.
I try used uvm_reg_block that contains uvm_reg_block in my code.
after the crate model, I can see that each register allocated in 4 address(oset), and when I using write_mem I getting 4 transactions.
I cant understand what wrong with my code.
Thanks.

Reply

Keisuke Shimizu says:


February 7, 2016 at 9:17 am

If you could share your code, I might be able to help.

Reply

Del D. says:
February 7, 2016 at 11:07 am

Hi Keisuke,
How do I write/read to a register in my test using the elds dened in the register model. In some instances, some of the elds get shrunk/expanded or in
some rare occasion moved around within the register during development. How do I make my code immune to these type of changes?
Thanks,
Del

Reply

Keisuke Shimizu says:


February 21, 2016 at 11:59 am

In the jelly_bean_reg_sequence, we wrote to the jb_recipe_reg like this:


write_reg(jb_reg_block.jb_recipe_reg,status,{sour,sugar_free,color,flavor});

Suppose the location of the sour eld and the sugar_free eld are swapped due to the specication change. As you guessed, we have to rewrite the
code to reect the change.
//sugar_freeandsourareswapped
write_reg(jb_reg_block.jb_recipe_reg,status,{sugar_free,sour,color,flavor});

To make the code immune from the change, we could write to the each register eld instead of writing to the entire register:
uvm_status_estatus;
jb_reg_block.jb_recipe_reg.sour.write(status,sour);
jb_reg_block.jb_recipe_reg.sugar_free.write(status,sugar_free);

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

33/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
jb_reg_block.jb_recipe_reg.color.write(status,color);
jb_reg_block.jb_recipe_reg.flavor.write(status,flavor);

However, this will generate four front-door register writes. Better approach would be using the set and update:
uvm_status_estatus;
jb_reg_block.jb_recipe_reg.sour.set(status,sour);
jb_reg_block.jb_recipe_reg.sugar_free.set(status,sugar_free);
jb_reg_block.jb_recipe_reg.color.set(status,color);
jb_reg_block.jb_recipe_reg.flavor.set(status,flavor);
jb_reg_block.jb_recipe_reg.update(status);

This will generate one register write at most. Similarly, we could read the jb_taste_reg without worrying about the location of the taste eld like
this:
uvm_status_estatus;
uvm_reg_data_tvalue;
jb_reg_block.jb_taste_reg.read(status,value);

//Youneedtoknowthelocationofthetastefield([1:0]).
$display("taste=%d",value[1:0]);

//Usingtheregisterfield,thelocationbecomestransparenttotheuser.
$display("taste=%d",jb_reg_block.jb_taste_reg.taste.get());//orget_mirrored_value()

Reply

Sheela B Patil says:


February 23, 2016 at 4:25 am

Hi Keisuke,
Thank you for the blog. Even I had the same issue as Tejas T V & Sasha. but got it resolved as I returned the rd value from the driver.
1. But my question is, If the mirror value compares the data against the data returned from driver with the RTL output, then what is the
necessary of establishing the connection with predictors bus_in imp port with the monitors ap?
2. Is it the only x that we have to return the data from driver ? Cannot we send data to mirror method from the monitor as the bus
transactions are captured at monitor?
Thanks in advance,
Sheela B Patil

Reply

Keisuke Shimizu says:


March 6, 2016 at 1:58 pm

1. The monitor captures all transactions on the bus, not just user-initiated read/writes. For example, the monitor captures the
transactions initiated by a bus bridge to keep the register model up to date.
2. The monitor does not know which transactions are initiated by the mirror methods.

Reply

Sunil says:
February 23, 2016 at 10:12 am

Hello Keisuke,
Please help in knowing the error while executing your code in questasim-10.2b. The error is:
** Error: (vlog-8386) jelly_bean_sequence.sv(13): An enum variable jb_tx.color of type color_e may only be assigned the same enum typed variable or one of
its values. Variable GREEN of type color_e is not valid.
Please guide.
Thanks and Regards
Sunil

Reply

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

34/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

Keisuke Shimizu says:


March 5, 2016 at 7:12 pm

I dont know the reason of the error. Have you tried a newer simulator?

Reply

vamsi says:
March 17, 2016 at 11:15 pm

Hi Keisuke,
I have some doubts in RAL model ,
1. Why we need randomize the class in reg block. rand Class_Name C_N_handle. If we are doing every eld as rand why again we need to
declare rand.
2. what is the exact functionality of support_byte_enable and provide_response?
3. what is the use of lock_model?

Reply

Keisuke Shimizu says:


March 19, 2016 at 4:22 pm

1. If you have the rand type-modier to the registers in the register block, you can randomize the entire register block like
jb_reg_block.randomize(). Otherwise, you need to randomize the registers one by one.
2. 1. If the target bus supports byte enable, set supports_byte_enable to 1. Otherwise, set it to 0.
2. If the target driver provides separate responses using get(req) and put(resp) for example, then set provides_responses
to 1. If the target driver does not provide separate responses using get_next_item(req) and item_done() for example,
then set it to 0.
3. The lock_model() checks the address overlapping and builds the address maps.

Reply

Kevin says:
June 9, 2016 at 11:44 am

Hi Dear Keisuke,
Thank you very much for all your post with so many details.
I try to use the serial bus like i2c to program the registers at the beginning of the simulation. I have some questions about it. would you please take a look at it?
1. I have nished the regmodel. But I am not sure if a reg sequence is good enough, or we need to have a i2c sequence still. ( As my understanding, virtual
sequence will start the reg sequence and pass the transaction all the way down to DUT interface if I do the connection correctly).
2. Since the bus is serial, we need to separate the transaction from regmodel into bit and drive to i2c interafce. . Which way do you think is better for the i2c
driver? In some example , it use seq_item_port. get_next_item and item_done(rsp) to do the conversation. Do you think it s a good way to do it? Do you have
any example for it?
3. In the DUT( jalley_bean_taster.v) I saw these code as follows, Should it be part of the jb_slave_if driver? I am a little bit confused about it.

always@(posedgejb_slave_if.clk)begin
if(jb_slave_if.command==jelly_bean_types::WRITE)begin
flavor<=jb_slave_if.flavor
color<=jb_slave_if.color
sugar_free<=jb_slave_if.sugar_free
sour<=jb_slave_if.sour
endelseif(jb_slave_if.command==jelly_bean_types::READ)begin
jb_slave_if.taste<=taste
end
end

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

35/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
always@(posedgejb_slave_if.clk)begin
if(jb_slave_if.flavor==jelly_bean_types::CHOCOLATE&&
jb_slave_if.sour)begin
taste<=jelly_bean_types::YUCKY
endelseif(jb_slave_if.flavor!=jelly_bean_types::NO_FLAVOR)begin
taste<=jelly_bean_types::YUMMY
end
end
Thanks you very much for your time and help.

Reply

Keisuke Shimizu says:


June 12, 2016 at 4:50 pm

1. I assume you already have the I2C transaction class (i2c_transaction) that contains I2C address and data information, and the I2C driver that
converts an I2C transaction into SDA/SCL wiggling. If so, all you need is a register adapter that converts register operation from/to an
i2c_transaction. Once you let your reg_map know the adapter by calling set_sequencer(), you should be able to do your_reg.write(status,
value), etc. in your sequence.
2. I would use get_next_item and item_done as you mentioned.
3. The code you mentioned represents the DUT. Its not a verication component.

Let me know if you need further clarication.

Reply

Kevin says:
June 14, 2016 at 6:01 pm

Hi Keisuke,
Thank you very much for your replay. The diagram is great !!
Yes, I write my own SCCB driver( i2c like interface). I still have some questions about the reg model to interface.
1. you should be able to do your_reg.write(status, value), etc. in your sequence.
You mention above that I am able to do reg.write in my sequence. Do you mean test sequence? As my understanding now, I do not need to
write an SCCB sequence. I could use the virtual sequence in the test cases to program register. Please correct me if i am wrong. For read I
have more questions.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

36/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
Write:
virtual sequence>reg_sequence (uvm_reg_bus_op, write)>SCCB_adapter.reg2bus(SCCB_trans)>SCCB_sequencer>SCCB_driver
>sda/scl.
Read:
virtual sequence>reg_sequence (uvm_reg_bus_op. read)>SCCB_adapter.reg2bus(SCCB_trans)>SCCB_sequencer>SCCB_driver
>sda/scl>SCCB_driver get read data> save it to SCCB_trans.
After read operation, driver will get data from sda/scl and pack it into SCCB_trans, do you think it is necessary to use a tlm_fo to hold the
data? ( As my understading, tlm_fo is better). I am not sure where should we use the SCCB monitor to grep the SCCB_trans.
And how do we compare the value with the value in the regmodel.
2. Do we need to call reg2bus and bus2reg anywhere in the code? ( I do not nd it). Or once we we do reg.write and reg.read in the
reg_sequence, it will be called automatically. I understand the usage of reg2bus, what why do we need bus2reg? In the read ow above, I do
not nd the place to use bus2reg.
3. Some of the Read/Write are not single read and write. But the access operations are only UVM_READ and UVM_WRITE( I search the
Reference manual). Does that mean the adapter do not handle complicated R/W. Those control will located in the SCCB driver.
Best,

Reply

Keisuke Shimizu says:


June 22, 2016 at 6:03 pm

1. I dont think you need a uvm_tlm_fifo. In your sequence, call your_reg.read(status,value), then compare the value
against your expected value. Regarding the monitor location, please see the read() section of Register Access Methods.
2. You dont need to call reg2bus or bus2reg. Your register map calls bus2reg after your sequence has completed a register read
transaction on the bus. Then the converted value is used to update the register model.
3. The adapter should do simple eld-to-eld conversion between the uvm_reg_bus_op and the SCCB_trans. Serialization and
deserialization should be done by the driver.

Reply

Kevin says:
July 6, 2016 at 2:26 pm

Thanks Keisuke for your detailed explanation. I will try to implement it and let you know if it work.
Thank you very much.
Best

Kevin says:
July 19, 2016 at 5:15 pm

Hi Keisuke,
I try to use virtual sequence and virtual sequencer to control the test. Would you please take a look at the questions as
follows,
1. I wonder if I connect the m_reg_seq to p_sequencer.m_sccb_sqr will work? I try to control the RAL sequence though
virtual sequence and virtual sequencer in the test.
2. Since I do m_vseq.start(m_env.m_vsqr); Do I need to do anything else to instantiate the vseq?
Such as connecting m_vseq.m_sccb_sqr to env.m_vsqr.m_sccb_sqr?? I think i already connect them in the env so that it
should be OK.
3. p_sequencer seems not quite easy to connect. Do you think just use virtual sequence will be better?

//Insidethevirtualsequenceclass:
classmy_vsequenceextendsuvm_sequence
`uvm_declare_p_sequencer(my_vsequencer)
....
taskbody()

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

37/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic
m_clk_seq=clk_base_sequence::type_id::create("m_clk_seq")
m_rst_seq=rst_base_sequence::type_id::create("m_rst_seq")
m_reg_seq=reg_base_sequence::type_id::create("m_reg_seq")

fork
m_clk_seq.start(p_sequencer.m_clk_sqr)
m_rst_seq.start(p_sequencer.m_rst_sqr)
m_reg_seq.start(p_sequencer.m_sccb_sqr)//
join
endtask
endclass
//Insidetheenvclass:
classmy_envextendsuvm_env
my_vsequencerm_vsqr
...

functionvoidconnect_phase(uvm_phasephase)
super.connect_phase(phase)
m_vsqr.m_clk_sqr=m_clk_agt.m_sqr
m_vsqr.m_rst_sqr=m_rst_agt.m_sqr
m_vsqr.m_sccb_sqr=m_sccb_agt.m_sqr
m_env_cfg.m_reg_block.reg_map.set_sequencer(.sequencer(m_sccb_agt.m_sqr),
.adatpter(m_sccb_agt.m_sccb_adapter))
m_env_cfg.m_reg_block.reg_map.set_auto_prediect(0)

endfunction:connect_phase
endclass

//Insidethetestclass:
classmy_testextendsuvm_test
....
my_envm_env
m_env=my_env::type_id::create("m_env")
taskrun
...
m_vseq=my_vsequence::type_id::create("m_vseq")

//...
m_vseq.start(m_env.m_vsqr)
//...
endtask:run

Keisuke Shimizu says:


July 24, 2016 at 4:55 pm

1. It looks ne.
2. m_vseq.start(m_env.m_vsqr) should be enough.
3. Your code looks good, but you dont have to use a virtual sequencer.

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

38/39

29/12/2016

UVMTutorialforCandyLovers9.RegisterAbstractionClueLogic

mayurkubavat says:
July 28, 2016 at 12:47 am

Awesome post!

Reply

Ax Maxou says:
August 11, 2016 at 12:49 am

Hi Keisuke,
Thanks a lot for this topic, but I have some quastion. What I should do if I have 2 interaction register elds in 2 registers. For example reg A.eld1(RO), but
always have value from reg B.eld1(RW) . How I can implement this using RAL.

Reply

Keisuke Shimizu says:


August 27, 2016 at 3:16 pm

I wrote a new article to answer your question. Let me know if you have further questions.

Reply

Leave a Reply
Enteryourcommenthere...

(c) 2011-2016, ClueLogic, LLC


Proudly powered by WordPress | Education Hub by WEN Themes

http://cluelogic.com/2012/10/uvmtutorialforcandyloversregisterabstraction/

39/39

Vous aimerez peut-être aussi