[libre-riscv-dev] [hw-dev] Re: 6600-style out-of-order scoreboard designs (ariane)

Luke Kenneth Casson Leighton lkcl at lkcl.net
Wed May 22 09:12:37 BST 2019


ok so here's scenario 1:

* two instructions are both idle
* therefore there are (obviously) no read (or write) dependencies
* both CUs are idle, both are !BUSY, therefore both are not generating
"Write Req Rel"
* therefore, GO_WRITE is prevented from happening.
* the same is *NOT* true of GO_READ.
* instruction 2 tries to issue... this FAILs because the priority picker is
stuck on Instr 1.

here's the sequence:

Issue1 ________________________________________________

Issue2 ________________________________________________

RDDeps1 _______________________________________________

RDDeps2 _______________________________________________

RD Deps are NORed together to produce "Readable" (which, because the reads
are all LO, and there is *NO RD_REQ_RELEASE*, is *PERMANENTLY* HI for *BOTH
UNITS*):
                   ________________________________________________
RDABLE1  /
                   ________________________________________________
RDABLE2  /

the priority picker *PERMANENTLY* generates a priority pick for Unit 1, and
*NEVER* generates a priority pick for Unit 2:
                   ________________________________________________
GO_RD1  /

GO_RD2   ________________________________________________


the first fix for this that i tried was to use the "Function Unit Busy"
signal as a form of "Read Release".  this worked for some circumstances...
until i made the instruction completion time much longer. then i had this:

               _________________________________________
Issue1 _/
                        __________________________________________
Busy1:______/

RDDeps1: _________________________________________
               ________________________________________________
RDBL1: /

because readable is now GATEd by Busy1,  GORD goes HI even though READABLE1
is permanently HI (no dependencies).  bear in mind: there *are* no Read
Dependencies, therefore (just as above), READABLE1 *will* remain
permanently HI.
                         _________                  ______
  _______
GORD1: ____/                   \________/            \_________/
  \______......

except... unfortunately, on very long instructions, because Busy1 remains
HI for a long duration, and because (obviously) the instruction never gets
any *new* dependencies (duh), after the GO_Read is DEASSERTED (on one
clock), the BUSY1 signal is (clearly) still HI, so the priority-picker
goes, "oh!  your READABLE is HIGH?  let me give you another GO_READ!"

flip-GOREAD, flop-NOGOREAD, flip-GOREAD, flop-NOGOREAD

the same does not happen on Write because Write has that "cancellation"
signal which is using an SR-Latch that, once it goes LOW, it can *NEVER* be
re-asserted until *AFTER* Issue goes LOW.

what my experimentation showed is: the *exact* same logic applies to Read
as does to Write.

have i been able to explain it clearly enough, this time?

l.


More information about the libre-riscv-dev mailing list