Counter constructor

Counter(
  1. List<SumInterface> interfaces, {
  2. required Logic clk,
  3. required Logic reset,
  4. Logic? restart,
  5. dynamic resetValue = 0,
  6. dynamic maxValue,
  7. dynamic minValue = 0,
  8. int? width,
  9. bool saturates = false,
  10. String name = 'counter',
})

Creates a counter that increments according to the provided interfaces.

The width can be either explicitly provided or inferred from other values such as a maxValue, minValue, or resetValue that contain width information (e.g. a LogicValue), or by making it large enough to fit maxValue, or by inspecting widths of interfaces. There must be enough information provided to determine the width.

If no maxValue is provided, one will be inferred by the maximum that can fit inside of the width.

The restart input can be used to restart the counter to a new value, but also continue to increment in that same cycle. This is distinct from reset which will reset the counter, holding the count at resetValue.

If saturates is true, then it will saturate at the maxValue and minValue. If false, will wrap around (overflow/underflow) at the maxValue and minValue. The equalsMax, equalsMin, overflowed, and underflowed outputs can be used to determine if the sum is at the maximum, minimum, (would have) overflowed, or (would have) underflowed, respectively.

Implementation

Counter(
  super.interfaces, {
  required Logic clk,
  required Logic reset,
  Logic? restart,
  dynamic resetValue = 0,
  super.maxValue,
  super.minValue = 0,
  super.width,
  super.saturates,
  super.name = 'counter',
}) : super(initialValue: resetValue) {
  clk = addInput('clk', clk);
  reset = addInput('reset', reset);

  if (restart != null) {
    restart = addInput('restart', restart);
  }

  addOutput('count', width: width);

  final sum = Sum(
    interfaces,
    initialValue:
        restart != null ? mux(restart, initialValueLogic, count) : count,
    maxValue: maxValueLogic,
    minValue: minValueLogic,
    width: width,
    saturates: saturates,
  );

  count <=
      flop(
        clk,
        sum.sum,
        reset: reset,
        resetValue: initialValueLogic,
      );

  // need to flop these since value is flopped
  overflowed <= flop(clk, sum.overflowed, reset: reset);
  underflowed <= flop(clk, sum.underflowed, reset: reset);

  equalsMax <= count.eq(maxValueLogic);
  equalsMin <= count.eq(minValueLogic);
}