Shop OBEX P1 Docs P2 Docs Learn Events
"slaving" two Props together — Parallax Forums

"slaving" two Props together

davejamesdavejames Posts: 4,047
edited 2011-05-10 18:52 in Propeller 1
In the discussions of Prop2, I read multiple comments wishing for more cogs.

Not knowing much about the Propeller in general, I ask the question: Can two (or more) Propellers be "slaved" together and run synchronously?

Might solve the perceived lack-of-cogs if this can be done.

Comments

  • Mike GreenMike Green Posts: 23,101
    edited 2011-05-05 17:27
    You can run several Props (either I or II) from the same external clock so that part is synchronized. You can also write code that synchronizes two cogs, one on each Prop, but it's not as simple as synchronizing two cogs on the same Prop. You can't set the system clock (CNT) so there's no way to make two Props have the same CNT value, so your code has to take that into account when the two Props talk to each other. It's possible for one Prop to send its CNT to the other in such a way that the 2nd Prop can figure out the difference between the two CNTs and save that for future communications.

    The "bottom line" is that you can synchronize two Props, but it requires use of an external clock source and it's not as simple as you'd like.
  • prof_brainoprof_braino Posts: 4,313
    edited 2011-05-06 05:59
    davejames wrote: »
    In the discussions of Prop2, I read multiple comments wishing for more cogs.

    Not knowing much about the Propeller in general, I ask the question: Can two (or more) Propellers be "slaved" together and run synchronously?

    Might solve the perceived lack-of-cogs if this can be done.

    using propforth, one may connect two props using power, ground, 2 i/o lines, clock, reset, and the EEPROM input (seven wires).

    The Master prop boots from its EEPROM to propforth. The master then resets the "slave" and elumates clock for the slave, then emulates EEPROM for the slave. Each slave can have sub-slaves with no limit discovered. Each additional slave has a hardware costs of seven wires and three resistors (four wires if you are lazy and use the resistors as point to point connections).

    The communications channel runs at full clock speed and continuously sends 96-bit packets. Users plops bytes into the I/O queue and they are sent over the serial channel, so it appears as the ordinary forth prompt.

    The communications channel consumes one cog on the master and one cog on the slave. Also two I/O lines, send and receive; also the master uses one I/O line to send clock to the slave.

    The user accesses the slave cogs with the same interface as in the master, with one-time set-up for the channel. To the users, it appears that seven more cogs and twenty eight pins have been added. There is no noticeable difference in the interactive user interface. Of course, the user must take care that application that need to happen FAST do not have to cross the inter-prop channel, but we have never encountered a problem with this yet. If we are lucky, we might create an application that is limited in this way before the prop2 comes out, but this is unlikely.

    http://code.google.com/p/propforth/wiki/PropForth4SetupAndTest
    search "High Speed Synchronous Serial channel"

    If you don't like using forth (most consider forth to be cheating because its too easy :) ), the code for the high speed serial can be optimized to assembler and use in for example spin programs. But I don't know of anyone who has done this yet.

    The instructions are a bit lacking since few people have tried them, PM me or open a thread for help. I will update the instructions as better descriptions come available.
  • HalcyonDazeHalcyonDaze Posts: 17
    edited 2011-05-06 06:02
    Ran into this on another project Im working on. So to expand the question a bit: What are the drawbacks/limitations of two props communicating that do not have the same CNT value? If I wanted to set up one prop to send its CNT to the other, how long is that saved value valid before it needs to re-send and calculate? Can it be done using normal communcation protocols, or does it require wiring to the clock pins? Is it a predetermined master/slave relationship, or can it be done bi-directionally?

    My goal ultimately is to sync a single communication cog on several props in a ring, so that each prop has a snapshot (and bridge) to the others by updating a shared profile and mirroring it onto the others. I am however new to dealing with clock speed at this level, so I am uncertain what level of synchronicity this will require. For that matter, Im not all that clear on the difference in functionality of an internal vs external clock source, or a shared clock source vs discrete ones for each chip/cog/etc.
  • prof_brainoprof_braino Posts: 4,313
    edited 2011-05-06 06:08
    Mike Green wrote: »
    The "bottom line" is that you can synchronize two Props, but it requires use of an external clock source and it's not as simple as you'd like.

    I avoid disagreing with people smarter than me, but think I must disgree here. Its actually MUCH easier using an appropriate configuration: When master prop send clock to the slave, both props are IDENTICALLY synchronized by nature of the hardware setup, for free. There may be other factors that I don't know about (my experience is limited) but we have not seen a dropped bit in the sync serial except during testing when we pulled the wire.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-05-06 07:04
    It depends on what you call "synchronization". There's one level of synchronization accomplished by having the Props use the same clock. That way their system clocks advance simultaneously and they go through the various phases of instruction execution at the same time. The second level is for all the Props to "know" the same time. Within a Prop, there's a single clock (CNT) that the cogs can use for reference in synchronizing their actions (using WAITCNT). When you have more than one Prop, they each have a separate system clock that's read-only and has an uncontrollable initial value. One Prop has to send its system clock value to all other Props in such a way that they all know exactly how much time is spent sending the clock value (not hard, but requires care). The result is that all Props have a system clock adjustment value that they can store. Any time two cogs need to do something at the same time, they can adjust the time so it's relative to the local clock, then use WAITCNT to wait for that time.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2011-05-06 07:31
    ...So for syncing the Counter,it might go something like this.

    1) Master sends its current Counter value to a slave

    2) Slave Sends the difference of it's counter value back to the Master (call it Counter Delta)

    3) Master sends its current Counter value plus the Counter Delta back to a Slave.

    4) At this point the slave Counter should match what the Master just sent in #3. If not, incremental adjustments are made to the Counter Delta until the values are locked.

    5) Once locked, either the Master or the Slave (not both) reference the Counter Delta when counter sync operations are necessary.

    Note: #1 to #4 could be a reiterative loop, since #1 and #3 could be the same code (Assuming that Delta counter on the Master starts out as Zero)
  • LeonLeon Posts: 7,620
    edited 2011-05-06 07:44
    Will deterministic operation be available, with the two chips communicating like that, as it is with those other parallel-processing chips?
  • Mike GreenMike Green Posts: 23,101
    edited 2011-05-06 07:45
    You don't need to send the counter back and forth because the two Props are running off the same clock. What you have to do is write your code (for both Props) so you know exactly what time it is throughout the interaction. The Master Prop fetches the CNT value, encodes it somehow, and transmits it serially (maybe using SPI) to the Slave Prop. The Slave has to know how much time elapses from the time the Master reads CNT so it can adjust the received value. The Slave also needs to know how much time has elapsed since the transmission has begun. The net result should be the difference between the two CNTs. Once that's known, the two Props are in lock-step.

    You could then have code running on either Prop that sends a future system-wide time to a cog on either Prop that the two cogs can, after adjusting for the local CNT, use in a WAITCNT. The two cogs will emerge from their WAITCNTs at the same time regardless of which Prop they're running in. Because the Props are running off the same external clock, they're in lockstep, completely deterministic.
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2011-05-06 07:48
    I was trying to compensate for propagation delay, not only in length of wire between Propellers, but just within the Propellers themselves. ... Thus the back and forth negotiation.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-05-06 08:01
    Since the resolution of the system clock (CNT) is one clock cycle, there's no way to handle finer synchronization other than manually "tuning" the clock distribution network
  • davejamesdavejames Posts: 4,047
    edited 2011-05-06 08:33
    ...well, thank you all for the feedback. I didn't realize my question would stimulate such an in-depth discussion.

    Maybe those that know the Propeller intimately could devise, proove, and document a method that would make this effort easier (subjective) for other members?

    Regards and thanks again for the technical insight,

    DJ
  • BaggersBaggers Posts: 3,019
    edited 2011-05-06 09:39
    Hi guys,

    You may or may not know that I've currently been working on getting two independent props ( on the same clock ) to work together synchronised.

    Now, the problems that you come across is way before you even get to run your first instruction. because the fact of the matter is...
    The program gets read off the i2C EEPROM using the internal RC clock, which is unfortunately, not very accurate, so what happens is...
    Not only do both your props not execute the first instruction at different times, but they also have a different HUB-OP round robin placement, as Round Robin slot 0 on prop 1 could be Round Robin slot x on Prop 2

    I've got some more free time next week over the weekend, so hope to get the sync working on every reset for my DuoGFX project.
  • Clock LoopClock Loop Posts: 2,069
    edited 2011-05-08 21:05
    My goal ultimately is to sync a single communication cog on several props in a ring, so that each prop has a snapshot (and bridge) to the others by updating a shared profile and mirroring it onto the others. I am however new to dealing with clock speed at this level, so I am uncertain what level of synchronicity this will require. For that matter, Im not all that clear on the difference in functionality of an internal vs external clock source, or a shared clock source vs discrete ones for each chip/cog/etc.



    All this is basically done.

    A master - slave framework, in spin, done with very minimal components, shows how to set up a multipropeller network operating on the same clock frequency source,

    The link shows 55 propeller DIP chips wired to eachother. 1 chip acts as a master with an eeprom, the other chips are programmed through the rx/tx lines PARALLEL.

    The amount of time to program 100 props like this is the same as programming a single prop. Very fast.

    The program and circuit attached show how to set up a communication network between all 55 props using only the TX and RX lines, (this requires order, or bad things happen on two lines with 55 props,)

    Order is achieved by running a random number generator on each prop. It happens that each prop does indeed randomly generate a number the size of your variable.

    http://forums.parallax.com/showthread.php?127983-55-Parallax-Propeller-s-Parallells-Processing-of-Permanent-Perturbations.
  • HalcyonDazeHalcyonDaze Posts: 17
    edited 2011-05-09 08:42
    Clock Loop wrote: »
    All this is basically done.

    A master - slave framework, in spin, done with very minimal components, shows how to set up a multipropeller network operating on the same clock frequency source,

    The link shows 55 propeller DIP chips wired to eachother. 1 chip acts as a master with an eeprom, the other chips are programmed through the rx/tx lines PARALLEL.

    The amount of time to program 100 props like this is the same as programming a single prop. Very fast.

    The program and circuit attached show how to set up a communication network between all 55 props using only the TX and RX lines, (this requires order, or bad things happen on two lines with 55 props,)

    Order is achieved by running a random number generator on each prop. It happens that each prop does indeed randomly generate a number the size of your variable.

    http://forums.parallax.com/showthread.php?127983-55-Parallax-Propeller-s-Parallells-Processing-of-Permanent-Perturbations.
    Thats a pretty slick implementation. Unfortunately my project needs to have a uniform hardware profile for all props, and cannot have a Master/Slave configuration unless it could re-assign the master role on the fly.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-09 09:42
    In order to synchronize two cogs on separate Propellers, after you have determined the difference in the system counters, on the first Propeller do a RDLONG, followed immediately by reading the CNT register, send this value to the second Prop, the second Prop then compensates the value for the known difference between the two system counters, preforms a RDLONG fallowed immediately by a read of CNT, compensates for the difference, loops subtracting 16 from the adjusted value it read from CNT above until the value becomes less than that of that of the value sent it and then determines the difference, then the current cog on Prop minus ((calculated_difference >> 1) & 0x7) is the cog that is in sync (with an error of up to one clock cycle).
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-09 09:52
    I made an error above (still writing this post):
    Where I said "(2 * calculated_difference & 0x7)" should read:
    ((calculated_difference >> 1) & 0x7).
  • jazzedjazzed Posts: 11,803
    edited 2011-05-09 09:55
    In order to synchronize two cogs on separate Propellers, after you have determined the difference in the system counters, on the first Propeller do a RDLONG, followed immediately by reading the CNT register, send this value to the second Prop ...
    @davidsaunders, you should probably post a known working and reliable example. Your hypothesis is probably subject to change. It is possible to sync things to a number, but even with that there will be minor differences in the phase of independent crystals. Even with a slaved and buffered crystal clock there are certain complications if all propellers including the master boot simultaneously.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-09 09:57
    Jazzed:
    The algorithm I outlined above is what I already use, assuming that both Props are running off the same crystal, it works great.

    And as I said there is a possible error of 1 clock cycle.
  • kuronekokuroneko Posts: 3,623
    edited 2011-05-09 17:04
    The algorithm I outlined above is what I already use, assuming that both Props are running off the same crystal, it works great.
    Please enlighten me/us. For simplicity's sake let's say the system counters are in sync. Prop 0 cog N gives me $539A7661, prop 1 cog M reports $539A9AB7. What does that tell us?
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-09 17:14
    That would mean that if the cog on being used to test on both props is cog 0, that Cog (0-3) = cog 5 on Prop 1 is within one clock of correct sync to cog 0 on prop 0.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-09 17:14
    Kuroneko:
    Please we know you can fallow a simple algorithm (the great work you show on the forums proves this).
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-09 17:19
    Sorry that actually means that assuming cog 0 to test on both Props, a shared crystal and the same clock mode, that cog 0 on prop 0 is in perfect sync with cog 5 of Prop 1, as far as hub access goes.
  • kuronekokuroneko Posts: 3,623
    edited 2011-05-09 17:31
    Sorry that actually means that assuming cog 0 to test on both Props, a shared crystal and the same clock mode, that cog 0 on prop 0 is in perfect sync with cog 5 of Prop 1, as far as hub access goes.
    OK, at least we are on the same page as far as the result is concerned. It's just that I would have worded it differently.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-09 20:50
    A little better explanation of the above algorithm:
            and sncval,#$0F
            rdlong tmmp02,#0
            mov tmp01,cnt
            and tmp01,#$F
            sub sncval,tmp01  NR,WC,WZ
      if_a  sub sncval,tmp01
      if_be sub tmp01,sncval
      if_be mov sncval,tmp01
            shr sncval,#1
      if_a  mov snccog,#8
      if_be mov snccog,#0
      if_a  sub snccog,sncval
      if_be add snccog,sncval
              and snccog,#7
    
  • kuronekokuroneko Posts: 3,623
    edited 2011-05-10 01:21
    and sncval,#$0F
            rdlong tmmp02[COLOR="blue"],#0[/COLOR]
            mov tmp01,cnt
            and tmp01,#$F
            sub sncval,tmp01  NR,WC,WZ
      if_a  sub sncval,tmp01
      if_be sub tmp01,sncval
      if_be mov sncval,[COLOR="blue"]pmt01[/COLOR]
            shr sncval,#1
      if_a  mov snccog,#8
      if_be mov snccog,#0
      if_a  sub snccog,sncval
      if_be add snccog,sncval
            and snccog,#7
    
    I'm assuming for a moment that pmt01 is a typo and should read tmp01. Feeding 16 (adjusted) remote cnt values ($xxxx_xxx0-$xxxx_xxxF) into this fragment gives me 3 times cog 0 as an answer. Which - I dare say - is wrong. Here is my version which expects the (adjusted) remote cnt value of cog 0 (in time) and tells you which cog the current one (running this fragment) is in sync with.
    cogid   $ nr
            sub     time, cnt
            shr     time, #1
            neg     time, time
            and     time, #7
    
    I'm prepared to accept David's code as design decision but consider the following
    • adjusted remote cnt ends in 5
    • local cog N running the code with cnt ending in 4
    • local cog N+1 running the code with cnt ending in 4+2 = 6
    • now both cogs get remote cog 0 assigned as their sync partner
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-10 08:29
    Sorry about that. I was half asleep, not paying attention when I looked for the code fragment, I guess I posted an earlier version. Will look for the correct one. I mark my code using extended Parallax font characters (which do not show in a text editor that converts to 7-bit ASCII), and with out a working BST I am having difficulty reading my own comments.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-10 09:37
    kuroneko:
    I just ran your scenario through the above code (that is only run on COG 0 of the secondary Prop [all other cogs are assigned relative to this], and is intended to find the cog synced with COG 0 on the main Prop), and your scenario gave COG 0 on Prop 0 equals COG 0 on Prop 1 (which is the situation that brings you of by 1 clock cycle [because Hub Windows are 2 Cycles long]), and since the other cogs are given relative to the value calculated by this routine, you end up with "COG + 1" of Prop 1 (which is COG 1, as this code is only run on COG 0 of Prop 1), being assigned as synced to COG 1 of Prop 0.

    Also I corrected the two typos, above.
  • davidsaundersdavidsaunders Posts: 1,559
    edited 2011-05-10 09:51
    If any knows at what clock during the Op execution Pins are written and read, a much easier method would be to simply flip a pin high on Prop 0, and read it on Prop 1, (using the CNT to determine which cog is in best hub sync [If I am not mistaken hub 0 is always in sync with modulo 16 of the local CNT register (will have to test this for sure), this should simplify things a bit]).
  • kuronekokuroneko Posts: 3,623
    edited 2011-05-10 18:52
    I just ran your scenario through the above code ...
    Yes, that was an escape clause I considered to avoid the issue. Figure out one pairing and base everything else on that one. I had to make an assumption here as to how you derive the other pairings (if necessary).
Sign In or Register to comment.