rohd icon indicating copy to clipboard operation
rohd copied to clipboard

Pipeline must provide access to inputs of a given stage.

Open kimmeljo opened this issue 2 years ago • 6 comments

Describe the bug

The Pipeline abstraction only provides an API to get the combinational version of a pipeline signal in a given stage. Hence, if you want to do something like:

  • Start with the input flop of a particular signal in a particular stage
  • Use this input in some combinational logic in the given stage
  • Use the output of this combinational logic to drive the output flop of that signal in the given stage

You end up with a combinational loop using the .get(signal, stageindex) API.

Looking at the current implementation, I do not see another way to accomplish the above. An enhancement would be to provide a new API with direct access to the inputs of the given stage (see below for sample implementation).

To Reproduce

Pipeline dbgPipeline = Pipeline(_clk, reset: _reset, ], stages: [ (p) => [ p.get(mysignal) < 0, ], (p) => [ p.get(mysignal) < mycombsignal, ], ]

mycombsignal <= dbgPipeline.get(mysignal, 1) | 0x1;

Expected behavior

One should be able to use a signal in any stage of the pipeline to derive the signal's value in the next pipeline stage combinationally.

Actual behavior

There is a ROHD exception at runtime because of a combinational loop.

Additional: Dart SDK info

No response

Additional: pubspec.yaml

No response

Additional: Context

Sample implementation used as a workaround:

Logic getInput(Logic logic, [int? stageIndex]) { stageIndex ??= _stages.length - 1;

final stageLogic = _stages[stageIndex].input[logic]!;
return stageLogic;

}

kimmeljo avatar Oct 19 '23 22:10 kimmeljo

A couple things come to mind:

  • What should the "input" to a stage be? The output of the prior flop? The output after any stalling has been applied? I think probably the latter?
  • Can this be worked around by assigning in the first line of a pipeline stage to an intermediate variable? Is this worth a separate API, if so?

mkorbel1 avatar Oct 23 '23 17:10 mkorbel1

I'd define the input to stage i as the value of the flop that sits between stages (i-1) and i. How would stalling affect this value? Wouldn't a stall only affect the next cycle's value (i.e., the output, not the input as defined above)?

I can't remember if I tried your suggestion from bullet #2 but it seems like it would still be a combinational loop regardless? Just a more indirect one (combpipelinevalue -> tempsignal -> othertemsignal -> combpipelinevalue)

kimmeljo avatar Oct 23 '23 19:10 kimmeljo

Yes, you're right about the stalling, I was misremembering.

You should not hit a combinational loop, it's sort of like forwarding between pipe stages right? You can just tmpSignal < p.get(x) and use tmpSignal wherever it would be legal to.

mkorbel1 avatar Oct 23 '23 21:10 mkorbel1

I think that's what I tried? The problem is:

tmpSignal < p.get(x, i) ... p.get(x,i) < tmpSignal

I.e., I want to use the input value of the flop between stages (i-1) and i to derive some value that will then drive the flop between stages i and (i+1).

Doing the above results in a combinational loop exception in ROHD.

kimmeljo avatar Oct 25 '23 16:10 kimmeljo

Sorry, I mean not getting it from another pipe stage since that would get the output of that stage.

For example, in stage N:

tmpSignal < p.get(x),
p.get(x) < ... some other stuff ...

Then in stage M:

p.get(y) < tmpSignal

mkorbel1 avatar Oct 25 '23 17:10 mkorbel1

So relative to your description above, the problem in the particular case of this issue is that N == M. Hence the combinational loop if doing the above.

kimmeljo avatar Oct 27 '23 18:10 kimmeljo