LHS in non-blocking assignment may not be an automatic variable

,

Hi. I’m trying to write a “drive” task and getting this error in QuestaSim: “LHS in non-blocking assignment may not be an automatic variable”. Firstly at the part that i marked as:“/*****************************/” .
I have tried to create the variable “i” in interface and it did not solved.

Here is the code:

import uvm_pkg::*;
`include "uvm_macros.svh"
`include "FSM_txn.sv"

`ifndef FSM_driver
`define	FSM_driver
class FSM_driver extends uvm_driver#(FSM_txn) ;

....

    task run_phase(uvm_phase phase);
		FSM_txn txn ;
		drive(txn);
	endtask: run_phase
	
	task drive(FSM_txn txn);
		vif.data = 32'b0 ;
		vif.address = 32'b0 ;
			forever begin 
				if (vif.rst == 0 ) begin // drive address	
					//integer i = 31;
					@(posedge vif.clock) begin
						for ( int i=31 ; i>=0 ; i-- ) begin
							 @(posedge vif.clock) vif.address[i]= txn.address[i] ;
							
						end
						
					end
					
					//check condition to drive data 
					if (vif.address_o == 1'b1) begin
						@(posedge vif.clock) begin// drive data
							for (int i=31; i>=0 ; i-- ) begin
								@(posedge vif.clock) begin
								vif.data[i]= t.data[i] ;
								end
							end
						end	
					end
					
					
					#1 // when the second case is satisfied wait along 1 clock cycle
					
					//parity 
					if(vif.data_o == 1) begin 
						bit [7:0] address_byte3 ;
						bit [7:0] address_byte2 ;
						bit [7:0] address_byte1 ;
						bit [7:0] address_byte0 ;
						bit [7:0] data_byte3 ;
						bit [7:0] data_byte2 ;
						bit [7:0] data_byte1 ;
						bit [7:0] data_byte0 ;
						
						bit dummy[16:0];
						
						for( int i=31 ; i>23 ; i--) begin
							address_byte3[i-24] <= vif.address[i];/*****************************/
							data_byte3[i-24] <= vif.data[i] ;
						end
						
						dummy = {^address_byte3,data_byte3} ; // now dummy[16] is parity bit of 3rd bytes (verilog concatenation)				
						@(posedge vif.clock) vif.parity <= dummy [16] ;
						
						
						for(int i=31 ; i>23 ; i--) begin
							address_byte2[i-24] <= vif.address[i-8];
							data_byte2[i-24] <= vif.data[i-8] ;					
						end
						dummy = {^address_byte2,data_byte2} ;
						@(posedge vif.clock) vif.parity <= dummy [16] ;
						
						
						for(int i=31 ; i>23 ; i--) begin
							address_byte1[i-24] <= vif.address[i-16];
							data_byte1[i-24] <= vif.data[i-16] ;					
						end
						dummy = {^address_byte1,data_byte1} ;
						@(posedge vif.clock) vif.parity <= dummy [16] ;
						
						for(int i=31 ; i>23 ; i--) begin
							address_byte0[i-24] <= vif.address[i-24];
							data_byte0[i-24] <= vif.data[i-24] ;					
						end
						dummy = {^address_byte0,data_byte0} ;
						@(posedge vif.clock) vif.parity <= dummy [16] ;
					
					
					
					end
				end else begin // if rst equals to 1 
				#2 
				vif.parity = 0 ;
				vif.data_o = 0 ; 
				vif.address_o = 0  ;
				
				end
			end
	endtask : drive
	
	
endclass 

`endif

In reply to ufukyil:

You can’t use a non-blocking assignment to an automatic variable because there is the possibility that it may not exist when the actual assignment happens.

In this case, you should be using blocking assignments.

In reply to cgales:

In fact you should be using non-blocking assignment to all your vif.signals and blocking assignment to everything else.

I did needed changes, thanks for assistance.
Now i am facing with another problem. Maybe it is related with another topic but I need to find even parity of first, second, third, and fourth bytes of address[31:0] and data [31:0]. Here i was trying to do so for first bytes of data and address :

dummy = {^address_byte3,data_byte3}

In my scenario, the MSB of dummy will be the parity of first bytes however im taking this error message : “Illegal unpacked array concatenation. The number of elements (2) doesn’t match with the type’s width (17).”
Due to i am a newbei, asking you for more detailed explanation. Thanks again.

In reply to ufukyil:

I did needed changes, thanks for assistance.
Now i am facing with another problem. Maybe it is related with another topic but I need to find even parity of first, second, third, and fourth bytes of address[31:0] and data [31:0]. Here i was trying to do so for first bytes of data and address :

dummy = {^address_byte3,data_byte3}

In my scenario, the MSB of dummy will be the parity of first bytes however im taking this error message : “Illegal unpacked array concatenation. The number of elements (2) doesn’t match with the type’s width (17).”
Due to i am a newbei, asking you for more detailed explanation. Thanks again.

I think you need to start with the basics of SV, there are several resources online you can look for packed and unpacked arrays, how and where to declare/assign variables, also the LRM to understand about the different data types SV has in your code I see this

dummy bit [16:0]; //defines an unpacked array of 1-bit elements {dummy[0],..., dummy[16]} 

To which you are assigning only 2 elements (actually you are assigning 1 element of one bit (xor reduction of address_byte3), and another element of 8 bits (data_byte3) )

According to the LRM Section 10.10 Unpacked array concatenation
“The elements thus represented shall be arranged in left-to-right order to form the resulting array. It shall be
an error if the size of the resulting array differs from the number of elements in a fixed-size target
. If the size
exceeds the maximum number of elements of a bounded queue, then elements beyond the upper bound of
the target shall be ignored and a warning shall be issued.”


// Code your testbench here
// or browse Examples
module test();
  bit a [15:0];
  bit [7:0] b = 128;
  bit [31:0] data = 32'h0000_0001;
  initial begin
    $display("a %p", a);
    $display("b %p", b);
    $display("data %p", data);
    $display("{^data, b} %b", {^data, b});   
    //a = {1'b1, 1'b1}; //Error target size 17 and num of elements is 2
    $display("a %p", a);
  end
  
endmodule

// Gives the following output
# KERNEL: ASDB file was created in location /home/runner/dataset.asdb
# KERNEL: a '{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
# KERNEL: b 128
# KERNEL: data 1
# KERNEL: {^data, b} 110000000
# KERNEL: a '{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

Also please read Section 10.10.1 Unpacked array concatenations compared with array assignment patterns to see the differences between a = '{} and a = {}, as it can lead to unexpected results if not used with care IMHO.

HTH,
-R

In reply to rgarcia07:

I didn’t realise that i defined the “dummy” as unpacked array. Thanks for help.