cases function

Logic cases(
  1. Logic expression,
  2. Map conditions,
  3. {int? width,
  4. ConditionalType conditionalType = ConditionalType.none,
  5. dynamic defaultValue}
)

Shorthand for a Case inside a Conditional block.

It is used to assign a signal based on a condition with multiple cases to consider. For e.g., this can be used instead of a nested mux.

The result is of type Logic and it is determined by conditionaly matching the expression with the values of each item in conditions. If width of the input is not provided, then the width of the result is inferred from the width of the entries.

Implementation

Logic cases(Logic expression, Map<dynamic, dynamic> conditions,
    {int? width,
    ConditionalType conditionalType = ConditionalType.none,
    dynamic defaultValue}) {
  for (final conditionValue in [
    ...conditions.values,
    if (defaultValue != null) defaultValue
  ]) {
    int? inferredWidth;

    if (conditionValue is Logic) {
      inferredWidth = conditionValue.width;
    } else if (conditionValue is LogicValue) {
      inferredWidth = conditionValue.width;
    }

    if (width != inferredWidth && width != null && inferredWidth != null) {
      throw SignalWidthMismatchException.forDynamic(
          conditionValue, width, inferredWidth);
    }

    width ??= inferredWidth;
  }

  if (width == null) {
    throw SignalWidthMismatchException.forNull(conditions);
  }

  for (final condition in conditions.entries) {
    if (condition.key is Logic) {
      if (expression.width != (condition.key as Logic).width) {
        throw SignalWidthMismatchException.forDynamic(
            condition.key, expression.width, (condition.key as Logic).width);
      }
    }

    if (condition.key is LogicValue) {
      if (expression.width != (condition.key as LogicValue).width) {
        throw SignalWidthMismatchException.forDynamic(condition.key,
            expression.width, (condition.key as LogicValue).width);
      }
    }
  }

  final result = Logic(name: 'result', width: width, naming: Naming.mergeable);

  Combinational([
    Case(
        expression,
        [
          for (final condition in conditions.entries)
            CaseItem(
                condition.key is Logic
                    ? condition.key as Logic
                    : Const(condition.key, width: expression.width),
                [result < condition.value])
        ],
        conditionalType: conditionalType,
        defaultItem: defaultValue != null ? [result < defaultValue] : null)
  ]);

  return result;
}