Jump to content
Sign in to follow this  
yyn

IES + AXI UVC + UVM_REG question about blocking write operation

Recommended Posts

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

Share this post


Link to post
Share on other sites

A blocking adapter sequence would call get_response() before calling item_done() on it's request. If you give an example of what you have that's non-blocking, I can show you how to modify it to be blocking.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Hi yyn

I have to code an adapter for connecting the register model and the adapter should convert register items into axi burst items. I m also using the AXI UVC from cadence

The following is a uvm cookbook example for a reg2bus transaction for an ahb transaction.

virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);

apb_seq_item apb = apb_seq_item::type_id::create("apb");

apb.we = (rw.kind == UVM_READ) ? 0 : 1;

apb.addr = rw.addr;

apb.data = rw.data;

return apb;

endfunction: reg2bus

I have a similar one for axi,

virtual function uvm_sequence_item reg2bus(const ref uvm_reg_bus_op rw);

vr_axi_master_burst axi = axi_master_burst::type_id::create("axi");

axi.direction = (rw.kind == UVM_READ) ? 0 : 1;

axi.addr = rw.addr;

axi.data = rw.data;

`uvm_info("ADAPTER","before returning axi",UVM_LOW);

return axi;

`uvm_info("ADAPTER","after returning axi",UVM_LOW);

endfunction: reg2bus

The simulation hangs at the return axi point. It does not return. What can the reason for a simulation hanging at return axi point?

Has anyone implemented a register model for an AXI transaction?

I know that just configuring the data and the address wont be enough, but why does it hang at return axi ?

Share this post


Link to post
Share on other sites

I have a set of registers extending from uvm_reg. The registers are created in a file and the file is created in a register block. In a sequence, the model is created

The body of the sequence is as follows :

virtual task body();

`uvm_info("SEQ","Entered task body",UVM_LOW);

data[31:0] = 32'h0FFF_0FFF;

rm.rf.r1.write(status,data);

`uvm_info("SEQ","Finished writing the data",UVM_LOW);

endtask :body

where rm = register model

rf = register file

r1 = register

I have used the display statements for debug purpose and i see that inspite of entering the body, it hangs during the write. The write does not happen and it hangs in the adapter function before returning the axi burst item( see above post)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×