Pipeline constructor Null safety

Pipeline(
  1. Logic clk,
  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 simple pipeline, separating arbitrary combinational logic by flop stages.

Each stage in the list stages is a function whose sole parameter is a PipelineStageInfo object and which returns a List of Conditional objects. Each stage can be thought of as being the contents of a Combinational block. Use the PipelineStageInfo object to grab signals for a given pipe stage. Flops are positive edge triggered based on clk.

Signals to be pipelined can optionally be specified in the signals list. Any signal referenced in a stage via the PipelineStageInfo will automatically be included in the entire pipeline.

If a reset signal is provided, then it will be consumed as an active-high reset for every signal through the pipeline. The default reset value is 0 for all signals, but that can be overridden by setting resetValues to the desired value. The values specified in resetValues should be a type acceptable to Logic's put function.

Each stage can be stalled independently using stalls, where every index of stalls corresponds to the index of the stage to be stalled. When a stage's stall is asserted, the output of that stage will not change.

Implementation

Pipeline(this.clk,
    {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

  if (_numStages == 0) {
    return;
  }

  _resetValues = Map.from(resetValues);

  _setStalls(stalls);

  signals.forEach(_add);

  final combMiddles = <List<Conditional>>[];
  for (var i = 0; i < _numStages; i++) {
    final combMiddle = _stages[i].operation(PipelineStageInfo._(this, i));
    combMiddles.add(combMiddle);
  }

  for (var stageIndex = 0; stageIndex < _numStages; stageIndex++) {
    Combinational([
      for (Logic l in _registeredLogics)
        get(l, stageIndex) < _i(l, stageIndex),
      ...combMiddles[stageIndex],
      for (Logic l in _registeredLogics)
        _o(l, stageIndex) < get(l, stageIndex),
    ], name: 'comb_stage$stageIndex');
  }
}