Shop OBEX P1 Docs P2 Docs Learn Events
RFBYTE/WORD/LONG work in hub exec — Parallax Forums

RFBYTE/WORD/LONG work in hub exec

TonyB_TonyB_ Posts: 2,232
edited 2025-12-20 12:23 in Propeller 2

I have tested RFBYTE/WORD/LONG in hub exec and they work, contrary to what the documentation says. They remove the byte/word/long after the next instruction from the FIFO. Possible uses for this are (a) to read data embedded within hub exec code, maybe put there by another cog and (b) to skip an instruction without any time penalty.

An example of (a):

rflong x
<instr2>
long $x_data
rflong y
<instr4>
long $y_data

The main advantage of using RFxxxx is that takes only two cycles, much faster than the 9...26 cycles (+1 if long crossing) for RDxxxx in hub exec mode. Note that if you wait sufficient time after a hub exec branch for FIFO filling to finish, RDxxxx can take the same as in cog exec, 9...16 cycles (+1 if long crossing).

An example of (b):

if_nz rflong temp
      <instr1>
_ret_ <instr2>
'return if z, continue if nz

Using RFLONG to skip an instruction is equivalent to SKIPF with fixed skip pattern of %10. Hub exec doesn't support SKIPF itself. RFLONG removes the skipped instruction from the FIFO before it enters the instruction pipeline so it wastes no cycles, unlike SKIP.

RFVAR{S} did not work in hub exec mode in my tests. Consecutive RFBYTE/WORD/LONG also did not work. However, all RFxxxx can be used in cog exec after a routine in hub RAM returns. The data that RFxxxx reads start four bytes after the routine because the long directly after it has been read already as part of instruction pipelining. Note that a RDFAST is not needed before RFxxxx in this case because the former was done during the branch from cog to hub exec.

EDIT:
Added RFxxxx vs. RDxxxx time comparison.

Comments

  • evanhevanh Posts: 17,009

    Thieving data makes sense. And I'd come to the conclusion the FIFO doesn't terminate. It just stops being used.

  • TonyB_TonyB_ Posts: 2,232
    edited 2025-12-19 23:34

    @evanh said:
    Thieving data makes sense. And I'd come to the conclusion the FIFO doesn't terminate. It just stops being used.

    Yes and the good thing is that RFxxxx doesn't interfere with an instruction fetch in hub exec. I might test RFVAR{S} again as the other RFxxxx work.

    It's perfectly possible to do the following:
    From cog/LUT exec, call a routine in hub RAM then after it returns do RFxxxx's to read data starting four bytes after the end of the routine, without ever needing a RDFAST.

  • RaymanRayman Posts: 15,899

    Hmm... I was also under the impression that one can't touch the fifo in hubexec mode...

  • evanhevanh Posts: 17,009

    @Rayman said:
    Hmm... I was also under the impression that one can't touch the fifo in hubexec mode...

    It will crash your program if not carefully crafted.

  • @evanh said:

    @Rayman said:
    Hmm... I was also under the impression that one can't touch the fifo in hubexec mode...

    It will crash your program if not carefully crafted.

    For some instructions the docs are 'guidelines' more than rules. I thought RFxxxx in hub exec was worth trying and what I've described above does actually work. Care is needed to match RFxxxx with the size of data being removed from the FIFO, e.g.

    rfbyte x
    <instr2>
    byte $x_data
    rflong y
    <instr4>
    long $y_data
    

    but otherwise coding is straightforward.

  • roglohrogloh Posts: 6,209
    edited 2025-12-20 03:39

    This looks potentially useful for some future things. Perhaps it could pass a fixed 32 bit argument to some common cogexec routine called via different hubexec codepaths saving a couple of cycles, or for a parameter / return address? to an execf code block in cog RAM from hubexec code. That could allow a nice way to "return" back to hubexec from conditionally called execf code sprinkled throughout your hubexec code. Eg to return back to your hubexec code you could do:

    in hubRAM:

    rflong retaddr  ' read return address before conditionally branching into cogexec code
    if_z execf cogsvc ' conditionally do cog service
    long $+4 ' address of next long in hub
    <next_instr> ' next hubexec instruction after cogexec mode completes continues here
    

    in cogRAM:

    cogsvc  long  #%101001110 << 10 + cogexecsvc ' skipf pattern
    retaddr long 0 ' place to store return address
    
    cogexecsvc <svc_instr1>
    <svc_instr2>
    ...
    jmp retaddr ' continue with hub exec from where it was called
    

    This probably does incur a penalty however when returning due to hub fifo refill. But if your COG RAM is full and you can't break apart the service routines and can conveniently pack them together with execf it could still be helpful.

  • RaymanRayman Posts: 15,899
    edited 2025-12-20 21:41

    I'm trying to understand that first example...

    So x and y are cog registers associated with the cog that is running the hubexec code, got that.
    No "RDFAST" command is needed?

    You just drop in a rflong x and then x gets loaded with hub data at PC+8?

    What is with the:
    <instr2> and <instr4>
    .. are these actually executed?
    Or, are you saying they are skipped?

  • evanhevanh Posts: 17,009

    The long $x_data and long $y_data are not executed because they are stolen out of the FIFO by each respective RFLONG. The FIFO is happy to give up its content to whichever path does the grabbing. It still behaves as a FIFO.

    Applies to the streamer too: If the cog reads the FIFO between streamer reads then their respective data can be described as interleaved in hubRAM. The streamer could also coincide it reads, that would count as a single to the FIFO and I don't know if both would see the same data. Probably would.

  • evanhevanh Posts: 17,009

    @evanh said:
    The long $x_data and long $y_data are not executed because they are stolen out of the FIFO by each respective RFLONG. The FIFO is happy to give up its content to whichever path does the grabbing. It still behaves as a FIFO.

    This being reliable probably implies the two paths are clocked on alternate clocks. Which will possibly just be incidental in terms of FIFO. Chip won't have explicitly designed it for the FIFO that way.

  • RaymanRayman Posts: 15,899

    seems you can't use <instr2> and <instr4> in a post without marking it as code...
    Fixed my post above just now...

  • evanhevanh Posts: 17,009
    edited 2025-12-20 21:53

    @Rayman said:
    seems you can't use <instr2> and <instr4> in a post without marking it as code...
    Fixed my post above just now...

    Correct, hubexec is operating the whole time. It always takes from the FIFO on every second clock cycle. The FIFO will in turn read from hubRAM at a faster rate than regular hubexec because the RFLONGs are consuming extra longwords from the FIFO on the alternate clock cycles.

    There's definitely extra demands that could have gone crappy but don't.

Sign In or Register to comment.