system-veriloguvm

Structure containing dynamic data in non-procedural context for parameterized test class


Below code in SV/UVM is producing VCS compile error shown after the code.

 typedef enum int {
  ABC,
  DEF,
  GHI,
 . . .
 } enum_t

class some_test #(type T=uvm_test) extends T;
 
 `uvm_component_param_utils(some_test#(T))

 bit assoc_array[3][enum_t];


 //bunch of tasks and functions here

 
 task run_phase(uvm_phase phase);
   int index;
  
  //Below wait inside some fork-join and begin-end blocks
  //index calculated
  assoc_array[index].delete(); //Compiler OK here
  assoc_array[index][DEF] = 1; //Compiler OK here
 
  //some more forked threads

  wait(assoc_array[index].exists(ABC) && (assoc_array[index][ABC]==1)); //COMPILER ERROR
 endtask

endclass

Error is :

Error-[DTINPCIL] Dynamic type in non-procedural context
"wait ((this.assoc_array[index].exists(ABC) && (this.assoc_array[index][ABC] == 1))) ;"
  Argument: this.assoc_array[index]
  Structure containing dynamic data and/or used in dynamic arrays may not be 
  used in non-procedural context.

I do not understand why this is non-procedural context. Does it have anything to do with the test being a parameterized test? I am doing such "extends" to achieve multiple inheritance. I saw that in a blog by Tudor Timi titled "Fake it till you make it - Emulating multiple inheritance in System Verilog", though his example achieved something else and was definitely not on a parameterized test.

In some other test package, I have this piece of code as well:

typedef some_test #(some_basic_test) better_test;

Solution

  • I was able to reproduce your VCS compile error with a minimal code example on EDA playground. However, 3 other simulators do not produce compile errors.

    I do not understand the error message. The code uses wait inside a task called from an initial block, which seems like a procedural context to me.

    I also tried on a more recent version of VCS that I have, and I get the same error. You could contact Synopsys for help.

    Here is the code I used:

    module tb;
    
    typedef enum int {
        ABC,
        DEF,
        GHI
    } enum_t;
    
    bit assoc_array[3][enum_t];
    int index;
    
    task runphase;
        assoc_array[index][DEF] = 1;
        wait(assoc_array[index].exists(ABC));
    endtask
    
    initial begin
        runphase();
    end
    endmodule