Notes about our handling of vl-patternkeys.
The keys in assignment patterns can be expressions (which should
resolve to array indexes, for array patterns), structure member names, type
names, or the special keyword
'{ 0: a, 1: b, 2: c, default: 0 } // assign to some array indices, default others... '{ foo: 3, bar: 5 } // assign to struct members by name (maybe) '{ integer: 5, opcode_t: 7 } // assign to struct members by type (maybe)
Simple names are particularly ambiguous here. For instance, a name like
int arr [3:0]; parameter place = 0; assign arr = '{place: 3, default: 0 };
or (2) a structure member name, as in:
typedef struct { int place; int value; } slot_t; slot_t s = '{ place: 3, value: 4 };
or (3) the name of some type, as in:
typedef logic [3:0] place; typedef struct { place src; place dest; int data; } msg_t; msg_t m = '{ place: 0, data: 0 };
This ambiguity is problematic in early parts of annotate, such as
shadowcheck, where we want to check that, e.g., wires are used declared
before they are used. Here, because of type parameters, we might not be able
to tell the names of a structure's members until elaboration time. For
example, suppose there is no type named
mytype_t foo = '{ place: 0, ... }
In this case, we won't know whether
Rather than further intertwine shadowcheck and elaborate, our approach is to avoid this ambiguity by require that all simple names used in assignment pattern keys must be either the names of types or structure members. Although NCVerilog doesn't impose this restriction, it appears that our behavior matches that of VCS. For instance, when we submit the following to VCS J-2014.12-SP3-1:
module foo1 ; int arr [3:0]; parameter place = 0; assign arr = '{place: 3, default: 0 }; endmodule
we find that it reports the following error:
Error-[IAP] Illegal assignment pattern test.sv, 5 foo1, "place:3" Assignment pattern is illegal due to: Assignment Pattern with named fields cannot be assigned to a non-structure target
Upon parsing a vl-patternkey there are four possibilities:
To reduce insanity we are going to assume that any such
At parse time, after dealing with
On the other hand, if we get an expression which is a simple name, then we will immediately convert it to a structmem instead of an expr vl-patternkey. Note that we don't yet know whether it's a structure name or a type name; structmems will need to be further disambiguated before we're sure they aren't types.
During shadowcheck, we have enough information to tell whether a structmem is actually a type. We can then check for tricky shadowing as per usual. Type disambiguation can then make the final conversion of structmems to types as necessary.
Later on, in svex conversion: if we encounter a struct pattern, we should
probably also explicitly check that any type keys such as