copying HUB memory to COG memory

I have an application that runs several assembly tasks in different cogs. One cog gets data via the input pins, puts together a 32-bit sample (long) and writes it to an array (50 longs = 200 bytes) in HUB memory. I've verified that this works correctly.
What I now need to do is use a separate cog to grab all 50 longs and bring them into COG memory for further manipulation. After reading around A LOT on this it seems I need to use self-modifying code. I've put together the following snippet based on Mike Green's example in this thread:
http://forums.parallax.com/showthread.php?p=608701
Although I'm sure Mike's post works, I still didn't follow completely. This seems to be a VERY important topic. One which I'll need to understand for complex and time critical Prop applications. Many folks seem to get this already and I am hoping some of them would comment on the following code.
Thanks,
pgbpsu
What I want to do in words:
Copy 50 longs (200 bytes) of HUB memory into COG memory and store it under the symbol cog_mem
1. set loop counter to 50
2. store starting address of hub memory to local variable (hub_index)
3. store starting address of cog memory to local variable (cog_index)
4. set destination field of future rdlong command to cog memory address where I'd like the data stored (cog_index)
5. use rdlong to get the 32 bits pointed at by hub_index and store it in cog memory at cog_index
6. increment the address of the hub data (hub_index) for next read
7. increment the address of the cog data (cog_index) for next read
8. repeat until all 50 longs have been copied
What I now need to do is use a separate cog to grab all 50 longs and bring them into COG memory for further manipulation. After reading around A LOT on this it seems I need to use self-modifying code. I've put together the following snippet based on Mike Green's example in this thread:
http://forums.parallax.com/showthread.php?p=608701
Although I'm sure Mike's post works, I still didn't follow completely. This seems to be a VERY important topic. One which I'll need to understand for complex and time critical Prop applications. Many folks seem to get this already and I am hoping some of them would comment on the following code.
Thanks,
pgbpsu
What I want to do in words:
Copy 50 longs (200 bytes) of HUB memory into COG memory and store it under the symbol cog_mem
1. set loop counter to 50
2. store starting address of hub memory to local variable (hub_index)
3. store starting address of cog memory to local variable (cog_index)
4. set destination field of future rdlong command to cog memory address where I'd like the data stored (cog_index)
5. use rdlong to get the 32 bits pointed at by hub_index and store it in cog memory at cog_index
6. increment the address of the hub data (hub_index) for next read
7. increment the address of the cog data (cog_index) for next read
8. repeat until all 50 longs have been copied
VAR long Shared[noparse][[/noparse]50] ' 200 bytes that are shared amoung the cogs PUB Main cognew(@entry,@Shared) 'Launch new cog to read HUB memory into COG memory DAT { Read data from HUB memory, store in COG memory } entry ORG 0 mov addr, PAR ' address of first byte in HUB RAM mov samples_left, #50 ' set number of samples to copy mov hub_index, addr ' set hub_index = address of HUM RAM copy2cog mov cog_index, #cog_mem ' set cog_index = address of cog_mem movd rdlong_dest, cog_index ' set destination of rdlong command to cog_index rdlong_dest rdlong 0-0, hub_index ' rdlong HUB_MEMORY[noparse][[/noparse]hub_index]; ' store in COG_MEM[noparse][[/noparse]cog_index] add hub_index, #4 ' set hub_index to next long in HUB memory add cog_index, #1 ' set cog_index to next long in cog memory djnz samples_left, #copy2cog ' decrement samples_left, jump back to copy2cog ' DATA NOW IN COG MEMORY ' DO OTHER THINGS 'VARIABLES samples_left res 1 ' number of samples left to copy to cog hub_index res 1 ' pointer to location in hub memory cog_index res 1 ' pointer to location in cog memory cog_mem res 50 ' storage for data copied over from HUB FIT 496
Comments
http://forums.parallax.com/showthread.php?p=668559
Post Edited (deSilva) : 1/23/2008 10:31:47 PM GMT
I thought deSilva would say more
Note the two changes:
1. An delay is required between modifying an instruction and then using it
2. Your djnz jump location will result in all the longs being written to the first location of·cog_mem
you must be referring to ex07C
In fact, that's where I began, and realized that there was a way to solve my problem. However, I didn't follow it fully so I started searching the forums for "self-modifying code" and reading the prop manual re: MOVS, MOVD, MOVI. I still wasn't comfortable enough with this concept to take what you did (which is close to what I want) and turn it into working code for something slightly different. But I'm starting to get my head around this slowly with the help of the many great people, like you, here on this forum.
mirror-
Thanks for pointing out my mistakes. I certainly don't want to copy every element from HUB ram into a single location in COG ram. How do you know that the nop is necessary? I believe you, but don't recall seeing that in the manual.
Rereading deSilva's text he quite clearly states: "And note: There is a strict rule: NEVER modify the next instruction to be executed! " I mis-interpreted this to mean never modify future instructions rather than never modify an instruction then execute it immediately. You can see just how confused I was.
I think I'm on the right track now.
Thanks again.
p
You will find more background explanation for this in the "sidetrack" about pipelining..