Shop OBEX P1 Docs P2 Docs Learn Events
How to watipeq efficiently with multiple changing inputs — Parallax Forums

How to watipeq efficiently with multiple changing inputs

The inputs I wait to wait for change simultaneously and sometimes waitpeq it gives false positives.

How to do what watipeq does, without false positives and with minimum latency on matching inputs?

Comments

  • kwinnkwinn Posts: 8,697
    If the inputs
    byrtolet wrote: »
    The inputs I wait to wait for change simultaneously and sometimes waitpeq it gives false positives.

    How to do what watipeq does, without false positives and with minimum latency on matching inputs?

    How fast are the input signals changing? It may be that your inputs are not quite simultaneous due to differences in impedances, capacitance, length of signal lines, etc. If that is the case a second waitpeq may be needed.

    For Spin:

    ((PUB ┆ PRI))
    WAITPEQ (State, Mask, Port)

    State is the logic state(s) to compare the pin(s) against. It is a 32-bit value that
    indicates the high or low states of up to 32 I/O pins. State is compared against either
    ( INA & Mask), or ( INB & Mask), depending on Port.
    Mask is the desired pin(s) to monitor. Mask is a 32-bit value that contains high (1)
    bits for every I/O pin that should be monitored; low (0) bits indicate pins that should
    be ignored. Mask is bitwised-ANDed with the 32-bit port’s input states and the
    resulting value is compared against the entire State value.
    Port is a 1-bit value indicating the I/O port to monitor; 0 = Port A, 1 = Port B. Only
    Port A exists on current (P8X32A) Propeller chips.


    For Assembly:

    Instruction: Pause a cog’s execution until I/O pin(s) match designated state(s).

    WAITPEQ State, (#) Mask

    State (d-field) is the register with the target state(s) to compare against IN x ANDed
    with Mask.
    Mask (s-field) is the register or a 9-bit literal whose value is bitwise ANDed with IN x
    before the comparison with State.

  • byrtolet wrote: »
    ...without false positives and with minimum latency on matching inputs?
    If there is 'any' possibility that the two inputs might occur on the same clock then you have a separate cog for each input.
  • ErNaErNa Posts: 1,738
    byrtolet wrote: »
    The inputs I wait to wait for change simultaneously and sometimes waitpeq it gives false positives.

    How to do what watipeq does, without false positives and with minimum latency on matching inputs?

    The question is not asked precisely enough to be answered. "I wait to wait" means "I'm am waiting to wait." If you wait, you can not wait to wait and if you are not waiting, you can not wait to wait.
    "Simultaneous" is not defined by definition, As two events happen at the same time at the same place establish one event and two events happening at the same time at different points happen at the same time only for an observer while for another observer the same events happen at different times.

    If you look for something that does what waitpeg does but without false positives, you look for something that does thing different from waitpeq, as waitpeq creates "false positives" in contrast to what you are looking for.

    So this is what is meant when there is the saying: a computer always does, what you say to him, never what you meant to say.
  • Consider using WAITPNE rather than WAITPEQ when there are multiple inputs. The two forms behave in rather different ways, the former being good for detecting when one or more inputs change, and the latter for detecting when a group of inputs coalesce into a target state. Leaving a state vs entering a state if you will.

    It is not clear precisely what you need to accomplish. An example would help, especially about pulse widths and timings.

  • Do you have noise on the inputs?
    Do you need pull-up, pull down?
    Is the grounding efficient ?
    Is there cross over?


  • ErNaErNa Posts: 1,738
    Ltech, the questions you ask are, as I would like to see the problem, of no relevance. To me it looks, the word "simultaneously" is not understood correctly. A processor is clocked and samples value at the input pins. The bits latched represent the values of the input pins at the moment of latching, independently of how the values are defined. And as they are latched at clock rate, the bits not only reflect the inputs at the moment of latching, but for the duration of the clock period. Byrtolet has to decribe his task (his problem, respectively) more precisely. Only then the community can help.
  • I have 16 bit address bus driven from 6502 cpu.
    what I need is to wait until particular address is output on the bus.

    The problem is that while the bus changes its address, the propeller might sample it right during the transition, giving an input which is not an address actually put by the 6502.
    For example on once 6502 cycle one might have 0xffff on the address bus, and on the next 0x0000.
    During the transition between the two, propeller might read anything.
    What I need is a stable input (at least two consecutive reads to read the same value)
    What have at the moment (in c pseudocode)
    while(true)
    {
      waitpeq(lookfor_addres, address_mask)
      if ( (INA & address_mask) != lookfor_address))
        continue;
    // react to this particular address
    }
    
    While this works I'm seeking for a solution with lower latency (in my example I have an extra latency of an input read, binary AND, comparison and conditional jump.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2019-10-07 03:56
    Isn't there an address or R/W strobe that you could include in your waitpeq? That would ensure that all the address lines have settled.

    -Phil
  • Cluso99Cluso99 Posts: 18,066
    You need to synchronise with the phase 2 IIRC.
  • A simple PASM routine running in its own cog could check and recheck the address bus, and communicate a stable match to the main cog via a spare pin or via a lock.
  • ErNaErNa Posts: 1,738
    I did a google search for "6502 cpu datasheet" and found this Page 12 shows the timing diagram and as usual, there are signals that show, that the address and data bits are valid. I do not think, that valid data can be extracted from the address bits only. Anyway, watching the sync signal should do the job.
  • In principle one can use phi2 signal to synchronize,
    the problem is that the addresses are valid long before phi2 is high, and some time after phi2 becomes low, so just including phi2 in the waitpeq will not do (remember, I need the valid address as soon as possible).

    One could wait for phi2 to become high, then wait for it to become low, wait a little and read inputs, but then it still has to do the check if the address is the desired one.
    And moreover, after the "react for particular address" part, all that waiting might miss another desired address.
  • The 6502's timing is pretty leisurely compared to that of the Prop. So I'm not sure what the problem would be just to wait for the φ2 signal to go high to capture the address. You've got plenty of time after that to do with it what you need to. I really think that's your only chance to guarantee an accurate address read.

    -Phil
  • A simple PASM routine running in its own cog could check and recheck the address bus, and communicate a stable match to the main cog via a spare pin or via a lock.

    Unfortunately I can't afford to waste a cog and beside that, the communication would just add latency.
  • The 6502's timing is pretty leisurely compared to that of the Prop. So I'm not sure what the problem would be just to wait for the φ2 signal to go high to capture the address. You've got plenty of time after that to do with it what you need to. I really think that's your only chance to guarantee an accurate address read.

    -Phil

    Phil, I disagree. If you have 1Mhz 6502 & 80 Mhz propeller you have 20 instructions per 6502 clock. If one accesses the hub you have even less. If the Phi2 duty cicle is 50% (which is not in my use case) you have 10 instructions.
  • ErNaErNa Posts: 1,738
    edited 2019-10-08 12:13
    I would use a wait on the adress valid pin and next cmp with jmp backward
    loop:
      wait for address not valid
      wait for address valid
      cmp ina to pattern with zero
      jmp nz loop:
      
      PROCESS DATA
    
  • Wuerfel_21Wuerfel_21 Posts: 4,374
    edited 2019-10-08 13:15
    Have you considered pulling down the 6502's RDY pin when your address is matched to make it wait an additional cycle for your data?
  • Wuerfel_21 wrote: »
    Have you considered pulling down the 6502's RDY pin when your address is matched to make it wait an additional cycle for your data?

    I don't have access to the RDY pin.
  • ErNa wrote: »
    I would use a wait on the adress valid pin and next cmp with jmp backward
    loop:
      wait for address not valid
      wait for address valid
      cmp ina to pattern with zero
      jmp nz loop:
      
      PROCESS DATA
    
    There's no address valid pin per se. And while it's possible to wait for the falling edge of PHI2 and then check the address after a fixed amount of time, I'm afraid to skip some 6502 clocks while doing so.
  • byrtolet wrote: »
    ErNa wrote: »
    I would use a wait on the adress valid pin and next cmp with jmp backward
    loop:
      wait for address not valid
      wait for address valid
      cmp ina to pattern with zero
      jmp nz loop:
      
      PROCESS DATA
    
    There's no address valid pin per se. And while it's possible to wait for the falling edge of PHI2 and then check the address after a fixed amount of time, I'm afraid to skip some 6502 clocks while doing so.

    If you are using a 1MHz 6502, from the Rockwell datasheet you a at most 225ns to wait for the address to be valid, which is less than two instructions of the Propeller at 80MHz. As long as you are only looking for a specific address or well-behaved range of addresses (e.g. $FFF0 to $FFFF), requiring only one or two comparisons, and save any hub access for after the address match you should easily be able perform your matching within 20 instructions.

    Another salient point is whether you are simply triggering propeller actions on address matches, or whether you need to interact on the data bus as well.

    If the required reaction time includes reading data from or putting data onto the data bus you have around 7 and 4 instructions respectively to do so.
    Given that a 6502 can only meaningfully access the data bus for a data transfer every 2 or 3 cycles you have some time to do your hub access during the following 6502 instruction fetches.

    If you are trying to have the propeller feed instructions to the 6502 then you really also need control of the 6502 clock to be exercised from the propeller.
  • AJL wrote: »
    If you are using a 1MHz 6502, from the Rockwell datasheet you a at most 225ns to wait for the address to be valid, which is less than two instructions of the Propeller at 80MHz. As long as you are only looking for a specific address or well-behaved range of addresses (e.g. $FFF0 to $FFFF), requiring only one or two comparisons, and save any hub access for after the address match you should easily be able perform your matching within 20 instructions.

    Another salient point is whether you are simply triggering propeller actions on address matches, or whether you need to interact on the data bus as well.

    If the required reaction time includes reading data from or putting data onto the data bus you have around 7 and 4 instructions respectively to do so.
    Given that a 6502 can only meaningfully access the data bus for a data transfer every 2 or 3 cycles you have some time to do your hub access during the following 6502 instruction fetches.

    If you are trying to have the propeller feed instructions to the 6502 then you really also need control of the 6502 clock to be exercised from the propeller.

    I can actually feed 6502 instructions quite reliably (it takes a cog). The problem is that I have ran out of cogs, and in the last cog I must decode 6502 address on 6502's write cycle, and depending of the written bits set two longs in the hub. And beside that, on another address copy the written value. I even have a code that works sometimes, but only sometimes.
  • jmgjmg Posts: 15,140
    .
    byrtolet wrote: »
    I can actually feed 6502 instructions quite reliably (it takes a cog). The problem is that I have ran out of cogs, and in the last cog I must decode 6502 address on 6502's write cycle, and depending of the written bits set two longs in the hub. And beside that, on another address copy the written value. I even have a code that works sometimes, but only sometimes.
    Do you have the clocks all locked ? - ie derive the 6502 clock from the P1 PLL ?

  • jmg wrote: »
    .
    byrtolet wrote: »
    I can actually feed 6502 instructions quite reliably (it takes a cog). The problem is that I have ran out of cogs, and in the last cog I must decode 6502 address on 6502's write cycle, and depending of the written bits set two longs in the hub. And beside that, on another address copy the written value. I even have a code that works sometimes, but only sometimes.
    Do you have the clocks all locked ? - ie derive the 6502 clock from the P1 PLL ?

    No.
Sign In or Register to comment.