Transition bins for write and read to same address

currently my code is like this

covergroup mesh_cmd_cg (string inst_name, int min, int max) with function sample(mesh_ior_cmd_transaction cmd_txn);

   cp_cmd_mt : coverpoint cmd_txn.tx_type {
      bins WRITE         = {WRITE};
      bins READ          = {READ};
   }

   cp_cl_addr : coverpoint cmd_txn.cl_addr {
      bins MIN     = {min};
      bins MID[4]  = {[(min+'h1):(max-'h1)]};
      bins MAX     = {max};
    }

   cp_trans_write_read_write : coverpoint cmd_txn.tx_type iff(cmd_txn.cl_addr == 'h100 ) {

      bins w_r_w = (WRITE=>READ=>WRITE);
    }
endgroup

currently I’m checking trasnition bin by manually putting an address but is there any way to make it generic like for any value between min to max if it detects the sequence of write->read->write with same address it should hit. Is there any way to call whatever value that is sampled in cp_cl_addr in cp_trans_write_read_write

In reply to Raja VA:

This is difficult to do using a covergroup. The way you have written it for a fixed address does not require consecutive operations. You need to clarify if that is what you wanted.

If you need consecutive operations to the same address, you would need to create another signal that represents stability in the address between operations.

If you don’t need consecutive operations (i.e WRITE:'h100=>WRITE:'h200=>READ:'h100=> WRITE:'h100), that would be much more difficult to do with a covergroup, but easier with a cover property directive.

In reply to dave_59:
for now

cp_trans_write_read_write : coverpoint cmd_txn.tx_type {

  bins w_r_w = (WRITE=>READ=>WRITE);
}

for now this is hitting everytime a write->read->write sequence is detected regardless of address but I want it to hit only if it detects same address so I need to establish some relation between cl_addr and tx_type which I’m facing problem with

In reply to Raja VA:
You need to create a stable address bit and cross with your W/R/W transition.

module top;
   
   typedef enum {READ,WRITE} tx_e;
   tx_e      tx_type;
   bit [7:0] cl_addr;
   bit [7:0] prev_addr[3];
   bit       stable_addr;
   
   covergroup mesh_cmd_cg;
      cp_cmd_mt : coverpoint tx_type {
	 bins WRITE         = {WRITE};
	 bins READ          = {READ};
      }
      cp_cl_addr : coverpoint cl_addr {
	 bins MIN     = {0};
	 bins MID[4]  = {[1:254]};
	 bins MAX     = {255};
      }
      
      cp_trans_write_read_write : coverpoint tx_type {
	 
	 bins w_r_w = (WRITE=>READ=>WRITE);
      }
      cp_stable_addr: coverpoint stable_addr {
         bins sa = {1};
      }
      cr_w_r_w_rep: cross cp_trans_write_read_write, cp_stable_addr;
      
   endgroup : mesh_cmd_cg
     
   mesh_cmd_cg cg  = new;
   
   function void sample(tx_e tx, bit [7:0] ad);
      tx_type 	  = tx;
      cl_addr 	  = ad;
      prev_addr   = {ad, prev_addr[0:1]};
      stable_addr = prev_addr[0] == prev_addr[1] &&
	            prev_addr[1]  == prev_addr[2];
      cg.sample();
   endfunction : sample
   initial begin
      sample(WRITE,1);
      sample(READ ,1);
      sample(WRITE,2);
      
      sample(WRITE,3);
      sample(READ ,3);
      sample(WRITE,3);
      
   end
   	
endmodule : top

In reply to dave_59:

does the size of prev_addr depend on cl_addr size? my cl_addr size is 43 bit.

In reply to Raja VA:

More precise not array size, but width of array element equal to cl_addr.


  //prev_addr is used to keep 3 conductive address. (Address width will upto you)
  //When all 3 index of array has same address, stable_address become 1.
  //And same address set in array due to WRITE -> READ -> WRITE, cross will be covered
  bit [42:0] cl_addr;.       //43 bit
  bit [42:0] prev_addr [3];. //43 bit, 43 bit, 43 bit

Thanks!