File operation in uvm

Hi,

I have created UVM monitor. I am trying to extract the data and write it into a file but the problem is that the file does not get created. It should get created in the same folder in which i am creating the monitor.

Here is the code:

task run_phase(uvm_phase phase);
      forever begin
          @(posedge vif.clk)
          begin   
             trans.valid_out <= vif.dut_clk.valid_out;
               // if(vif.vip_clk.valid_out == 1) begin
                fd = $fopen("data_txt", "w"); 
                $fwrite(fd, "%b", trans.valid_out);  
                $display("valid_out=%d", trans.valid_out);
                trans.ciphertext[0] <= vif.dut_clk.ciphertext[0];
                $display("ciphertext=%h", trans.ciphertext[0]);
               //end
             end
          end  
   endtask

The “data_txt” file will be created in the folder in which you run your simulation, which may be different from where the monitor file is located.

In reply to shankar_logic:

Several things to consider:

  • You open the file inside the forever loop. This will continuously open a file with the same name at each clock. This will probably cause issues.
  • You never close the file, which may also cause issues.

I have seen the folder but there is no file with this name data_txt.

Ok but if i will use $writememb or $writememh then will it work

In reply to shankar_logic:

There are a few weaknesses in your code:
(1) you should never use $display in your UVM code. Always employ the UVM reporting macros like `uvm_info etc.
(2) Writing in a file from your UVM code you should also use the uvm_action from reporting for writing to a file (UVM_LOG)
(3) If you want to write to a file you should open the file at the beginning of your simulation.
Never open the file somewhere in a task. This is legal but it is bad coding practice.

In reply to shankar_logic:

I was trying your code with the $fopen in the run_phase and it is creating the file data_txt.
Where are you creating an object of your transaction trans?

I am creating the object in the sequence class.

In reply to shankar_logic:
OK. But coming back to your code. Calling $fopen(“data_txt”, “w”); in each loop cycle creates always a new file. at the end of the current cycle you have exactly 1 entry. You lost all the other ones.
Is this the behavior you want to have?

Sir i have made changes and moved the $fopen system task outside the loop. But still the file is not generated.

virtual task run_phase(uvm_phase phase);
`uvm_info(“INFO”,“Starting UVM monitor run_phase”, UVM_NONE);
fd = $fopen(“data_out.txt”, “w”);
forever begin
@(posedge vif.clk)
begin
trans.valid_out <= vif.vip_clk.valid_out;
if(vif.vip_clk.valid_out == 1) begin
$fwrite(fd, “%b”, trans.valid_out);
$display(“valid_out=%d”, trans.valid_out);
trans.ciphertext[0] <= vif.vip_clk.ciphertext[0];
$display(“ciphertext=%h”, trans.ciphertext[0]);
end
end
end
endtask

Thanks for the help and finally the file got generated but i am not able to write the data into the file. I am using $write system task to write the data into the file.

virtual task get_and_drive(uvm_phase phase);
file = $fopen(“data_driver.txt”);
forever begin
phase.drop_objection(this);
seq_item_port.get_next_item(req);
phase.raise_objection(this);
$cast(rsp, req.clone());
rsp.set_id_info(req);
drive_transfer(rsp);
seq_item_port.item_done();
end
endtask

virtual task drive_transfer(encrypt_seq_item trans);
begin
@(posedge vif.clk) begin
$display(“i am here”);
vif.vip_clk.key <= trans.key;
vif.vip_clk.data <= trans.data;
$write(file, “trans.data”);
vif.vip_clk.valid_in <= 1;

        trans.valid_out <= vif.vip_clk.valid_out;
        
        $display("vif.vip_clk.data = %h", vif.vip_clk.data[0]);
        $display("vif.vip_clk.key = %h", vif.vip_clk.key[0]);
        $display("trans.valid_out= %d", trans.valid_out);
     end      
   end   
      
      @(posedge vif.clk) begin
        $display("vif.vip_clk.valid_in = %d",vif.vip_clk.valid_in);
        vif.vip_clk.valid_in <= 0;
     end
endtask

In reply to shankar_logic:

HAving a deeper look to your code I found a few weaknesses:

(1) It seems you are using a clocking block named vip_clk. Then you have to synchronize your code woth the clocking block instead of the clk signal of the virtual interface.
(2) You should use blocking assignments in your code.

Here is my code example which works for me.

task run_phase(uvm_phase phase);
  apb_seq_item trans;
  apb_seq_item trans_clone;
  int fd;

  `uvm_info(get_type_name(),"run_phase",UVM_MEDIUM)
  trans = apb_seq_item::type_id::create("trans");
  fd = $fopen("data_txt", "w");
  forever begin
    @(negedge vif.pclk)
    $fwrite(fd, "%d\n", fd);
 // insert the monitor protocol here
    $cast(trans_clone, trans.clone());
    `uvm_info(get_type_name(), {"write trans to ap \n", trans.sprint()}, UVM_HIGH)
    ap.write(trans_clone);
  end
endtask : run_phase