Unions
In Neo, a union
(commonly known as a tagged union or sum type) enables a logic value to contain different data types. The union contains a tag, which functions like an enum where each variant is associated with a LogicType
representing one of the data types. The tag is checked via a match expression before accessing the data, which ensures the data on the wire is always interpreted as the correct type. They can also be parameterized.
Definition
Unions contain a list of Variants, each optionally containing a Logic Type defining the data value.
union MyUnion {
A(Bits(32)), // This variant must be constructed with a data value of Bits(32)
B, // This variant does not have a data value
}
union MyParameterizedUnion(t: LogicType) {
A(Bits(32)),
B(t),
}
Use
For unparameterized unions, the name becomes a LogicType
value and can be instantiated directly. For parameterized unions, the name is a function reference to be called with values for the parameters.
logic val(0): MyUnion;
logic parameterized_val(0): MyParameterizedUnion(Int(32));
To construct a variant of a union, the union's LogicType
value contains methods for each variant. For variants with data, the method requires an argument of the variant's specified LogicType
, and that value's timing will apply to the instance of the union. For variants without data, the method takes no arguments and the instantiated value will be a constant.
// some_data will have to be Bits(32) and have timing 0
assign val = MyUnion.A(some_data);
// Since the B variant has no data, no argument is required and there is no timing consideration
assign val = MyUnion.B();
// The name of the union can be inferred in assignments, which is particularly useful with parameterized unions
assign parameterized_val = .B(some_other_data);
To read the value of a union, a match expression is used:
match val {
A(x) => {
// x is a Bits(32) and has the same timing as val
}
B => {
// No data value is associated with B
}
}
A match expresion has to be used as it enforces checking the variant before accessing the data, ensuring the data is always interpreted as the correct type.