[libre-riscv-dev] pipeline sync issues

Jacob Lifshay programmerjake at gmail.com
Wed Apr 17 05:31:04 BST 2019


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.
>
> that's why the unit tests that i wrote have been barfing when
> BufferedPipeline has been connected to any of UnbufferedPipeline,
> RegStage or BreakReadyStage, because they deliberately set/clear send
> and receive conditions on a random basis.
>
> so basically, pipe-mode requires - *REQUIRES* - that the down-stream
> recipients read the damn data. if it says "read enabled", you MUST
> read it, because the "pipe" has been set to a mode where new data
> *will* come in.
>
> 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.

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.

Jacob



More information about the libre-riscv-dev mailing list