Shop OBEX P1 Docs P2 Docs Learn Events
Prop2 FPGA files!!! - Updated 2 June 2018 - Final Version 32i - Page 158 — Parallax Forums

Prop2 FPGA files!!! - Updated 2 June 2018 - Final Version 32i

1154155156158160

Comments

  • RaymanRayman Posts: 13,803
    Questions about MODCZ

    I think I see that you use %0000 to clear C or Z and %1111 to set.
    Do you need to use WCZ to set these?
    I think you do, but don't see why. The other modX don't need anything special to work, right?

    Also, is "cccc" and "zzzz" actually defined anywhere?
    I think it's the same format as "instruction prefix".
    But, this isn't so clear when applied here...
  • RaymanRayman Posts: 13,803
    edited 2019-03-13 20:34
    Think I might need a 1-clock instruction to interface HyperRam @ 100 MBPS with a 250 MHz clock.
    Is there any way to skip one clock?
  • RaymanRayman Posts: 13,803
    Ok, I think I'll slow the HyperRam down and try using waitse# to follow RWDS.

    Question: How does timing of waitse# track with INA?

    Are they both 2 clocks behind?
  • TonyB_TonyB_ Posts: 2,108
    edited 2019-03-13 23:53
    Rayman wrote: »
    Questions about MODCZ

    I think I see that you use %0000 to clear C or Z and %1111 to set.
    Do you need to use WCZ to set these?
    I think you do, but don't see why. The other modX don't need anything special to work, right?

    Also, is "cccc" and "zzzz" actually defined anywhere?
    I think it's the same format as "instruction prefix".
    But, this isn't so clear when applied here...

    Usage:
    MODCZ cccc,zzzz WCZ
    MODC cccc WC
    MODZ zzzz WZ
    ---------------
    MODCZ constants cccc/zzzz
    ---------------
    
    _CLR                    =       %0000
    _NC_AND_NZ              =       %0001
    _NZ_AND_NC              =       %0001
    _GT                     =       %0001
    _NC_AND_Z               =       %0010
    _Z_AND_NC               =       %0010
    _NC                     =       %0011
    _GE                     =       %0011
    _C_AND_NZ               =       %0100
    _NZ_AND_C               =       %0100
    _NZ                     =       %0101
    _NE                     =       %0101
    _C_NE_Z                 =       %0110
    _Z_NE_C                 =       %0110
    _NC_OR_NZ               =       %0111
    _NZ_OR_NC               =       %0111
    _C_AND_Z                =       %1000
    _Z_AND_C                =       %1000
    _C_EQ_Z                 =       %1001
    _Z_EQ_C                 =       %1001
    _Z                      =       %1010
    _E                      =       %1010
    _NC_OR_Z                =       %1011
    _Z_OR_NC                =       %1011
    _C                      =       %1100
    _LT                     =       %1100
    _C_OR_NZ                =       %1101
    _NZ_OR_C                =       %1101
    _C_OR_Z                 =       %1110
    _Z_OR_C                 =       %1110
    _LE                     =       %1110
    _SET                    =       %1111
    
  • AJLAJL Posts: 512
    edited 2019-03-13 23:17
    Rayman wrote: »
    Questions about MODCZ

    I think I see that you use %0000 to clear C or Z and %1111 to set.
    Do you need to use WCZ to set these?
    I think you do, but don't see why. The other modX don't need anything special to work, right?

    To expand on what TonyB_ wrote:
    WCZ affects both flags, while WC and WZ only affect the respective flag; Without either, it effectively becomes a NOP.


    Edit: MODC and MODZ are simply aliases for MODCZ that make it clear that you only intend to affect one flag.
  • RaymanRayman Posts: 13,803
    TonyB_: Is this list in the documentation anywhere?
  • cgraceycgracey Posts: 14,133
    Rayman wrote: »
    TonyB_: Is this list in the documentation anywhere?

    It's in "instructions.txt" within the zip file.
  • cgraceycgracey Posts: 14,133
    evanh wrote: »
    cgracey wrote: »
    ... it's a little more economical to keep it in the hub.
    That's something I bet wasn't tested in terms of used routing space. The bigger the cogs are the longer the linking routes become.

    Those routes already exist for conveying results of other hub instructions, so there's no extra routes to cogs, only some hub logic.
  • Cluso99Cluso99 Posts: 18,066
    MODCZ
    Be careful, MODZ _SET WZ sets to Z,
    whereas _CLR sets to NZ
  • cgraceycgracey Posts: 14,133
    Cluso99 wrote: »
    MODCZ
    Be careful, MODZ _SET WZ sets to Z,
    whereas _CLR sets to NZ

    I just tested this and it works correctly, setting or clearing the flag, and not toggling it.
  • Cluso99Cluso99 Posts: 18,066
    edited 2019-03-14 01:24
    cgracey wrote: »
    Cluso99 wrote: »
    MODCZ
    Be careful, MODZ _SET WZ sets to Z,
    whereas _CLR sets to NZ

    I just tested this and it works correctly, setting or clearing the flag, and not toggling it.

    I didn't mean it wasn't working, just that sometimes it seems back the front. Z is always a problem ;)
  • evanhevanh Posts: 15,126
    cgracey wrote: »
    evanh wrote: »
    cgracey wrote: »
    ... it's a little more economical to keep it in the hub.
    That's something I bet wasn't tested in terms of used routing space. The bigger the cogs are the longer the linking routes become.
    Those routes already exist for conveying results of other hub instructions, so there's no extra routes to cogs, only some hub logic.
    Cool.
  • Cluso99 wrote: »
    MODCZ
    Be careful, MODZ _SET WZ sets to Z,
    whereas _CLR sets to NZ

    Given the convention of a set flag being '1' state and a clear flag being '0' state, it is clearer to restate what you wrote as

    "Be careful, MODZ _SET WZ sets the flag to indicate Z,
    whereas _CLR clears the flag to indicate NZ"

    with italics showing inserted text and bold showing changed text.
  • evanhevanh Posts: 15,126
    We've been through that before. Cluso doesn't want the Z flag to be viewed as a plain store bit in any situation.
  • evanh wrote: »
    We've been through that before. Cluso doesn't want the Z flag to be viewed as a plain store bit in any situation.

    Yes, I saw that. It doesn't mean that his world view is entirely right, nor that it should be entirely ignored.

    The fact that the Z flag can be operated on, set, and cleared directly is at odds with its function as a zero result flag.

    Cluso99 wants (or needs) to continue to read Z as Zero state, and NZ as Non-Zero state, rather than Z as set state, and NZ as clear state (Not-Z) of the Z flag. Ok, fine by me, I think both views can be accommodated, even if you don't get all parties to agree.

    The phrasing I selected was intended to be inclusive of both its operation and implementation (as a general purpose flag), and the interpretation of the meaning of the flag supported by its name.

  • Cluso99Cluso99 Posts: 18,066
    edited 2019-03-14 07:00
    The problem is that it varies depending on which instructions you are using.

    I always view the Z flag as Z=result is zero and NZ is result is non-zero. That is the majority case!!!
    Unfortunately a few instructions (like testB and MODZ) copy the bit into the Z flag rather than indicating the result is Zero or Non-Zero. So the Z flag is now reversed to the common usage.

    I am living with it, but where the result is not what some expect, it needs a warning.
  • evanhevanh Posts: 15,126
    There is lots of small details that are not clear about many things. When I use the regular CMP instruction I always add the comment "C = borrow of (D - S)" because I can't be sure if it D or S that is above, below, greater, less or whatever.

    The non-numeric uses of Z and C is one of the easier ones to follow.
  • Cluso99 wrote: »
    The problem is that it varies depending on which instructions you are using.

    I always view the Z flag as Z=result is zero and NZ is result is non-zero. That is the majority case!!!
    Unfortunately a few instructions (like testB and MODZ) copy the bit into the Z flag rather than indicating the result is Zero or Non-Zero. So the Z flag is now reversed to the common usage.

    I am living with it, but where the result is not what some expect, it needs a warning.

    Personally I disagree with your view of the reversal of meaning, as the flag represents (among other things) the zero output of the ALU, but copying the bit into the flag doesn't involve an ALU operation, AFAICT. However, I'm not inflexible enough to stand my ground and insist that your view is wrong.

    I agree regarding the need for a warning, but equally the warning needs to be clear to as many as possible.

    The flag is labelled Z, and the states of the flag being referred to are Z and NZ, which everyone seems to follow and agree is correct, and therefore is the language I used for the reworded warning.
    The issue appears to only relate to bit-wise operations, where copying the state of the bit to the flag disagrees with Cluso99's view of what should happen.
    Many of us believe that when dealing with individual bits, the state should transfer unchanged, rather than performing a decision on whether the bit is Zero or Non-Zero.

    Question for @Cluso99 : Do you believe the instructions that store and restore the state of the flags should invert the Z flag in both actions, or store and restore the flag state unchanged?
  • Cluso99Cluso99 Posts: 18,066
    edited 2019-03-14 11:21
    @AJL
    Here is the ambiguity in a nutshell...
                    and     x,#1    wz
            if_z    'the result was zero
    
                    testb   x,#1    wz
            if_nz   'the bit was zero
    

    Is this consistent???


    And in Chip's P1 Spin Interpreter he sets the bottom 2 bits of the byte code into the flags thus...
                    test    op,#%01         wz      'get flags                          
                    test    op,#%10         wc      '(note varop requires c=1)
      if_nc_and_z   'bits=00
      if_nc_and_nz  'bits=01
      if_c_and_z    'bits=10
      if_c_and_nz   'bits=11
    
    In P2 we can use XBYTE which can write the LUT EXEC bits 1 and 0 to C and Z
    While I have not tested this, I expect that the Z will be reversed as
      if_nc_and_nz  'bits=00
      if_nc_and_z   'bits=01
      if_c_and_nz   'bits=10
      if_c_and_z    'bits=11
    
  • evanhevanh Posts: 15,126
    yes
  • The use of the Z flag is well documented, and it's meaning is clear to me.
  • RaymanRayman Posts: 13,803
    edited 2019-03-14 12:45
    Looks like the difference is whether or not it is a regular ALU or move type of operation...
    Things like testb and modcz are different and maybe can be expected to behave differently...

    I'm not sure I like the name "testb" though as it does imply to me that it would behave like Cluso thinks....
    Don't know what I'd call it instead though... Maybe "movbf" for move a bit to a flag...
    Or, maybe "movbcz" is better...
  • AJLAJL Posts: 512
    edited 2019-03-14 13:08
    Cluso99 wrote: »
    @AJL
    Here is the ambiguity in a nutshell...
                    and     x,#1    wz
            if_z    'the result was zero
    
                    testb   x,#1    wz
            if_nz   'the bit was zero
    

    Is this consistent???

    Yes, in my view it can be totally consistent:
                    and     x,#1    wz
            if_z    'the result was zero
    
                    testb   x,#1    wz
            if_nz   'the bit was clear
                                 ^^^^^
    
    In each case the flag is set. I'm going to assume that neither of us will convince the other, but as I see it, the test is not whether the bit was 1 or 0, but instead whether it was set or clear; a small but significant difference. Note that TESTB and AND are different instructions performing significantly different operations. Don't confuse TEST with TESTB.
    Cluso99 wrote: »
    And in Chip's P1 Spin Interpreter he sets the bottom 2 bits of the byte code into the flags thus...
                    test    op,#%01         wz      'get flags                          
                    test    op,#%10         wc      '(note varop requires c=1)
      if_nc_and_z   'bits=00
      if_nc_and_nz  'bits=01
      if_c_and_z    'bits=10
      if_c_and_nz   'bits=11
    

    The flags are operating the same way, but the Z flag state had to be stored inverted because of the limitation set by the TEST instruction.

    P2 code is not always the same as P1 code, however in the case of TEST it is.
    From the P1 manual:
    TEST is similar to AND except it doesn’t write a result to Value1; it performs a bitwise AND of the values in Value1 and Value2 and optionally stores the zero-result and parity of the result in the Z and C flags.
    If the WZ effect is specified, the Z flag is set (1) if Value1 AND Value2 equals zero. If the WC effect is specified, the C flag is set (1) if the result contains an odd number of high (1) bits.
    From the P2 Instruction spreadsheet:
    Test D with S. C = parity of (D & S). Z = ((D & S) == 0).
    To get Z set with TEST it is necessary to have all of the tested bits clear.
    Addit: Also note that C is not set directly here, but is a parity result.

    TESTB however is a new P2 instruction detailed as
    Test bit S[4:0] of D, write to C/Z. C/Z = D[S[4:0]].
    That is a single bit of D is copied into C or Z unchanged. This is a powerful new capability, but TEST has been left unchanged. If you prefer that approach use it!
    Cluso99 wrote: »
    In P2 we can use XBYTE which can write the LUT EXEC bits 1 and 0 to C and Z
    While I have not tested this, I expect that the Z will be reversed as
      if_nc_and_nz  'bits=00
      if_nc_and_z   'bits=01
      if_c_and_nz   'bits=10
      if_c_and_z    'bits=11
    

    Yes, that matches the P2 instruction document, plus there are also
    IF_00 'same as IF_NC_AND_NZ which has the same meaning on P1
    IF_01 'same as IF_NC_AND_Z which has the same meaning on P1
    IF_10 'same as IF_C_AND_NZ which has the same meaning on P1
    IF_11 'same as IF_C_AND_Z which has the same meaning on P1
    

    But my point is that the storing and restoring of the flags gives no distortion of the state at any point in the process. If you check bits 1 and 0 in the LUT address targeted by XBYTE you will see the flags to be loaded in their correct state not with Z inverted to account for the TEST instruction limitations.

    Regards,
    Anthony.
  • Cluso99Cluso99 Posts: 18,066
    edited 2019-03-16 06:22
    The Z flag has always meant ZERO. This goes way back to mainframe days when microprocessors were not even thought of.
    It does not matter how you view the flag as whether its set or cleared. You just test it with an IF_Z , IF_NZ, or BNZ, JNZ, etc
    Equality was an extension that when subtracted the result is considered zero, hence equal.

    As far as I am concerned, TESTB and TEST should give the same results. It is just wrong when it doesn't.
    Moving bits into flags is new for the P2, and it is inconsistent. It should have been a test like it always has been.

    FWIW I know it will not be changed, but it is most definitely wrong.
  • Cluso99Cluso99 Posts: 18,066
    Chip has extended the bit instructions to also permit a range of bits.

    So what will TESTB do with multiple bits and the Z flag???
  • Cluso99 wrote: »
    The Z flag has always meant ZERO. This goes way back to mainframe days when microprocessors were not even thought of.
    It does not matter how you view the flag as whether its set or cleared. You just test it with an IF_Z , IF_NZ, or BNZ, JNZ, etc
    Equality was an extension that when subtracted the result is considered zero, hence equal.

    As far as I am concerned, TESTB and TEST should give the same results. It is just wrong when it doesn't.
    Moving bits into flags is new for the P2, and it is inconsistent. It should have been a test like it always has been.

    FWIW I know it will not be changed, but it is most definitely wrong.

    FWIW, I also have experience that extends beyond microprocessors, having worked on mainframes that didn't even have a Z flag, but instead had distinct Compare Designators, for Equal/Unequal, Greater than or Equal/Less Than, and Outside of Limits/Within Limits. On that processor checking a register contained zero was performed by a comparison with a register hardwired to return 0. There are many ways to achieve the same outcomes, and to declare one as wrong because it varies from your experience, no matter how extensive your experience may be, is somewhat limiting for meaningful discussion.

    That said, the Z flag continues to mean ZERO; that hasn't changed.
    Direct control of the flag is what is new. Making programmers remember to store one of the flags inverted seems like unnecessary effort.

    If TEST and TESTB gave the same the results, then one of them would be superfluous.
    On the P1, TEST was an alias for AND with the NR effect specified. If you wanted to TEST a single bit in the range 10 to 31 you had to use a register to store the mask. TESTB allows copying any single bit to a flag with only an immediate for the designator (no mask necessary).

    P1 and P2 not having Sign or Overflow flags feels odd, and AND/TEST putting the parity result into C has always seemed like an unusual choice to me, but because, unlike most other processors, you can choose whether the flags are affected or not it is actually a clever idea.

    Part of what allows the Propeller chips to exist is that Chip takes a different approach to the usual.

    Maybe one of the assemblers for the P2 can allow aliasing of instructions, so that you can choose a name that let's you rationalise the behaviour of these instructions. ;-)
  • Cluso99Cluso99 Posts: 18,066
    edited 2019-03-16 09:42
    The issue is that TEST and TESTB give opposite results. TEST can test multiple bits.
    In the current ES chip TESTB can only test a single bit.
    However, Chip has implemented a bit range for the new silicon. Whether that is in the TESTB instruction I don’t know. If it is, the who knows what the instruction will do.

    BTW the mainframes did have flags. They were internal and implicit. A branch less, equal, greater were all testing these implicit flags. If you examined the circuitry you would find flipflops representing those flags. Some had a zero or equal, and maybe a less than so combined they would do less and equal. It just depended on the actual implementation. Sometimes the less than might be a negative flag.
  • evanhevanh Posts: 15,126
    edited 2019-03-16 10:37
    Round and round we go ... TEST and TESTB are not related:
    - TESTB is a bit op that, quite relevantly, equally uses C and Z. The most commonly used form is a plain bit move but I see it can also perform all four of the common logic ops with either of the specified flags. So the flags are what D is normally, and D is S and S is an extra control.
    - TEST is a somewhat stray binary longword logic op. It is functionally AND NR, but there is no counterparts for the other logic ops.
  • evanhevanh Posts: 15,126
    edited 2019-03-16 11:03
    Maybe that needs emphasised - The C and Z instruction encoding, for TESTB, means use C flag or Z flag as both ALU input and result - replacing the position D normally holds. The two flags are a convenient and accessible working space for the job of doing single-bit logic ops. And moves.
  • Cluso99 wrote: »
    The issue is that TEST and TESTB give opposite results. TEST can test multiple bits.
    In the current ES chip TESTB can only test a single bit.
    However, Chip has implemented a bit range for the new silicon. Whether that is in the TESTB instruction I don’t know. If it is, the who knows what the instruction will do.

    BTW the mainframes did have flags. They were internal and implicit. A branch less, equal, greater were all testing these implicit flags. If you examined the circuitry you would find flipflops representing those flags. Some had a zero or equal, and maybe a less than so combined they would do less and equal. It just depended on the actual implementation. Sometimes the less than might be a negative flag.

    If you had read my response carefully you would have seen that the particular mainframe I was talking about called them Compare Designators (explicit, not implicit) and none of them represented Zero, the closest was the Equal/Unequal CD.

    My point was that not every processor has a Zero flag, and that there are always many ways to achieve the same result.

    The name is what seems to be the problem here. If, instead of it being called TESTB, it were called LDFLAGS would you still be concerned about the direct load nature of the operation?
Sign In or Register to comment.