Pipeline.multi constructor

Pipeline.multi(
  1. List<Logic> _clks,
  2. {List<List<Conditional> Function(PipelineStageInfo p)> stages = const [],
  3. List<Logic?>? stalls,
  4. List<Logic> signals = const [],
  5. Map<Logic, Const> resetValues = const {},
  6. Logic? reset}
)

Constructs a Pipeline with multiple triggers on any of _clks.

Implementation

Pipeline.multi(this._clks,
    {List<List<Conditional> Function(PipelineStageInfo p)> stages = const [],
    List<Logic?>? stalls,
    List<Logic> signals = const [],
    Map<Logic, Const> resetValues = const {},
    this.reset}) {
  _stages = stages.map(_PipeStage.new).toList();
  _stages.add(_PipeStage((p) => [])); // output stage

  _resetValues = Map.from(resetValues);

  _setStalls(stalls);

  signals.forEach(_add);

  for (var stageIndex = 0; stageIndex < stageCount; stageIndex++) {
    Combinational.ssa((ssa) {
      // keep track of the previously registered logics:
      final prevRegisteredLogics = _registeredLogics.toSet();

      // build the conditionals first so that we populate _registeredLogics
      final stageConditionals = _stages[stageIndex].operation(
        PipelineStageInfo._(this, stageIndex, ssa),
      );

      // if any new logics were registered, add some extra assignments
      // to make up the gap since it didn't get included in prior generations
      for (final l in _registeredLogics) {
        if (!prevRegisteredLogics.contains(l)) {
          for (var i = 0; i < stageIndex; i++) {
            // make sure to hook up in-to-out through main for .get's
            get(l, i) <= _i(l, i);
            _o(l, i) <= get(l, i);
          }
        }
      }

      return [
        for (final l in _registeredLogics)
          ssa(get(l, stageIndex)) < _i(l, stageIndex),
        ...stageConditionals,
      ];
    }, name: 'comb_stage$stageIndex');

    // do output connections as assignments so they can be collapsed
    for (final l in _registeredLogics) {
      _o(l, stageIndex) <= get(l, stageIndex);
    }
  }

  _constructionComplete = true;
}