of static method
Constructs a LogicValue from val
which could be of a variety of types.
Supported types include String, bool, int, BigInt, LogicValue, and Iterable<LogicValue>.
If fill
is set, then all bits of the returned value will be set to
val
. If the val
is not representable as a single bit of information,
then setting fill
will throw an Exception.
If the width
can be inferred from the type (e.g. String, LogicValue,
Iterable<LogicValue>), then width
does not need to be provided.
If width
is provided and does not match an inferred width, then width
is used.
If a width
cannot be inferred, then it is required, or else it will
throw an Exception.
If val
does not fit in a specified width
, then the returned value will
be truncated.
bools will infer a default width of 1
, but it can be overridden.
Invalid 1-bit val
s will always be fill
ed even if fill
is false
,
but will default to a width of 1 unless width
is specified.
Implementation
static LogicValue of(dynamic val, {bool fill = false, int? width}) {
if (val is int) {
if (width == null) {
throw LogicValueConstructionException(
'`width` must be provided for `int`.');
}
if (fill) {
return LogicValue.filled(
width,
val == 0
? LogicValue.zero
: val == 1
? LogicValue.one
: throw LogicValueConstructionException(
'`int` can only can fill 0 or 1, but saw $val.'));
} else {
return LogicValue.ofInt(val, width);
}
} else if (val is BigInt) {
if (width == null) {
throw LogicValueConstructionException(
'`width` must be provided for `BigInt`.');
}
if (fill) {
return LogicValue.filled(
width,
val == BigInt.zero
? LogicValue.zero
: val == BigInt.one
? LogicValue.one
: throw LogicValueConstructionException(
'`BigInt` can only fill 0 or 1, but saw $val.'));
} else {
return LogicValue.ofBigInt(val, width);
}
} else if (val is bool) {
width ??= 1;
if (fill) {
return LogicValue.filled(width, val ? LogicValue.one : LogicValue.zero);
}
return LogicValue.ofInt(val ? 1 : 0, width);
} else if (val is LogicValue) {
if (fill && val.width != 1) {
throw LogicValueConstructionException(
'Only 1-bit `LogicValue`s can be filled');
}
if (val.width == 1 && (!val.isValid || fill)) {
if (!val.isValid) {
// ignore: parameter_assignments
width ??= 1;
}
if (width == null) {
throw LogicValueConstructionException(
'Filled `LogicValue` $val must have provided a width.');
}
return LogicValue.filled(width, val);
} else {
if (val.width == width || width == null) {
return val;
} else if (width < val.width) {
return val.getRange(0, width);
} else {
return val.zeroExtend(width);
}
}
} else if (val is String) {
if (fill && val.length != 1) {
throw LogicValueConstructionException(
'Only 1-bit values can be filled');
}
if (val.length == 1 && (val == 'x' || val == 'z' || fill)) {
if (val == 'x' || val == 'z') {
// ignore: parameter_assignments
width ??= 1;
}
if (width == null) {
throw LogicValueConstructionException(
'Filled `String` $val must have provided a width.');
}
return LogicValue.filled(width, LogicValue.ofString(val));
} else {
if (val.length == width || width == null) {
return LogicValue.ofString(val);
} else if (width < val.length) {
return LogicValue.ofString(val.substring(0, width));
} else {
return LogicValue.ofString(val).zeroExtend(width);
}
}
} else if (val is Iterable<LogicValue>) {
if (fill && val.length != 1) {
throw LogicValueConstructionException(
'Only 1-bit values can be filled');
}
if (val.length == 1 &&
(val.first == LogicValue.x || val.first == LogicValue.z || fill)) {
if (!val.first.isValid) {
// ignore: parameter_assignments
width ??= 1;
}
if (width == null) {
throw LogicValueConstructionException(
'Filled `Iterable<LogicValue>` $val must have provided a width.');
}
return LogicValue.filled(width, val.first);
} else {
if (val.length == width || width == null) {
return LogicValue.ofIterable(val);
} else if (width < val.length) {
return LogicValue.ofIterable(val).getRange(0, width);
} else {
return LogicValue.ofIterable(val).zeroExtend(width);
}
}
} else if (val == null) {
throw LogicValueConstructionException('Cannot construct from `null`.');
} else {
throw UnsupportedTypeException(val,
const [LogicValue, int, BigInt, bool, String, Iterable<LogicValue>]);
}
}