Can HUB timing be deterministic?
Beau Schwabe
Posts: 6,568
The HUB instructions appear to be indeterminate, but really they are not.· The timing of each HUB instruction is affected by the relation between the moment it is reached and the start of the next HUB access window.· Instructions executed prior to the HUB instruction can shift the coincidence of these two events over the course of the applications execution.· Think about this, when a COG starts it is basically a HUB operation, this means that at the beginning of the COG assembly program or 'org 0' the COG has completed a HUB access window, so a reference point can be derived from there.
ALL of the HUB instructions take 7 system clocks to execute, but they can only execute every 16 system clocks.· What throws the deterministic timing off is the 7 clocks vs. the normal 4 clocks.· If you are aware of this and pay close attention to what is happening (a scope helps), then you can achieve deterministic timing results.· Page 24 and 25 of the Propeller Manual goes over this concept in some detail.
Try this code...
..At first glance, you would expect it to toggle pin #0 every 300nS, but instead it does it every 200nS.· Why?· Because of the HUB instruction.· The HUB instruction is complete after 7 Clocks, but must wait for the next HUB access to come around which will be in another 9 Clocks meanwhile two instructions that normally require 4 Clocks can execute within the 9 Clock waiting period, sort of "under the hood", and still have 1 clock left over.
Now, look at this code...
...The only difference is the addition of a nop instruction just before the jmp.·· With this example it takes 400nS to toggle pin #0 !!· Why twice as long when you add an instruction that only requires 50nS?· By increasing the total number of clocks after the HUB instruction from 8 to 12, you are now outside of the 9 clock window, and so the HUB instruction was missed.· As a result it has to wait for the next HUB window 16 clocks later before it can execute.· A total of 19 Clocks after the HUB instruction instead of 9.... (3 Clocks over the 9 Clock window plus 16 more system clocks = 19 Clocks).· Consequently, you could add a second nop instruction and still have an output pulse that toggles every 400nS since you must wait a total of 19 clocks anyway... ...an xor,2 nop's, and a jmp only occupy 16 clocks.
Here is another example that shows two pulses in a one-shot fashion· - Set Scope to "Single Trigger" mode
Signal Characteristics:
HIGH - 150nS
·LOW - 50nS
HIGH - 150nS
·LOW - Steady
By placing additional 'nop' instructions at the top of this program example, you can visually see on a scope, how this interaction relates to the HUB instructions by noting the width changes
of the first pulse caused by the·"indeterminate" HUB operation.· ...But as you can see·in this example, you can·determine the initial behavior of a HUB instruction.· Additionally, something else to note.· As long as the program remains the same between the two HUB instructions, the second pulse will always remain at a fixed width of 150nS.· This is because regardless of where the first HUB operation occurred, or what happens above it in code, the first HUB operation·SYNCs with·the HUB access window.· In doing so the second HUB operation is also synced... based on the instructions following the first HUB operation, and instructions prior to the second HUB operation.
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Post Edited (Beau Schwabe (Parallax)) : 11/30/2007 8:52:47 PM GMT
ALL of the HUB instructions take 7 system clocks to execute, but they can only execute every 16 system clocks.· What throws the deterministic timing off is the 7 clocks vs. the normal 4 clocks.· If you are aware of this and pay close attention to what is happening (a scope helps), then you can achieve deterministic timing results.· Page 24 and 25 of the Propeller Manual goes over this concept in some detail.
Try this code...
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 PUB AsmTestRun cognew(@AsmTest,0) DAT AsmTest org 0 mov t1, #1 shl t1, #0 'Pin Number or dira, t1 'Make Pin an Output Toggle rdlong t2, #0 '7 Clocks, but can only execute every 16 Clocks (200nS) xor outa, t1 '4 Clocks (50nS) jmp #Toggle '4 Clocks (50nS) t1 long 0 t2 long 0
..At first glance, you would expect it to toggle pin #0 every 300nS, but instead it does it every 200nS.· Why?· Because of the HUB instruction.· The HUB instruction is complete after 7 Clocks, but must wait for the next HUB access to come around which will be in another 9 Clocks meanwhile two instructions that normally require 4 Clocks can execute within the 9 Clock waiting period, sort of "under the hood", and still have 1 clock left over.
Now, look at this code...
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 PUB AsmTestRun cognew(@AsmTest,0) DAT AsmTest org 0 mov t1, #1 shl t1, #0 'Pin Number or dira, t1 'Make Pin an Output Toggle rdlong t2, #0 '7 Clocks, but can only execute every 16 Clocks (200nS) xor outa, t1 '4 Clocks (50nS) nop '4 Clocks (50nS) jmp #Toggle '4 Clocks (50nS) t1 long 0 t2 long 0
...The only difference is the addition of a nop instruction just before the jmp.·· With this example it takes 400nS to toggle pin #0 !!· Why twice as long when you add an instruction that only requires 50nS?· By increasing the total number of clocks after the HUB instruction from 8 to 12, you are now outside of the 9 clock window, and so the HUB instruction was missed.· As a result it has to wait for the next HUB window 16 clocks later before it can execute.· A total of 19 Clocks after the HUB instruction instead of 9.... (3 Clocks over the 9 Clock window plus 16 more system clocks = 19 Clocks).· Consequently, you could add a second nop instruction and still have an output pulse that toggles every 400nS since you must wait a total of 19 clocks anyway... ...an xor,2 nop's, and a jmp only occupy 16 clocks.
Here is another example that shows two pulses in a one-shot fashion· - Set Scope to "Single Trigger" mode
Signal Characteristics:
HIGH - 150nS
·LOW - 50nS
HIGH - 150nS
·LOW - Steady
CON _clkmode = xtal1 + pll16x _xinfreq = 5_000_000 PUB AsmTestRun cognew(@AsmTest,0) DAT AsmTest org 0 'Initial HUB window access Boundary nop 'By the time that a "HUB SYNC" and COG are loaded and begin to 'execute code, the 16 Clock HUB Boundary has a remainder of 11 'Clocks. Adding a 'nop' instruction here adds another 4 clocks 'to the 11 and places us on the edge of the 16 Clock HUB Boundary... '...at Clock number 15 actually. '16 Clock HUB Boundary mov t1, #1 '4 Clocks shl t1, #0 '4 Clocks Pin Number or dira, t1 '4 Clocks Make Pin an Output or outa, t1 '4 Clocks Make Pin HIGH '16 Clock HUB Boundary 'because we are off by 1 clock, the rdlong command 'requires 8 total clocks to complete. 1 to wait for 'the HUB operation, and the other for the 7 clocks 'required to carry out the HUB instruction rdlong t2, #0 '7 Clocks <- HUB access available here after 1 system clock. andn outa, t1 '4 Clocks under the Hood of the HUB instruction ; Make Pin LOW or outa, t1 '4 Clocks under the Hood of the HUB instruction ; Make Pin HIGH 'Since the HUB instruction takes 7 Clocks and another 'HUB operation can't happen again for another 9 Clocks 'we can fit two non HUB operations under the Hood as indicated 'above, and still have 1 Clock left over. '16 Clock HUB Boundary 'Since we are off by 1 clock again, the rdlong command 'will require 8 total clocks to complete. same as above 'the first time around. rdlong t2, #0 '7 Clocks <- HUB access available here after 1 system clock. andn outa, t1 '4 Clocks under the Hood of the HUB instruction ; Make Pin LOW nop '4 Clocks under the Hood of the HUB instruction ; Do Nothing '16 Clock HUB Boundary NoEnd jmp #NoEnd 'Keep COG alive t1 long 0 t2 long 0
By placing additional 'nop' instructions at the top of this program example, you can visually see on a scope, how this interaction relates to the HUB instructions by noting the width changes
of the first pulse caused by the·"indeterminate" HUB operation.· ...But as you can see·in this example, you can·determine the initial behavior of a HUB instruction.· Additionally, something else to note.· As long as the program remains the same between the two HUB instructions, the second pulse will always remain at a fixed width of 150nS.· This is because regardless of where the first HUB operation occurred, or what happens above it in code, the first HUB operation·SYNCs with·the HUB access window.· In doing so the second HUB operation is also synced... based on the instructions following the first HUB operation, and instructions prior to the second HUB operation.
·
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Beau Schwabe
IC Layout Engineer
Parallax, Inc.
Post Edited (Beau Schwabe (Parallax)) : 11/30/2007 8:52:47 PM GMT