Shop OBEX P1 Docs P2 Docs Learn Events
asymmetry between rd[long,word] and wr[long,word] — Parallax Forums

asymmetry between rd[long,word] and wr[long,word]

agsags Posts: 386
edited 2013-10-25 13:29 in Propeller 1
Every time I find something that seems odd, there's been a good reason behind it. I suspect this is no different.

Can anyone explain the thinking behind the PASM hub RAM read/write instructions? Specifically, the rdlong and rdword instructions clear the 2- and 1-LSbit of the address to be read, ensuring a long- and word-aligned destination (respectively). However, (per the documentation) the wrlong and wrword instructions do not do this (or it isn't stated that they do - I can't test at the moment as I don't have a Prop with me). That (apparently) means that I can write a long value to address xxx01, not long-aligned.

Thanks for any insight into this.

Comments

  • Dave HeinDave Hein Posts: 6,347
    edited 2013-04-04 13:10
    I believe the addresses for read and write work the same. rd/wrlong ignores the 2 LSBs and rd/wrword ignores the LSB.
  • agsags Posts: 386
    edited 2013-04-04 14:22
    I thought the same thing. Then I re-read the manual, and it makes it explicitly clear that this is the case with the rd[long/word] instructions (two or one LSbit ignored/zeroed) , but it says nothing at all about that for the wr[long/word] instructions.
  • kuronekokuroneko Posts: 3,623
    edited 2013-04-04 15:45
    Forget the manual and just go with the datasheet (which does mention the address handling for each of the 6 insn).
  • agsags Posts: 386
    edited 2013-04-04 16:24
    I just searched the datasheet (v1.2, 4-24-2009) and didn't find any reference. This is the online document titled "Propeller P8X32A Datasheet v1.2" Is this the one you are referring to?
  • kuronekokuroneko Posts: 3,623
    edited 2013-04-04 16:32
    ags wrote: »
    I just searched the datasheet (v1.2, 4-24-2009) and didn't find any reference. This is the online document titled "Propeller P8X32A Datasheet v1.2" Is this the one you are referring to?
    I have rev 1.0 printed out which has the info, currently it is at 1.4 (PropTool or this link). You want the table in section 6.4 (unless you want it spelled out, but then you are at the mercy of the manual).
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2013-04-04 19:29
    You shouldn't need either the manual or the datasheet for this, when a simple gedanken experiment will suffice. Consider this: hub memory is accessed as 32-bit long-aligned chunks by the Propeller hardware. A non-aligned word or long write would require two hub memory accesses to complete, which would break instruction timing. Therefore, such writes do not occur, meaning that one or two LSBs of the hub address are assumed to be zero for these writes.

    -Phil
  • agsags Posts: 386
    edited 2013-04-05 08:58
    Consider this: hub memory is accessed as 32-bit long-aligned chunks by the Propeller hardware ... Therefore, such writes do not occur...
    -Phil

    Phil:

    This is the first time I've seen (or understood) this. I suspected it (don't know how the hardware would implement arbitrary read/write alignment/size, implying no inherent boundaries in memory at all) but now it's clear. This is a good example of how (for me) understanding the details of the underlying hardware is very helpful in avoiding problems. I can now just keep in mind that memory (even hub RAM) is really long-aligned. In other words, accessing a byte really accesses a long (masking the 2 LSbits to determine the "container long" to access, and then the 2 LSbits are used to mask and shift bits appropriately). Is this the way the SPIN interpreter is implemented?

    One other way of saying this, more simply and clearly: hub RAM is just as long-aligned as cog RAM. SPIN provides an illusion of byte- or word-level access by handling the masking/shifting that is done manually in PASM code.

    This has resurfaced as a topic of interest for me as I am doing more advanced (or maybe just risky, poor design) work. For instance, I define a VAR byte array. So that is (only guaranteed to be) byte aligned. But I pass the address in to a PASM driver (using a "mailbox", not par, so all 16 address bits are intact). To speed up hub RAM r/w, I aways r/w using RD/WRLONG, rather than RD/WRBYTE four times. You can see the problem - made worse because there is a one-in-four chance that it will actually work, depending on ordering of the VAR block symbols. Ouch.
  • Mike GreenMike Green Posts: 23,101
    edited 2013-04-05 09:14
    1) This behavior (ignoring 2 LSBs for xxLONG and 1 LSB for xxWORD) is done in the hardware. Memory accesses are done using LONGs and xxBYTE and xxWORD access the appropriate portion of the long word for reading or writing.

    2) The SPIN interpreter doesn't do anything special with this. Byte variables are accessed using xxBYTE instructions and word variables are accessed using xxWORD instructions and the hardware takes care of the rest.

    3) Yes, you will run into trouble if you use xxLONG to access values that are not aligned on 32-bit boundaries. You will also run into trouble if you use xxWORD to access values not aligned on 16-bit boundaries.

    4) This is often solved by allocating your "fast" buffers as LONG arrays and accessing them using xxBYTE instructions and .BYTE[n] suffixes (like myLongArray.BYTE[n]). This will force SPIN to use its byte interpretive codes to access the individual bytes in the array and "n" is considered a byte index.
  • agsags Posts: 386
    edited 2013-04-05 09:50
    Thanks for the clarifications Mike. This simplifies things for me quite a bit. Until now, I found myself spending more time than seemed reasonable trying to think through all the alignment/access scenarios. Now it's pretty clear.

    The reason I declared the array a byte array is because I do access it in SPIN, and I wanted to avoid the tedious (IMO) need to use the byte[base][offset] syntax everywhere. (I realize I can also just use base+offset to calculate the address directly). I posted in a separate thread in hopes there was some way around this (like a C typedef) but no one had a solution to offer.

    I suppose one way around this would be to ensure that the array is the first byte aligned symbol in the VAR section. That strikes me as pretty fragile and error prone, though. At least I understand it now though.
  • agsags Posts: 386
    edited 2013-04-07 13:33
    kuroneko wrote: »
    I have rev 1.0 printed out which has the info, currently it is at 1.4 (PropTool or this link). You want the table in section 6.4 (unless you want it spelled out, but then you are at the mercy of the manual).
    BTW, it was in there (versions 1.2 and 1.4), I just missed it. I didn't read closely enough to see that bits of s/d registers that are used are explicitly called out. My apologies for the unnecessary inquiry (but answer appreciated nonetheless).
  • 5thDimension5thDimension Posts: 10
    edited 2013-10-25 13:29
    This was a great discussion; really answered some questions I had. Thanks to all who contributed to it!
Sign In or Register to comment.