end#1;rg.mirror(status,UVM_CHECK,UVM_BACKDOOR,uvm_reg_map::backdoor(),this);if(status!=UVM_IS_OK)begin`uvm_error("uvm_reg_access_seq",{"Status was '",status.name(),"' when reading reset value of register '",rg.get_full_name(),"' through backdoor"})endrg.write(status,v,UVM_BACKDOOR,maps[j],this);if(status!=UVM_IS_OK)begin`uvm_error("uvm_reg_access_seq",{"Status was '",status.name(),"' when writing '",rg.get_full_name(),"' through backdoor"})endrg.mirror(status,UVM_CHECK,UVM_FRONTDOOR,maps[j],this);if(status!=UVM_IS_OK)begin
end#1;rg.mirror(status,UVM_CHECK,UVM_BACKDOOR,null,this);if(status!=UVM_IS_OK)begin`uvm_error("uvm_reg_access_seq",{"Status was '",status.name(),"' when reading reset value of register '",rg.get_full_name(),"' through backdoor"})endrg.write(status,v,UVM_BACKDOOR,maps[j],this);if(status!=UVM_IS_OK)begin`uvm_error("uvm_reg_access_seq",{"Status was '",status.name(),"' when writing '",rg.get_full_name(),"' through backdoor"})endrg.mirror(status,UVM_CHECK,UVM_FRONTDOOR,maps[j],this);if(status!=UVM_IS_OK)begin
// get_local_mapfunctionuvm_reg_mapuvm_reg::get_local_map(uvm_reg_mapmap,stringcaller="");if(map==null)returnget_default_map();if(m_maps.exists(map))returnmap;foreach(m_maps[l])beginuvm_reg_maplocal_map=l;uvm_reg_mapparent_map=local_map.get_parent_map();while(parent_map!=null)beginif(parent_map==map)returnlocal_map;parent_map=parent_map.get_parent_map();endend`uvm_warning("RegModel",{"Register '",get_full_name(),"' is not contained within map '",map.get_full_name(),"'",(caller==""?"":{" (called from ",caller,")"})})returnnull;endfunction
case(rw.path)// ...VIA USER BACKDOORUVM_BACKDOOR:beginuvm_reg_backdoorbkdr=get_backdoor();uvm_reg_mapmap=uvm_reg_map::backdoor();if(map.get_check_on_read())exp=get();if(bkdr!=null)bkdr.read(rw);elsebackdoor_read(rw);value=rw.value[0];// Need to clear RC fields, set RS fields and mask WO fieldsif(rw.status!=UVM_NOT_OK)beginuvm_reg_data_two_mask;foreach(m_fields[i])beginstringacc=m_fields[i].get_access(uvm_reg_map::backdoor());if(acc=="RC"||acc=="WRC"||acc=="WSRC"||
if(rw.path==UVM_DEFAULT_PATH)rw.path=m_parent.get_default_path();if(rw.path==UVM_BACKDOOR)beginif(get_backdoor()==null&&!has_hdl_path())begin`uvm_warning("RegModel",{"No backdoor access available for register '",get_full_name(),"' . Using frontdoor instead."})rw.path=UVM_FRONTDOOR;endelserw.map=uvm_reg_map::backdoor();endif(rw.path!=UVM_BACKDOOR)beginrw.local_map=get_local_map(rw.map,caller);
m_lineno=lineno;if(path==UVM_DEFAULT_PATH)path=m_parent.get_default_path();if(path==UVM_BACKDOOR&&(bkdr!=null||has_hdl_path()))map=uvm_reg_map::backdoor();elsemap=get_local_map(map,"read()");if(map==null)return;// Remember what we think the value is before it gets updatedif(check==UVM_CHECK)exp=get_mirrored_value();XreadX(status,v,path,map,parent,prior,extension,fname,lineno);
// get_local_mapfunctionuvm_reg_mapuvm_reg::get_local_map(uvm_reg_mapmap);if(map==null)returnget_default_map();if(m_maps.exists(map))returnmap;foreach(m_maps[l])beginuvm_reg_maplocal_map=l;uvm_reg_mapparent_map=local_map.get_parent_map();while(parent_map!=null)beginif(parent_map==map)returnlocal_map;parent_map=parent_map.get_parent_map();endend`uvm_warning("RegModel",{"Register '",get_full_name(),"' is not contained within map '",map.get_full_name(),"'"})returnnull;endfunction
case(rw.get_door())// ...VIA USER BACKDOORUVM_BACKDOOR:beginuvm_reg_data_tfinal_val;uvm_reg_backdoorbkdr=get_backdoor();if(rw.get_map()!=null)rw.set_local_map(rw.get_map());elserw.set_local_map(get_default_map());value=rw.get_value(0);// Mimick the final value after a physical readrw.set_kind(UVM_READ);if(bkdr!=null)bkdr.read(rw);else
uvm_reg_maptmp_map;uvm_reg_maptmp_local_map;if(rw.get_door()==UVM_DEFAULT_DOOR)rw.set_door(m_parent.get_default_door());if(rw.get_door()==UVM_BACKDOOR)beginif(get_backdoor()==null&&!has_hdl_path())begin`uvm_warning("RegModel",{"No backdoor access available for register '",get_full_name(),"' . Using frontdoor instead."})rw.set_door(UVM_FRONTDOOR);endelseif(rw.get_map()==null)beginuvm_reg_mapbkdr_map=get_default_map();if(bkdr_map!=null)rw.set_map(bkdr_map);elserw.set_map(uvm_reg_map::backdoor());endend
// poketaskuvm_reg::poke(outputuvm_status_estatus,inputuvm_reg_data_tvalue,inputstringkind="",inputuvm_sequence_baseparent=null,inputuvm_objectextension=null,inputstringfname="",inputintlineno=0);uvm_reg_backdoorbkdr=get_backdoor();uvm_reg_itemrw;m_fname=fname;m_lineno=lineno;if(bkdr==null&&!has_hdl_path(kind))begin`uvm_error("RegModel",{"No backdoor access available to poke register '",get_full_name(),"'"})status=UVM_NOT_OK;return;endif(!m_is_locked_by_field)XatomicX(1);// create an abstract transaction for this operationrw=uvm_reg_item::type_id::create("reg_poke_item",,get_full_name());rw.set_element(this);rw.set_door(UVM_BACKDOOR);rw.set_element_kind(UVM_REG);rw.set_kind(UVM_WRITE);rw.set_bd_kind(kind);rw.set_value((value&((1<<m_n_bits)-1)),0);rw.set_parent_sequence(parent);rw.set_extension(extension);rw.set_fname(fname);rw.set_line(lineno);if(bkdr!=null)bkdr.write(rw);elsebackdoor_write(rw);status=rw.get_status();`uvm_info("RegModel",$sformatf("Poked register \"%s\": 'h%h",get_full_name(),value),UVM_HIGH)do_predict(rw,UVM_PREDICT_WRITE);if(!m_is_locked_by_field)XatomicX(0);endtask:poke// peektaskuvm_reg::peek(outputuvm_status_estatus,outputuvm_reg_data_tvalue,inputstringkind="",inputuvm_sequence_baseparent=null,inputuvm_objectextension=null,inputstringfname="",inputintlineno=0);uvm_reg_backdoorbkdr=get_backdoor();uvm_reg_itemrw;m_fname=fname;m_lineno=lineno;if(bkdr==null&&!has_hdl_path(kind))begin`uvm_error("RegModel",$sformatf("No backdoor access available to peek register \"%s\"",get_full_name()))status=UVM_NOT_OK;return;endif(!m_is_locked_by_field)XatomicX(1);// create an abstract transaction for this operationrw=uvm_reg_item::type_id::create("mem_peek_item",,get_full_name());rw.set_element(this);rw.set_door(UVM_BACKDOOR);rw.set_element_kind(UVM_REG);rw.set_kind(UVM_READ);rw.set_bd_kind(kind);rw.set_parent_sequence(parent);rw.set_extension(extension);rw.set_fname(fname);rw.set_line(lineno);if(bkdr!=null)bkdr.read(rw);elsebackdoor_read(rw);status=rw.get_status();value=rw.get_value(0);`uvm_info("RegModel",$sformatf("Peeked register \"%s\": 'h%h",get_full_name(),value),UVM_HIGH)do_predict(rw,UVM_PREDICT_READ);if(!m_is_locked_by_field)XatomicX(0);endtask:peek
// Task: write//// Write the specified value in this field//// Write ~value~ in the DUT field that corresponds to this// abstraction class instance using the specified access// ~path~. // If the register containing this field is mapped in more// than one address map, // an address ~map~ must be// specified if a physical access is used (front-door access).// If a back-door access path is used, the effect of writing// the field through a physical access is mimicked. For// example, read-only bits in the field will not be written.//// The mirrored value will be updated using the <uvm_reg_field::predict()>// method.//// If a front-door access is used, and// if the field is the only field in a byte lane and// if the physical interface corresponding to the address map used// to access the field support byte-enabling,// then only the field is written.// Otherwise, the entire register containing the field is written,// and the mirrored values of the other fields in the same register// are used in a best-effort not to modify their value.//// If a backdoor access is used, a peek-modify-poke process is used.
// Task: read//// Read the current value from this field//// Read and return ~value~ from the DUT field that corresponds to this// abstraction class instance using the specified access// ~path~. // If the register containing this field is mapped in more// than one address map, an address ~map~ must be// specified if a physical access is used (front-door access).// If a back-door access path is used, the effect of reading// the field through a physical access is mimicked. For// example, clear-on-read bits in the field will be set to zero.//// The mirrored value will be updated using the <uvm_reg_field::predict()>// method.//// If a front-door access is used, and// if the field is the only field in a byte lane and
inputintlineno=0);// Task: poke//// Deposit the specified value in this field//// Deposit the value in the DUT field corresponding to this// abstraction class instance, as-is, using a back-door access.// A peek-modify-poke process is used// in a best-effort not to modify the value of the other fields in the// register.//// The mirrored value will be updated using the <uvm_reg_field::predict()>// method.//externvirtualtaskpoke(outputuvm_status_estatus,inputuvm_reg_data_tvalue,inputstringkind="",inputuvm_sequence_baseparent=null,inputuvm_objectextension=null,inputstringfname="",inputintlineno=0);// Task: peek//// Read the current value from this field//// Sample the value in the DUT field corresponding to this// abstraction class instance using a back-door access.// The field value is sampled, not modified.//// Uses the HDL path for the design abstraction specified by ~kind~.//// The entire containing register is peeked// and the mirrored value of the other fields in the register// are updated using the <uvm_reg_field::predict()> method.////externvirtualtaskpeek(outputuvm_status_estatus,outputuvm_reg_data_tvalue,inputstringkind="",inputuvm_sequence_baseparent=null,inputuvm_objectextension=null,inputstringfname="",inputintlineno=0);
uvm_reg_blockblk=m_parent.get_block();rw.path=blk.get_default_path();endif(rw.path==UVM_BACKDOOR)beginif(m_parent.get_backdoor()==null&&!m_parent.has_hdl_path())begin`uvm_warning("RegModel",{"No backdoor access available for field '",get_full_name(),"' . Using frontdoor instead."})rw.path=UVM_FRONTDOOR;endelserw.map=uvm_reg_map::backdoor();endif(rw.path!=UVM_BACKDOOR)beginrw.local_map=m_parent.get_local_map(rw.map,caller);
rw.set_door(blk.get_default_door());endif(rw.get_door()==UVM_BACKDOOR)beginif(m_parent.get_backdoor()==null&&!m_parent.has_hdl_path())begin`uvm_warning("RegModel",{"No backdoor access available for field '",get_full_name(),"' . Using frontdoor instead."})rw.set_door(UVM_FRONTDOOR);endelserw.set_map(uvm_reg_map::backdoor());endif(rw.get_door()!=UVM_BACKDOOR)beginrw.set_local_map(m_parent.get_local_map(rw.get_map()));if(rw.get_local_map()==null)begin
m_parent.do_write(rw);`elseif(!is_indv_accessible(rw.get_door(),rw.get_local_map()))beginrw.set_element_kind(UVM_REG);rw.set_element(m_parent);rw.set_value(value_adjust,0);m_parent.do_write(rw);if(bad_side_effect)begin`uvm_warning("RegModel",$sformatf("Writing field \"%s\" will cause unintended side effects in adjoining Write-to-Clear or Write-to-Set fields in the same register",this.get_full_name()))endendelsebeginuvm_reg_mapitem_map=rw.get_local_map();uvm_reg_mapsystem_map=item_map.get_root_map();uvm_reg_field_cb_itercbs=new(this);m_parent.Xset_busyX(1);
// poketaskuvm_reg_field::poke(outputuvm_status_estatus,inputuvm_reg_data_tvalue,inputstringkind="",inputuvm_sequence_baseparent=null,inputuvm_objectextension=null,inputstringfname="",inputintlineno=0);uvm_reg_data_ttmp;m_fname=fname;m_lineno=lineno;if(value>>m_size)begin`uvm_warning("RegModel",{"uvm_reg_field::poke(): Value exceeds size of field '",get_name(),"'"})value&=value&((1<<m_size)-1);endm_parent.XatomicX(1);m_parent.m_is_locked_by_field=1'b1;tmp=0;// What is the current values of the other fields???m_parent.peek(status,tmp,kind,parent,extension,fname,lineno);if(status==UVM_NOT_OK)begin`uvm_error("RegModel",{"uvm_reg_field::poke(): Peek of register '",m_parent.get_full_name(),"' returned status ",status.name()})m_parent.XatomicX(0);m_parent.m_is_locked_by_field=1'b0;return;end// Force the value for this field then poke the resulting valuetmp&=~(((1<<m_size)-1)<<m_lsb);tmp|=value<<m_lsb;m_parent.poke(status,tmp,kind,parent,extension,fname,lineno);m_parent.XatomicX(0);m_parent.m_is_locked_by_field=1'b0;endtask:poke// peektaskuvm_reg_field::peek(outputuvm_status_estatus,outputuvm_reg_data_tvalue,inputstringkind="",inputuvm_sequence_baseparent=null,inputuvm_objectextension=null,inputstringfname="",inputintlineno=0);uvm_reg_data_treg_value;m_fname=fname;m_lineno=lineno;m_parent.peek(status,reg_value,kind,parent,extension,fname,lineno);value=(reg_value>>m_lsb)&((1<<m_size))-1;endtask:peek