Can HUB timing be deterministic?
Beau Schwabe
Posts: 6,574
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
