Jump to content


  • Content Count

  • Joined

  • Last visited

  1. Hi I need some suggestions to avoid race conditions I have two tasks : write and read automatic task write_reg(regname,value); . . . endtask automatic task read_reg(regname,value); . . . endtask These tasks can be called simultaneously, so i have used a semaphore to prevent two writes happening at the same time or two reads accessing the same task , the modification being : automatic task write_reg(regname,value); wr_key.get(1); . . . wr_key.put(1); endtask automatic task read_reg(regname,value); rd_key.get(1); . . . rd_key.put(1); endtask This works fine. Now when the problem is to avoid write and read happening to the same register, i am facing different sorts of race conditions when i implement different logic. Method 1: automatic task write_reg(regname,value); wr_key.get(1); wr_reg = regname; if(wr_reg==rd_reg) wait(rd_reg=="READ_DONE"); . . wr_key.put(1); wr_reg = WRITE_DONE; endtask automatic task read_reg(regname,value); rd_key.get(1); rd_reg = regname; if(wr_reg==rd_reg) wait(wr_reg=="WRITE_DONE"); . . rd_key.put(1); rd_reg= READ_DONE; endtask If i do this, the problem is solved unless and until there is a lock condition that both read and write to the same register get the read and write key at the same time. In this situation, both the tasks wait for the WRITE_DONE and READ_DONE indefinitely and it is a lock condition. To avoid this, i decided to give priority to read in such a condition by using flags wr_flag and rd_flag. automatic task write_reg(regname,value); wr_key.get(1); wr_reg = regname; if(wr_reg==rd_reg)begin wr_flag=1; wait(rd_reg=="READ_DONE"); wr_flag=0; end . . wr_key.put(1); wr_reg = WRITE_DONE; endtask automatic task read_reg(regname,value); rd_key.get(1); rd_reg = regname; if(wr_reg==rd_reg)begin rd_flag=1; if(wr_flag==1)begin $display("both rd and wr are called at same time, hence allow rd to happen"); end else begin wait(wr_reg=="WRITE_DONE"); end rd_flag=1; end . . rd_key.put(1); rd_reg= READ_DONE; endtask This works fine, until and unless the time when rd_reg=READ_DONE; and the time when rd_reg=READ_DONE coincides thus again making the wait in the write task wait(rd_reg=READ_DONE) indefinite. I tried using events, but they have also their own issues. What is the best way to manage timing and avoid race conditions in such situations?
  2. meenu

    pack function

    it works pretty well, but now i face a different situation . what if module test187; import uvm_pkg::*; `include "uvm_macros.svh" class ac extends uvm_object; rand bit[31:0]a; rand bit[121:32]b; rand bit[162:122]c; rand bit[511:163]d; `uvm_object_utils_begin(ac) `uvm_field_int(a,UVM_DEFAULT) `uvm_field_int(b,UVM_DEFAULT) `uvm_field_int(c,UVM_DEFAULT) `uvm_field_int(d,UVM_DEFAULT) `uvm_object_utils_end function new (string name=""); super.new(name); endfunction endclass class bc extends uvm_object; rand bit[511:0]field; `uvm_object_utils(bc) function new (string name=""); super.new(name); endfunction endclass initial begin ac ma = new; bc mb = new; bit d[]; ma.pack(d); $display({>>{d}}); end endmodule Am assigning variable a of class ac with the value {16'h00,8'h5,8'h5} via a task. When i pack, the value am expecting is byte 0 = 0 byte 1 = 5 byte 2 = 0 byte 3 = 5 byte 4 = 0 byte 5 = 0 byte 6 =0 byte 7= 0 all bytes are packed properly, except for the first eight bytes which are packed in reverse order : byte 0 = 0 byte 1 = 0 byte 2 = 0 byte 3 = 0 byte 4 = 0 byte 5 = 5 byte 6 =0 byte 7=5 byte 8=.. . . . byte 63=.. why does this happen?
  3. I have a package and inside the package there is a task . There is an env abc whose handle abc_env is created in my_env and the connections are done in my_env. I would like to use a handle of abc abc_env2 in the task inside my package but assign the properties of abc_env1 to it. How can i assign the environment's handle ( abc_env1) to abc_env2 in my_env file? file 1 package xyz . . task pqr() abc abc_env2; .............. endtask endpackage file 2 class my_env extends uvm_env abc abc_env1; void build function abc_env1 = abc::type_id::create("abc_env1",this); endfunction . . . . . endclass
  4. This is to know whether there is an easier method to do this. There is a packet class A { rand int a; rand int b; rand int c; rand int d; rand int e; rand int f; constraint a_c{b==0->a==0;} . . . . . } I have a task which randomizes A and does some operation on its members task operate_on_A(); A obj_a; assert(obj_a.randomize() with a==10;b==3;c==9;} // few values would be fixed, few random endtask From a test, i would like to call this task d,e and f get random values as of now. i would like to control from the test whether d,e,f would get random values or fixed values passed from the test when calling the task. If am passing fixed values, it should get the fixed values, else it should be randomized. How can this be done in a generic manner and what is the best possible way in uvm ?
  5. meenu

    pack function

    Hi uwes This packs into bits. If i would like to pack them into bytes, what should i use ?
  6. pack function in UVM I have a class class A extends uvm_sequence_item; ... rand bit[3:0]a; rand bit[121:0]b; rand bit[162:122]c; rand bit[511:163]d; ... endclass I have another class class B extends uvm_sequence_item; .... rand bit[511:0]field; ... endclass I would like to assign to field the packed version of all the fields of class A. ie. B b1; A a1; b1 = pack(all fields of a1); How can i use the uvm pack function for this?? Need immediate help
  7. Hi In a register sequence i would like to use data of type uvm_reg_data_t where the value of data should be random. uvm_reg_data_t data; size = rg.get_n_bits(); data[size-1:0] = $random; What should be the type of the variable size? Should it be a parameter or define? I would like the value of size to change according to the width of the register. So the width of data should change according to the width of the register. What is the best way to do this?
  8. I have created a second register block which consists of registers of widths 32,64,128,256 and 2048. 1)After the proper integration, i get an error that the UVM_REG_DATA_WIDTH should be 2048 or higher.I set it to 2048 and i do not get the error anymore. 2)I m using the cadence AXI UVC. When i do a write sm.sf.ABA.write(status,data) where data is a 32bit value FFFFF07, the adapter reg2axi gets the burst, but i get an error that the strobe value F is invalid. I have set the strobe as F so that all 4 bytes of data get written. These same settings in the adapter function works for the previous register model. The new register model also has an address width and data width of 32. The burst is ignored since the strobe value is invalid and write does not happen. 3)The monitor receives a 32bit read burst instead of the write, though i perform a write and though the address of the ABA register is 07, it reads from address 7B80. If i perform a read after write, the write burst is ignored because of the invalid strobe, and the monitor receives two read bursts instead of a write followed by a read and both are different addresses. The first one being 7B80 and the second one of a lower address. Any idea on what is happening?
  9. Okie that makes sense to me now. 1) Other than introducing a delay between the write_reg and read_reg, is there any other method to allow the write to complete before the read. I do not think there is any ordering possible between write and read operation without the delay introduction. 2)Just like a 64bit data is split into two 32bit bursts by the reg model itself, is this abstraction extended to 128bit, 256 bit or 512 bit registers as well. I mean to ask is it possible to write to a 128bit register with a data bus of width 32bits via a register model using the same adapter? For eg: is a 128 bit data intended to be written into a 128bit register split into 4 bursts by the model internally?
  10. Hi 2) gets solved, the updation takes some time and introducing a delay before the sampling point after the trigger solves the problem Thanks !
  11. Hi Janick 1) In order to ensure that read happens only after write completes, I provided a delay between issuing the write and read task calls. And now the monitor sees WR32, WR32, RD32, RD32 and the same is sent to the predictor. There is no collission error. But what does collision error actually imply? Thanks for the fix. 2)Either read or write, i send the data to the predictor from my monitor. But when the direction is read, i trigger an event ->read_done. After the read task call, i wait for the event @read_done, and try to get the data via reg.get(); ,but the data is always zero. In case of 32bit read operations, the data obtained via reg.get() is proper. Does not this imply that the predictor does not update the register model properly in case of 64bit operations?
  12. I do a write first followed by a read. So my monitor sees and reports WR32,RD32,WR32 and R32.
  13. Two 32bit transactions is what it returns. In that case a collision each is detected for both read and write.
  14. Hi Janick I did not exactly get what you said. I can understand that it performs the two burst operation when it reads/ writes a 64 bit register over a 32bit bus. How is it possible to perform two individual operations on the 64bit register? For eg: If i would like to read the value from a 64bit register AFE written with data =64'hFFFFF_FFFF_FFFF_F000 . The start address of AFE being 24. I issue a read: rm.rf.AFE.read(status,data) and the first read burst would contain the data 32'hFFFF_F000 and this is what the monitor would get as the first monitor burst. In my monitor, i assign this to a burst of type axi master burst and send it to the predictor. The address of the first burst would be 24. The second read burst contains the data 32'hFFFF_FFFF and the monitor receives it and assigns it to the master burst's data which is sent to the predictor. This time the address would be 28 (24+4). Probably when it sees two addresses for the same register AFE, it reports a collision detection. What is the solution to this?
  15. Hi I have a register model which has registers of width 32 and 64. The data width and address width are both 32 of the AXI interface. I m using a predictor to update the register model with the current state of the registers of the DUT. When i make an attempt to write to a 64bit register, the data is automatically sent as two bursts of single transfers. ( Is this the register model internal working?) I have set length =1 ( single transfer) and size =WORD(32bits) Read also happens in two bursts. I have implemented a monitor which monitors the transactions. It assigns the attributes of the monitor burst to the master burst and sends it to the predictor. It works for 32 bit registers. But when i try to write to/read from a 64 bit register, I get an error from the predictor "[REG_PREDICT_COLLISION] Collision detected for register rm.AWE where rm is the register model and AWE - 64 bit register Has anyone faced this error before? What is solution to this?