Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Seq] Pipeline generator #587

Closed
mikeurbach opened this issue Feb 12, 2021 · 7 comments · Fixed by #3203
Closed

[Seq] Pipeline generator #587

mikeurbach opened this issue Feb 12, 2021 · 7 comments · Fixed by #3203
Labels
enhancement New feature or request

Comments

@mikeurbach
Copy link
Contributor

A common pattern seems to be generating an RTL (in the "register-transfer level") pipeline of some depth, most recently brought up here: #585 (comment). This pattern appears in Handshake's lowering of memories for an analogous reason: to delay the control network to match the memory delay. Finally, ESI's buffers are lowered into pipeline stages implemented by an external module implemented in System Verilog.

It would be great if CIRCT could provide some sort of shared utility that these uses could all rely on.

@teqdruid
Copy link
Contributor

teqdruid commented Feb 12, 2021 via email

@mikeurbach
Copy link
Contributor Author

Putting those abstractions into a dialect sounds good to me. Now that I think about it, there is already a pipeline operation in the StaticLogic dialect: https://circt.llvm.org/docs/Dialects/StaticLogic/#staticlogicpipeline-circtstaticlogicpipelineop. I'm not sure what the intended layering of dialects is, but maybe we could standardize pipeline generators to go through that.

@mikeurbach
Copy link
Contributor Author

Coming back to this a couple months later, I guess the proper place for such an operation would be in the seq dialect? The staticlogic.pipeline is higher level, and solves a different problem.

@mikeurbach mikeurbach changed the title [RTL/SV] Pipeline generator [Seq] Pipeline generator Apr 13, 2021
@teqdruid
Copy link
Contributor

teqdruid commented Apr 13, 2021

I don't think the seq dialect is the right place for this as it is a higher level construct and not well understood or agreed upon.

What would be the difference between this op and the pipeline in static logic?

@mikeurbach
Copy link
Contributor Author

Maybe we're talking about different things. The StaticLogic pipeline is meant to describe pipelined computation:

The "staticlogic.pipeline" operation represents a statically scheduled
pipeline stucture which contains several MLIR blocks. Each MLIR block is
corresponding to a pipeline stage.

What I'm interested in is something more like the ESI ChannelBuffer:

A channel buffer (`buffer`) is essentially a set of options on a channel.
It always adds at least one cycle of latency (pipeline stage) to the
channel, but this is configurable.

There are many places that we just want a bunch of "registers" connected in a series, without any fancy computation in between. So I was imagining something in the seq dialect (maybe "pipeline" is a misnomer), that essentially represents the same thing as the ChannelBuffer. It could potentially lower into seq.compregs connected back-to-back. The ESI ChannelBuffer could trivially lower into this (or be replaced by it) and the FIRRTL memory lowering could also use it. Or, maybe this doesn't need to be a new op, it could just be a helper function to build a properly connected series of seq.compreg, similar to the code Andrew just implemented here: https://github.com/llvm/circt/pull/915/files#diff-d79ddd3f6d31d832cd0a2a7934495c126c0bad25a46fd09ca8b079a94c1fe815R60-R75

Apologies if I'm not understanding or if I'm using the wrong terminology, but the above pattern keeps coming up (so far in Handshake, ESI, and FIRRTL), so I thought it would be good to have one place in CIRCT where this can be implemented. Another way to look at it is I would like to generalize the ChannelBuffer to not be ESI-specific, and implement a lowering to in-tree dialects, rather than lowering to a Verilog primitive.

@teqdruid
Copy link
Contributor

Yeah, "pipeline" can mean many things but it generally describes pipelined computation. There are a bunch of terms (all implying slightly different things) for what you're looking for. I typically use the term "buffered wire" (or just "buffer") but that is often confused with the notion of an electrically buffered wire. Pipelined wire is probably clearer.

I think there is value in an op like this. I actually agree that it should be in the seq dialect but I could imagine getting pushback on this. We don't have a talk scheduled for tomorrow. Maybe this could be a topic of discussion?

ESI's channel buffer will eventually broaden beyond what it is today, but I don't think I'll be able to lower it to a PipelineRegOp anytime soon since pipelines generally describe feed-forward (no backpressure) pipelines. ESI (and handshake) require elastic pipelines, which are far more complex than a bunch of registers back-to-back. Any op which goes in seq would be feed-forward. FF pipelines can be used to implement elastic pipelines, but that's a who 'nother discussion.

@mikeurbach
Copy link
Contributor Author

Got it, thanks for the additional info. I'm looking forward to the memory discussion tomorrow, but I'll add this to the docket as well.

@teqdruid teqdruid linked a pull request May 26, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants