* a BufferedPipeline followed by * an UnbufferedPipeline (or UnbufferedPipeline2 which is the logic from BreakReadyChainStage) will FAIL for no good reason that i can see. *all other permutations work fine*. * BufferedPipeline followed by BufferedPipeline: fine * UnBufferedPipeline followed by BufferedPipeline: fine * UnBufferedPipeline2 followed by BufferedPipeline: fine * UnBufferedPipeline followed by UnbufferedPipeline: fine * UnBufferedPipeline2 followed by UnbufferedPipeline2: fine i haven't tried permutations of UnbufferedPipeline with UnbufferedPipeline2. this bug occurred *before* the addition of the dynamic data valid/ready logic, i just hadn't written a unit test that caused the above failure until writing the dynamic data valid/ready code. as it was interfering with the development i went back to a version of the code from a day ago, and *confirmed* that the bug is still present *before* the dynamic data valid/ready logic was added.
https://git.libre-riscv.org/?p=ieee754fpu.git;a=blob;f=src/add/test_buf_pipe.py;h=472675c742d6898136c305f301e7b159250f0742;hb=6e10838b834025c859c070d919b5b8ba1dc44436#l681
p_o_ready is combinatorial and is an entire cycle *too early*, relative to the data. so the BufferedPipeline is receiving a n_i_ready signal indicating that the next stage (the UnbufferedPipeline) is ready when it is not. the *other way round* is fine... because there is a delay introduced.
http://lists.libre-riscv.org/pipermail/libre-riscv-dev/2019-April/001009.html
created a new mode to BufferedPipeline which takes out the register (saving gates), and preserves the synchronised logic. still have to work out what to do about UnbufferedPipeline.
Created attachment 7 [details] gtkwave screenshot showing p_o_ready not in sync p.o_ready is not properly in sync with data, it is being set just beyond the clk. this means that only a combinatorial chain will be ok... right up until the point where it's connected to a sync'd valid/ready unit. by contrast, SimpleHandshake and BufferedHandshake send the data *and* its associated p.o_ready on the clock.
Truth Table Inputs Temp Output ------- - ----- P P N N ~NiR& N P i o i o NoV o o V R R V V R ------- - - - 0 0 0 0 0 0 1 0 0 0 1 1 1 0 0 0 1 0 0 0 1 0 0 1 1 0 0 1 ------- - - - 0 1 0 0 0 0 1 0 1 0 1 1 1 0 0 1 1 0 0 0 1 0 1 1 1 0 0 1 ------- - - - 1 0 0 0 0 1 1 1 0 0 1 1 1 0 1 0 1 0 0 1 1 1 0 1 1 0 1 1 ------- - - - 1 1 0 0 0 1 1 1 1 0 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 0 1 1 ------- - - - Note: PoR is *NOT* involved in the above decision-making. If p.o_ready is ignored, it has no way to determine if, during the previous cycle, it told the previous stage "sending data is okay". This is what is resulting in data corruption.
different types of pipelined and non-pipelined objects cannot be chained together. if one is pipelined but the other is not then whilst one can signal to other to stall, it cannot actually do so. closing as invalid