K
KJ
Kim Enkovaara said:The problem is to make clear functional description so accurately that
it describes all the functionality in the pipeline. At least in my
opinion tracking dependencies between pipeline stages is hard.
I'll certainly agree that tracking dependencies between pipeline stages is
hard...so don't design it that way. Use a good flow control specification
that scales well all the way up and down as your basis for getting things in
and out of sub blocks and I think you'll find that darn near all of your
dependency tracking will no longer be required.
Those descriptions may not need to be so terribly hard to produce as you may
be imagining. Keeping in mind the boundaries, you would be describing the
function of your 'Stage 3' only in terms of the inputs to stage 3 and the
function of 'Stage 25' only in terms of the inputs to Stage 25. Using a
common flow control specification (i.e. Avalon, Wishbone, etc.) as the basis
for getting stuff in and out of each block you would not need to really even
talk about flow control of any of the stages other than to say (and then of
course design to) that flow control specification.
OK, now if all the stages are designed say to adhere to Altera's AvalonWith dependencies I mean something like this as an example:
"Stages 3 and 25 share a common memory and stalls in the pipeline are
not allowed. When the format of incoming data is known we know that
when s3 is accessing memory s25 has propagated data that doesn't need
that access".
specification (as an example, not a sales pitch) then both stage 3 and stage
25 would be designed with a master interface for accessing the slave memory
and if your above statement is true then you would simply find that the
stage 3 read/write output signals do not happen to be set at the same time
as the stage 25 read/write output signals. That being the case, one can
- Simply add an assert to validate during simulation that this condition is
never violated.
- Or, detect and report the condition in a status bit
- Or, cover yourself and realize that stage 3 and stage 25 are competing for
a shared resource and add a simple arbiter.
If you did the design with this approach, you'd find that while you're
working on getting the stage 3 functionality up you would not need to know
or care about stage 25 (or any other stage). Same can be said for stage 25.
When it comes time to writing the logic that ties them all together (for the
most part the 'logic' is simply connecting the outputs of one stage to the
inputs to the next) the simple arbiter that you would need would cost at
most a single logic cell.
If your above statement about stages 3 and 25 and the memory are stillNow think that change is needed and one pipeline stage is added.
What are all the dependencies that have to be also changed, what are
the new hazards, is the new condition adding new hazards?
inherently true then I don't need to think about any changes in
dependencies. I simply design the new stage X to the same flow control
specification, connect it up and everything works out just fine. If adding
the new stage possibly alters the relationship between stages 3 and 25 and
the memory then I've already designed in the arbiter so the only thing that
needs to be considered is does the arbiter now maybe need some buffering on
the data path from each stage to avoid stalling the input to the pipeline.
Then don't do it the hard wayThose dependencies are really hard to handle.
Formal model checking can
be a good tool to proof that hazards are not possible with the used
constrained incoming data.
I've never happened to use them though. How good are they in practice and
how much work are they to use?
Of course there can be error conditions and
the design must get over them and heal itself, or at least indicate that
pipeline reset is needed.
In just pure dataflow pipeline without dependencies is not so hard to
document. It is just defined transactions between stages.
So then I think we agree that documenting the function of the sub blocks is
not the issue with documenting, just the dependency documentation.
But if the dependencies you're tracking are all flow control related, then
design everything to a good flow control specification that is designed to
handle stalls. If your requirement is for no stalls, and you've done your
design properly then all that will happen is that the 'wait' input to the
start of the pipeline will never get set even though the 'wait' input to
some of the individual sub-blocks might. The overhead in logic for using
something like Avalon is almost non-existent and the headaches that get
avoided by having to worry about how stages 3 and 25 and the memory all work
together are worth it.
Even if there are other dependencies outside of flow control to be
considered, I'm betting that flow control related dependencies are actually
far and away the biggest thing.
If the individual stages can possibly stall but the overall function can notAlso if
the stages can stall sometimes, and there are fifos to handle that,
then hazard handling comes much easier.
than there better be some fifos somewhere
Kevin Jennings