Jump to content

yyn

Members
  • Content Count

    16
  • Joined

  • Last visited

About yyn

  • Rank
    Junior Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Dear all, I'd like to access a register via multiple physical interfaces (bfm). Is it possible to set 2 different sequencers to the registers with same address? I have read this is a known issue from this forum. Could anybody give me a good example? I'm looking for a solution that there is no problem in prediction as well as write/read of UVM_REG. Thanks & Regards,
  2. Hi, I am testing multiple reset. My testbench is based on UVM_REG and I am using "write()" API to write registers. If reset is asserted when write() is executed, the next warning occurs. UVM_WARNING (UVM/FLD/SET/BSY) Setting the value of field "xxx" while containing register "yyy" is being accessed may result in loss of desired field value. A race condition between threads concurrently accessing the register model is the likely cause of the problem. As I debugged, the error is caused by "m_is_busy" variable of uvm_reg.svh. While write() is executed "m_is_busy" is set to 1 and set to 0. When reset is asserted, user scenario kills write() operation and reset all registers as calling reg_block.reset(). If reg_block.reset() is executed, mirrored value seems to be reset but desired value does not. And also, if reset is asserted between the time that "m_is_busy" is set to 1 and the time that "m_is_busy" is set to 0, "m_is_busy" remains "1". The same register is accessed later again, the above warning occurs. I think this warning is no effect for simulation result. But I want to clear this warning. Should user control UVM internal variable such as m_is_busy? When reset is asserted, what is right that which value the desired value of field has? How can I clear this warning? Thanks & Regards, yyn
  3. Dear Karandeep, Thanks for your reply. I solved the problem. Your answer is very helpful. Thanks a lot. I'm developing VIP based on UVM. This error is related to VIP and user scenario for multiple reset test. According to the time when reset is started and ended, this error occurs case by case. Bye.
  4. Hi, I am implementing multiple reset inside UVC componenets (sequencer, driver, monitor and etc). When reset is asserted between get_next_item() and item_done(), the following error is issued. UVM_ERROR (SEQREQZMB) The task responsible for requesting a wait_for_grant on sequencer '....' for sequence '...' has been killed, to avoid a deadlock the sequence will be removed from the arbitration queues. I guess this error is caused that queue for sequence item already gets a item to transfer into driver. How can I fix this problem? How can I remove current item from the arbitration queue? My UVC is using run_phase(). I don't use main_phase(). So, I would like to control it using run_phse(). Thanks & Regards,
  5. Hi, I have a question when I use uvm_config_db for interface connection. Generally, I know we use set() and get() function of "uvm_config_db" when we connect interface instance with virtual interface. As I know, uvm_config_db#(virtual aaa_intf)::set() is described inside top testbench module. And uvm_config_db#(virtual aaa_intf)::get() is some phase of inside class. What I want to do is to move set() function into some phase of class. Is it possible? If possible, which phase can I use not to be no problem in topology? Could you give me an example? I generally descirbes uvm_config_db#(virtual aaa_intf)::get() in connect_phase. Thanks & Regards, YYN
  6. Dear all, I made interrupt sequence. For interrupt opeartion, I use grab/ungrab function from UVM. But I have a problem not to grab. My testbench has 4 sequencers from interface UVC, so virtual sequence handles this. My interrupt sequence is based on uvm_reg_sequence. And I start the interrupt sequence in virtual sequence class and this virtual sequence is started in virtual sequencer. #-------------- class int_seq_c extends uvm_reg_sequence; ... ... virutal task body(); forever begin @(posedge interrupt); grab(regmodel.default_map.get_sequencer()); // Sequencer of AXI bus is get. // clear interrupt ungrab(regmodel.default_map.get_sequencer()); end endtask endclass class int_virt_seq_c extends uvm_sequence; int_seq_c int_seq; virutal task body(); int_seq = int_seq_c::type_id::create("int_seq"); int_seq.start(null); endtask endclass class my_virtual_sequencer extends uvm_sequencer; ... ... virtual task run_phase(uvm_phase phase); int_virt_seq = int_virt_seq_c::type_id::create("int_virt_seq"); fork int_virt_seq.start(this); join_none endtask endclass I checked grab startus in int_seq_c class using "is_grabbed()" function after executing "grab()" task. But 0 value is returned. What is my problem? How can I fix my problem? Thanks and Regards, // yyn
  7. Dear Jadec, First of all, thanks for your reply. The below shows some parts of adapter code. Please understand that some codes are ommitted. #--------------------------------------------------- `ifndef VR_AXI_REG_ADAPTER `define VR_AXI_REG_ADAPTER class vr_axi_reg_adapter extends uvm_reg_adapter; int unsigned burst_unique_counter ; vr_axi_address_t address ; vr_axi_privileged_mode_t privileged_mode ; int unsigned length ; vr_axi_data_t data_list [] ; `uvm_object_utils_begin(vr_axi_reg_adapter) `uvm_object_utils_end function new(string name = "vr_axi_reg_adapter"); super.new(name); provides_responses = 1; endfunction virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw); int unsigned burst_num; vr_axi_master_burst axi_burst; `uvm_info(get_type_name(), "reg2bus: start ...", UVM_MEDIUM) axi_burst = vr_axi_master_burst::type_id::create("vr_axi_master_burst"); burst_unique_counter++; address = rw.addr ; privileged_mode = NON_PRIVILEGED ; … … length = 1 ; if (rw.kind == UVM_WRITE) begin direction = vr_axi::WRITE ; data_list = new[1] ; data_list[0] = rw.data ; end else begin direction = vr_axi::READ ; end axi_burst.transfers = new[length]; axi_burst.data = new[length]; axi_burst.start_address = address ; axi_burst.use_start_address = 1 ; axi_burst.privileged = privileged_mode ; axi_burst.use_privileged = 1 ; … … axi_burst.length = length ; axi_burst.use_length = 1 ; axi_burst.transmit_delay = 0 ; axi_burst.use_transmit_delay = 1 ; if (direction == vr_axi::WRITE) begin for (int i = 0; i < length; i++) begin axi_burst.data = data_list; end //axi_burst.use_transfers = 1; axi_burst.use_data = 1; end `uvm_info(get_type_name(), $psprintf("reg2bus: convert register to axi (%s)", axi_burst.direction.name), UVM_HIGH) `uvm_info(get_type_name(), {"reg2bus: axi burst info:\n", axi_burst.sprint()}, UVM_HIGH) `uvm_info(get_type_name(), "reg2bus: done ...", UVM_MEDIUM) return axi_burst; endfunction: reg2bus virtual function void bus2reg(uvm_sequence_item bus_item, ref uvm_reg_bus_op rw); vr_axi_monitor_burst axi_burst; if(bus_item.get_name() == "vr_axi_monitor_burst") begin `uvm_info(get_type_name(), "bus2reg: start ...", UVM_MEDIUM) if (!$cast(axi_burst, bus_item)) begin `uvm_fatal(get_type_name(), "provided bus_item is not correct type") return; end rw.kind = axi_burst.direction == vr_axi::READ ? UVM_READ : UVM_WRITE; rw.addr = axi_burst.start_address; rw.data = axi_burst.transfers[0].data; rw.status = UVM_IS_OK; `uvm_info(get_type_name(), {"bus2reg: axi burst info:\n", axi_burst.sprint()}, UVM_HIGH) `uvm_info(get_type_name(), "bus2reg: done ...", UVM_MEDIUM) end endfunction endclass `endif // VR_AXI_REG_ADAPTER #------------------------------------------------------------------------- Additionally, can I ask one more question for AXI UVC and IES? As shown in above codes, bus2reg() function has "if" statement. This statement was added because "bus_item" is occured twice. The first "bus_item" occurs at the time that AXI driver drives transaction (vr_axi_master_burst) and the second "bus_item" occurs at the time that the transaction (vr_axi_monitor_burst) is monitored in AXI monitor. Is it right operation? I implemented an explicit predictor and connected "bus_in" port of predictor to analysis port of AXI monitor. #----- uvm_reg_predictor#(vr_axi_monitor_burst) axi2reg_predictor; ... ... axi_agent0_monitor_tlm.axi_monitor_burst_out.connect(axi2reg_predictor.bus_in); #--- I don't understand the relation exactly between "bus2reg()" and predictor and I am confusing it is correct operation that "bus_item" occurs two items, "vr_axi_master_burst" and "vr_axi_monitor_burst", when using AXI UVC (Actually I think that "bus_item" must ony occur when the transaction is monitored.). (I already asked this to Cadence, but I am still waiting for reply for long time. If you know, help me, please!!) Thanks a lot. Regards, // yyn
  8. Dear, I am simulating on IES using AXI UVC from Cadence. And the register is written using "write()" task from UVM. In this case, "reg2bus()" of register adapter class translates uvm_reg_bus_op into vr_axi_master_burst which is a sequence item of AXI. Also, "bus2reg" function updates bus_item into uvm_reg_bus_op. But transactions for setting registers are sent as non-blocking way. I want to implement blocking way. Blocking operation means that transaction for the next register is sent after transaction of the current register is sent and that transaction is ended. But, currently the second transaction is started before the previous transaction of AXI interface is ended. I want to control blocking operation in register adapter. How can I impelemt register adapter class? Thanks & Regards, //yyn
  9. Hello mszabo, Thanks for reply. I have a question for your answer. I am using UVM1.1 and my adapter has only bus2reg() and reg2bus() function. Where can I add "has_response"? Can you show me the example? Thanks & Regards, yyn
  10. Hello, My test case reads the register data from DUT using mirror() after reset is ended. But, the error occurrs like this. [195] UVM_ERROR (RegModel) Register "xxxx" value read from DUT (0x0000) does not match mirrored value (0x80). In my testbench, the register is set through AXI interface. The time "195 ns" that the error is reported is the time that read transaction is started. Actually, the readback value from DUT appears in "245 ns". I think the datas between the DUT readback value and the expected value of register package are compared in end of read transaction. But mirror() function of uvm_reg compares the data at the start of transaction. How can I fix my problem? How can I implement that the data can be compared at the end of transaction? Thanks & Regards, yyn
  11. Hi, I have a question of `uvm_do() macro usage. The following is an example code. class my_transfer extends uvm_object; rand string direction; rand bit [31:0] addr; rand bit [31:0] wdata; endclass class my_transaction extends uvm_sequence_item; rand int delay_before_transaction; rand int transfer_size; constraint const_c { transfer_size < 1000; } rand my_transfer transfers[]; constraint transfer_c {transfers.size() == transfer_size; } rand int delay_to_req_end; endclass In my sequence class, I want to execute like below code. But randomization is failed. Becuase there is no allocation of "transfers" array. virtual task body(); `uvm_do(req); // or `uvm_do_with(req, {req.transfer_size == 7; req.transfers[0].direction == READ; }) endtask If above sequence works, how should I modify my code? Is there any simple example? (I want that each transfer within transaction has constrained-random value for each field and I want to control this constraint in test senario or sequence.) Thanks & Regards, YYN
  12. Hi uwes, Error is compilation error of IES. Actually I already asked to Cadence support center, and I am still waiting for reply. But this is very urgent to me. Error message is "E, TYCMPAT: formal and actual do not have assignment compatible data types (expecting datatype compatible with 'specialization of class uvm_port_base' but found 'specialization of class uvm_analysis_imp' instead). I hope to obtain solution anywhere quickly. Thanks for your interest in advance.
  13. Hello, I have a question for analysis port connection. A UVC monitor that I use provides anaylsis port as followings (I provided this monitor from vendor). ************************************************** uvm_analysis_port #(uvm_sequence_item) monitor_item_done; ************************************************** I'd like to connect this port to "bus_in" of "uvm_reg_predictor" in my testbench. "bus_in" is a port that is provided from UVM library. ***************************************************** uvm_anaylsis_imp #(BUSTYPE, uvm_reg_dredictor #(BUSTYPE)) bus_in; ***************************************************** In my testbench code, I connected as followings, but this does not work in simulator. ********************************************************* if_env.master.monitor.monitor_item_done.connect(bus2reg_predictor.bus_in); ********************************************************* "axi2reg_predictor" is the handler name of "uvm_reg_predictor". How can I connect "bus_in" with "monitor_item_done"? Thanks & Regards,
  14. Hello, I have two questions about "uvm_reg_sequence". In below example, I'd like to use "CLK", which is a signal of "interface my_if" in "my_seq" extended from "uvm_reg_sequence", How can I connect interface of module to virtual interface of sequence class using "uvm_config_db#(virtual my_if)::get(xxxxx);" ****************************** interface my_if; logic CLK; endinterface module my_top; import uvm_pkg::*; `include "uvm_macros.svh" reg CLK; my_if mif(.*); assign mif.CLK = CLK; class my_seq extends uvm_reg_sequence; virtual interface my_if vif; virtual task body(); repeat (10) @(posedge vif.CLK); endtask endclass class my_test extends uvm_test; my_seq seq; virtual task run_phase(uvm_phase phase); super.run_phase(phase); seq = my_seq::type_id::creat("seq"); seq.start(null); endtask endclass initial begin CLK = 0; forever begin #5 CLK <= ~CLK; end end my_if mif (.*); assign mif.CLK = CLK; initial begin uvm_config_db#(virtual my_if)::set(null, "uvm_test_top.env*", "vif", mif); end initial begin run_test(); end endmodule ********************* How can I specify the register sequence (extended from "uvm_reg_sequence") as default sequence? Generally, UVM user guide shows example to use "start()". But, I want to use "uvm_config_db#(uvm_object_wrapper)::set(this, "xxxxx", "default_sequence", my_seq::type_id::get());" I don't know what is specified in "xxxxx". Thanks & Regards, yyn
  15. Dear jadec, Thanks for your answer. If possible, could you give an example code of your answer? Is there good example using built-in functions such as get_coverage() and include_coverage() for customized type "UVM_CVR_REG_KIND" ? I'd like to contorl coverage on or off as below after adding my type : uvm_reg::include_coverage("*", UVM_CVR_REG_KIND + UVM_CVR_FIELD_VALS); Thanks a lot. YYN
×