Pipeline.multi constructor
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;
}