There are a few things that need to be answered though:
Time References
Should you be able to reference a member of a struct via e.g. p[t].red, versus the time reference always being at the end (p.red[t])? It kind of makes sense.
But, regardless of the answer, the same logic does not apply to module instantiations - if modinstance is an instantiated module, modinstance[t].foo is not valid.
Also, having multiple doesn't make sense, so p[t].red[t] is also invalid.
Struct Literals
Structs could very conceivably be the result of an expression. For example:
p[t] = pixel { red = 5, green = 5, blue = 5 };
or even:
p[t] = pixel { red = x[t-1], green = 255 - x[t-1], blue = 5 };
Maybe this implies that struct literals can be used in operations? It's unclear what operations you could do on a struct literal, but certainly you could extract a field:
p[t] = pixel { red = x[t-1], green = 255 - x[t-1], blue = 5 }.red + 1;
or maybe you shouldn't be able to, since this is trivially wasteful. But, we have to consider how this interacts with enums in #10 - those could definitely be used in operations. Maybe.
This creates a sort of dual syntax - where x.red is valid if x is a struct literal, but it is not valid if x is a struct variable. Which implies that we should allow p[t].red, so that x.red is generally legal as long as x contains the time reference.
ABI
Should structs be passed between modules as a big bitvector, or as individual members?
Individual members plays a bit nicer with VCD dumps. But, big bitvectors (I think) will play a bit nicer with external interfaces - which means maybe we should use individual members, and disallow structs in extern modules (or in "top" modules).
For the ABI, it makes the most sense to me to pass each field as an individual variable. This also makes removing unnecessary timestamps for individual fields much easier
Structs would be nice, then you can do things like:
There are a few things that need to be answered though:
Time References
Should you be able to reference a member of a struct via e.g.
p[t].red
, versus the time reference always being at the end (p.red[t]
)? It kind of makes sense.But, regardless of the answer, the same logic does not apply to module instantiations - if
modinstance
is an instantiated module,modinstance[t].foo
is not valid.Also, having multiple doesn't make sense, so
p[t].red[t]
is also invalid.Struct Literals
Structs could very conceivably be the result of an expression. For example:
or even:
Maybe this implies that struct literals can be used in operations? It's unclear what operations you could do on a struct literal, but certainly you could extract a field:
or maybe you shouldn't be able to, since this is trivially wasteful. But, we have to consider how this interacts with enums in #10 - those could definitely be used in operations. Maybe.
This creates a sort of dual syntax - where
x.red
is valid ifx
is a struct literal, but it is not valid ifx
is a struct variable. Which implies that we should allowp[t].red
, so thatx.red
is generally legal as long asx
contains the time reference.ABI
Should structs be passed between modules as a big bitvector, or as individual members?
Individual members plays a bit nicer with VCD dumps. But, big bitvectors (I think) will play a bit nicer with external interfaces - which means maybe we should use individual members, and disallow structs in
extern
modules (or in "top" modules).