[libre-riscv-dev] pipeline sync issues

Luke Kenneth Casson Leighton lkcl at lkcl.net
Wed Apr 17 08:09:19 BST 2019

On Wed, Apr 17, 2019 at 5:31 AM Jacob Lifshay <programmerjake at gmail.com> wrote:
> On Tue, Apr 16, 2019 at 5:45 AM Luke Kenneth Casson Leighton
> <lkcl at lkcl.net> wrote:
> >
> > that's it: pipe mode is where the problems occur.
> >
> >                      # set readable and writable (NOTE: see pipe mode below)
> >                      self.readable.eq(~empty), # cannot read if empty!
> >                      self.writable.eq(~full),  # cannot write if full!
> >
> > so that's all sensible, so far.  if there's no room, don't allow
> > writing!  unfortunately... "pipe mode" does this:
> >
> >             with m.If(self.re):
> >                 m.d.comb += self.writable.eq(1)
> >
> > i.e. the "writeable" conditions are over-ridden (against plain
> > commonsense, i feel obliged to say).
> >
> > thus, if read is enabled, writable is *FORCED* to be set.  therefore,
> > if the output does NOT read the data, the input will DESTROY one value
> > in the FIFO by overwriting it.
> The value has not been destroyed, it's been output and the space in
> memory is simultaneously reused for the next input value. This works
> because the memory read port is asynchronous and therefore reads the
> old value and the write port is synchronous, so it acts similarly to a
> D flip-flop in that the old value can be read in the same clock cycle
> that a new value is being written.

 i understand that... it wasn't quite what i meant, having missed out
a word that allowed an ambiguous meaning.

 i meant, destroyed by virtue not of the conditions *inside* the stage
that contains the memory cell, instead by conditions (the contract)
being misunderstood *outside* of the stage that contains the memory
cell, i.e. by the *previous* stage

 i.e. by virtue of the former stage having set e.g. flow=True,
pipe=False, and the following stage having set... i don't know..
say... flow=False,pipe=True.

 my hunch is that there may be some conditions that, given the
existence of the new parameters flow (fwft) and pipe, we *might* be
able to *programmatically* check that, if a connection between two
pipes is made, and we *know* the conditions under which data will be
destroyed, it will be possible to throw an exception.

> > would you concur, jacob?
> I think there's no problem with that. If deq_ready (renamed to re) is
> set by external logic, that tells Queue that the external logic wants
> to transfer a value out, so if the external logic doesn't actually use
> the value it asked for, that's not Queue's fault.

 it's not the Queue's fault... yet what is to stop a programmer from
*not realising* that a problem can occur, and connecting two
pipe-stages together that are *known* to destroy data?

 we *need* to track this down, properly.

> Also, in the sort-of unit tests at the end of queue.py,
> BreakReadyChainStage is not equivalent to the case flow=True and
> pipe=True, it's only equivalent to the case flow=True and pipe=False.

 ok.  so that's something to test.

 i'm going to convert test_buf_pipe.py to nosetest-style running capability.


More information about the libre-riscv-dev mailing list