Forced jump
Paul Baker
Posts: 6,351
Project du jour is turning out to be a headache, it requires multiple tasks where the frequency is too high for RTCC method (interrupt overhead (6 cycles) would throw everything off). Anyways my solution is manually multithreaded modules which are strung together in order of need. Jmp + setting up·jump value approaches the problem with·ISR overhead. Can I do a "mov pc,w" to cause execution to jump to that location? What does jmp do that needs those 3 cycles (I know one additional is for the pipeline, but what is the other one)?·Do I need to place a nop after the command because of the instruction pipeline? What Im trying to implement is a fast as possible jmp ind.
Post Edited (Paul Baker) : 7/11/2005 6:40:01 AM GMT
Post Edited (Paul Baker) : 7/11/2005 6:40:01 AM GMT
Comments
Yes, provided that W contains the address of the jump target, you can use mov pc, w to jump to that target within the same code page. jmp pc+w (or add pc, w) is another method which allows for relative jumps with w holding the offset.
Actually, all three cycles are caused due the instruction pipeline. This 4-level pipeline usually holds four instructions read from four consecutive locations in program memory. On a jmp (or call), three instructions in the pipeline must be discarded, and it takes three cycles until the first instruction of the code sequence at the jmp target reaches the end of the pipeline. There is no need to place nop instructions.
BTW: Skip instructions take two cycles when a skip is executed. Again, this is because of the instruction pipeline. As only one instruction is skipped, only one instruction in the pipeline must be discarded. This is why it only takes one additional clock cycle.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
When your destination address is in w, and that destination is on the same page, then the mov pc,w executes the same as a jmp addr, timings and all. It is 3 cycles for either one. By the way, this makes a great state machine:
Cheers,
Peter (pjv)
I think I've got the module switching code down to 5 cycles (+1 if fsr needs to be set), I should be able to squeeze that in, the fast process is 3.57 MHz or a state transistion every 7 cycles, leaving 6 cycles between the trailing edge of the clock to the leading edge of the clock. Man I thought calculating the timing of NTSC was tricky, thats childs play compared to organizing a 3.57 MHz process, a 450 kHz process (1/8th speed of the faster process) and stuffing a bunch of support functions to perform data manipulations during the "dead space" while keeping the fast proccess a rock steady frequency.
As I hinted, Im tackling it by writing the support functions, then lacing them with the fast and slow processes by hand, then stringing them in a fashion that the leading edge of the clock in the next module happens exactly 7 cycles after the previous module's last trailing edge of the clock. Ive thought about using a preprocessing framework to do the merging of the processes but I think that would take longer than doing it by hand. Does anyone know of a free generic, flexible preprocessor that is also easy to use?
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Yes, that interleaved code writing (stuffing "dead" space) can get pretty tricky, but hey, once it's done and running, who cares. Years ago I had the need for that when I was doing 10 Mbit/sec bit-bang UARTing, and presently I'm doing it with 5 Mbit/sec UARTing interleaved with reading/writing serial memory at 12.5 MHz.
Could you describe in more detail what your exact high speed requirements are?? I'm kinda interested in seeing what others are needing and able to squeeze out of 50 Mips.
Cheers,
Peter (pjv)