Why can't parameter class typedefs be used in variable declarations?

This parameterized class can use typedefs defined in one of its parameter classes via a typedef, but cannot use the parameter class typedef directly to declare a member variable.

class m0s8xyz_env #(type P, type V) extends ovm_component;

  // Define type using parameter class typedef.
  typedef V::bus_loopback_vif_t v_bus_loopback_vif_t;

  // Member variable declaration using local typedef works
  v_bus_loopback_vif_t bus_loopback_vif;

  // Member variable declaration using parameter class typedef fails
  //V::bus_loopback_vif_t bus_loopback_direct_vif;

Why does use of a parameter class typedef work in a typedef but fail in a variable declaration?

Steve

Because the compiler needs to know that V::bus_loopback_vif_t is type in order to parse the variable declaration syntax. The parser does not know what kind of statement you are trying to write because it has no idea what kind of identifier bus_loopback_vif_t is. When you use the typedef keyword, the parser knows that the next token must be a type (eventually), and can parse the variable declaration using the local type. You will get an elaboration error if after parametrization, V::bus_loopback_vif_t does not turn out to be a type.

You should be able to use the following to avoid a local typedef:

type(V::bus_loopback_vif_t) bus_loopback_vif;

I see.

Thanks,
Steve

In reply to dave_59:

Just a further comment to generalize this rule:

All type identifiers must be declared as a type before they can be referenced as a type. You can declare an identifier as a type by using a typedef, forward typedef, type parameter, or type() operator.

The examples above V is known as a type because it is declared as a type parameter. Its specific type is unknown until after elaboration.
The result of type(V::bus_loopback_vif_t) is always a type, regardless of whether bus_loopback_vif_t is actually a type, variable or parameter.

I haven’t been able to get the type() operator to work in a declaration with a scope operator.

When I try

type(V::bus_loopback_vif) bus_loopback_vif;

I get

** Error: test.sv(88): Type-reference expression may not have hierarchical refs. or elements of dynamic types.

This is not a blocking issue since the typedef approach solve the problem and now makes sense, but it would be nice to understand it.

In reply to Steve Roe:

This small example worked for me.

class env #(type P, type V);

  type(V::bus_loopback_vif_t) bus_loopback_direct_vif;

endclass

module top;
class B;
   typedef int bus_loopback_vif_t;
endclass // B
   env#(int,B) e;
endmodule

Can show a small example that fails for you.

In reply to dave_59:

I think I’m running the same example

// Test type operator

class env #(type P, type V);
  type(V::bus_loopback_vif_t) bus_loopback_direct_vif;
endclass

module top;
class B;
  typedef int bus_loopback_vif_t;
endclass
  env#(int, B) e;
endmodule

I get these messages

QuestaSim vlog 10.2a Compiler 2013.03 Mar 15 2013
– Compiling package test_sv_unit
** Error: test.sv(4): Type-reference expression may not have hierarchical refs. or elements of dynamic types.
– Compiling module top
** Error: test.sv(4): Type-reference expression may not have hierarchical refs. or elements of dynamic types.

Maybe it’s a compiler dependency?

In reply to Steve Roe:

It turns out I was using a slightly different example that still had your local typedef in it, so the type() operator would always work. Once I removed the typedef, the version of Questa I was using caught the error at a later stage of elaboration after vlog. I thought this would work, but I’ll have to investigate it further.