Vl-usertype
Represents a reference to some user-defined SystemVerilog datatype.
This is a product type, introduced by deftagsum in support of vl-datatype.
Fields
- name — vl-scopeexpr
- Typedef name, like foo_t. May have a package scope, but
should not otherwise be hierarchical.
- res — vl-maybe-datatype
- The resolved type that name refers to. If present, it means
we've already looked up the type and resolved its value. See
below for more notes.
- pdims — vl-dimensionlist
- Packed dimensions for this user type.
- udims — vl-dimensionlist
- Unpacked dimensions for this user type.
- virtual-intfc — booleanp
- Indicates a virtual interface type, which we don't really support.
- intfc-params — vl-maybe-paramargs
- Parameter values -- relevant for the virtual-intfc case
Notes about the res Field
Originally, to deal with user-defined types, we tried to just
substitute definitions for usertypes. However, it turns out that
this isn't correct: e.g.
typedef logic signed [3:0] snib;
snib [3:0] foo1;
is not the same as just
logic signed [3:0] [3:0] foo2;
Here, foo1 is an unsigned array of signed slots, whereas
foo2 is a signed array of unsigned slots. (NCV and VCS also
treat them differently; we believe NCV gets it right with respect
to the spec, whereas VCS seems to do the substitution.)
We then decided we'd just deal with usertypes directly. We
rewrote all our type-manipulating functions to operate on a
datatype and scopestack simultaneously. However, we don't want to
store scopestacks between transformations. So there's a problem
with e.g. type parameters: e.g.
module sub #(type and_t = logic [3:0])
(input and_t a, b, output and_t o);
assign o = a & b;
endmodule
module super ();
typedef logic signed [5:0] my_and_t;
my_and_t a, b;
my_and_t o;
sub #(.and_t(my_and_t)) inst (a, b, o);
endmodule
Here, we want to transform sub, replacing the and_t
parameter with the overridden version my_and_t. But
my_and_t is only defined in super! So we might want to
do something like replacing the and_t type parameter with
typedef my_and_t and_t;, or leaving it as a parameter
#(type and_t = my_and_t). But neither of these work, because
my_and_t isn't defined in the scope of sub.
Our solution is to go back to doing substitution, but instead of
strictly substituting usertype <- definition, we leave the
usertype but add the res field, a vl-maybe-datatype which, if present, means we've resolved this
usertype and its definition is the res.
Subtopics
- Make-vl-usertype
- Basic constructor macro for vl-usertype structures.
- Vl-usertype->virtual-intfc
- Get the virtual-intfc field from a vl-usertype.
- Vl-usertype->intfc-params
- Get the intfc-params field from a vl-usertype.
- Vl-usertype->udims
- Get the udims field from a vl-usertype.
- Vl-usertype->res
- Get the res field from a vl-usertype.
- Vl-usertype->pdims
- Get the pdims field from a vl-usertype.
- Vl-usertype->name
- Get the name field from a vl-usertype.
- Change-vl-usertype
- Modifying constructor for vl-usertype structures.