Está en la página 1de 6

Instruction cycle time (Tcy)

The PIC will internally divide the clock input frequency by 4, in order to execute the program instructions. We will name these 4 pulses Q1 through Q4. The Program Counter will be increased on every Q1. During these 4 clock pulses, the PIC will fetch the instruction that the updated Program Counter indicates, and simultaneously it will execute the instruction that was fetched during the PREVIOUS Q1-Q4 pulses! This is something that you will probably will never have to deal with, and that will never cause you any further frustration more than understanding how the PIC works. So, look at the following timing chart:

It is clear that the PC (Program Counter) is increased ONCE every 4 clock pulses. This means that every 4 clock cycles, an instruction is executed. But you may also notice, that, for example, in order to execute the instruction in PC position = n+1, the PIC will need 8 clock pulses! During the first 4 pulses, it will fetch the instruction, and during the other 4 pulses it will execute it. This means that the PC will be increased 2 times, but only one instruction will be executed, right? WRONG! This would only happen during the very first instruction that the PIC will execute immediately after the power on. Due to the fact that during Q1-Q4 the PIC does 2 jobs simultaneously (fetch new instruction and execute previous instruction), on every PC increment (4 Clock Pulses) one instruction is executed, or better say that on every PC increment, on operation is carried out.

4 pulses = 1 operation, 1 operation = 1 instruction execution ?


The sub-title is of course a rhetorical question. Unfortunately, not all instructions are executed in a single operation (4 clock pulses). There are two categories of instructions that require 2 instruction executions in order to be fulfilled. The first category and most straightforward to understand contains all the instructions that have a conditional branch. These are the BTFSS, BTFSC, DECSZ and INCSZ. But how is a conditional branch handled from the PIC? Let's see an example with BTFSS instruction:
BSF Zero ;We set the Zero Flag BTFSS Zero ;If Zero is SET, then SKIP the next instruction {AN INSTRUCTION}

What will happen? On the first instruction, we SET the Zero flag. On the next instruction, we check if the Zero flag is set. The BTFSS means Skip If Set, thus, the following instruction will NOT be executed, as the Zero flag is SET. As a matter of fact, the PIC will NOT jump the following instruction. Instead, it will temporarily convert it into the NOP and will be executed as NOP. In this case, the BTFSS instruction must be calculated as a 2-Cycles instruction, and the instruction that follows the BTFSS must NOT be taken into account! Now look at the following example:
BCF Zero ;We set the Zero Flag BTFSS Zero ;If Zero is SET, then SKIP the next instruction {AN INSTRUCTION}

This example is the same as the previous one, but now we have CLEAR the Zero flag. The instructions that follows the BTFSS instruction will be executed normally! In this case, the BTFSS instruction must be calculated as an 1-Cycle instruction, and the following instruction must be taken into account accordingly. In other words, the conditional branching instructions may need 1 or 2 instructions cycles to be executed, according to the condition result. This is something that you need to pay attention when calculating the instruction cycles required for a subroutine. The second category with instructions that needs more than 1 cycle to be executed, contains all the instructions that will force the PC to change. These are the GOTO instruction, the CALL and the RETURN (including RETLW and RETFIE). But why does this happen? Well, if you have read and understood the first paragraph (4 pulses = 1 operation), then it will be easy to

understand why. In this paragraph i explained that during the very first instruction execution of the program immediately after a power-on, the PIC will require 2 instruction cycles. That is true, but not complete. Whenever the PC is forced (with a GOTO/CALL/RETURN instruction) to change. the PIC will need 2 cycles to execute this instruction. And why is that? Suppose we have this part of code to examine:
BSF Zero MOVLW 0xFF GOTO Label_1 MOVLW b'01010101' . . . MOVWF PORTA . . .

Label_1

When the PC is on the "MOVLW 0xFF" instruction (line 2), the PIC will execute the "BSF Zero" instruction and will load the "MOVLW 0xFF". On the next instruction cycle, the PC will indicate the "GOTO Label_1" instruction. The PIC will execute the "MOVLW 0xFF" and will fetch the "GOTO Label_1". Here is the interesting part. On the next instruction execution, the PC will indicate the "MOVLW b'01010101'" instruction, and the PIC will execute the "GOTO Label_1" instruction and will fetch the "MOVLW b'01010101'" instruction. On the next instruction cycle, the PC will indicate the instruction right after Label_1, as instructed before from the "GOTO Label_1" instruction. But it will NOT execute the already-fetched instruction, as it is the instruction right after the "GOTO Label_1"! That would be wrong! So, the execution is omitted! The execution of the instructions is then carried out normally by increasing the PC, fetching the new instruction and executing the "MOVWF PORTA" instruction. This executioncancellation that follows the GOTO command is the reason why such commands requires 2 instruction cycles to be fulfilled.

The following table indicates the cycles required from each instruction to be executed: Instruction Cycles BTFSS 1 or 2 BTFSC 1 or 2 INCFSZ 1 or 2 DECFSZ 1 or 2 GOTO Always 2 CALL Always 2 RETURN Always 2 RETLW Always 2 RETFIE Always 2 ***All other will require 1 instruction cycle to be executed.

An example - Calculate an 1 mSec delay subroutine


Let's make a real-life example subroutine. This subroutine, will generate an 1 mSec delay. The PIC operates with a 4 MHz clock input. This means that each instruction cycle is executed with 1MHz frequency, in other words, once every 1uSec. So, we need to call a subroutine that will execute 1000 instructions, in order to achieve the 1 mSec delay. Look at the following subroutine:
Delay_1_mSec MOVLW d'250' Delay_Loop ADDLW 0xFF BTFSS Zero GOTO Delay_Loop RETURN

; Decrease W by 1 ; Is the Zero flag Set? ; - NO. Goto back

The Delay_Loop is composed by 3 instructions, the "ADDLW 0xFF" with 1 cycle duration, the "BTFSS Zero" with 1 cycle duration (as long as W is not 0), and the "GOTO Delay_Loop" with 2 cycles duration. Adding them we have 4 cycles. This loop will be executed 250 times, as the W has the decimal value "250". So, 250 x 4 = 1000! This loop will generate 1000 uSec (that is 1 mSec) delay on each CALL. Here comes some further considerations. The overall delay of the subroutine will NOT be 1000 cycles exactly. It will be precisely 1002 cycles. First of all, we need to add the "MOVLW d'250'" that has 1 cycle length. The loop has 4 cycles overall delay, EXCEPT the last time it loops, that the W wil lbe zero and the "GOTO Delay_Loop" will be replaced with a "NOP" instruction. It will then have 3 cycles overall delay. So, the loop has exactly 249 x 4 + 3 cycles, that is 999 cycles. And finally, we need to add 2 cycles for the return instruction. So we have, 1 + 999 + 2 = 1002 cycles. If someone measures also the 2 cycles from the "CALL Delay_1_mSec" instruction, we have a total of 1004 cycles. How can we fix this? Very easy. I will call the loop (that has 4 cycles duration) one time less:
Delay_1_mSec MOVLW d'249' Delay_Loop ADDLW 0xFF BTFSS Zero GOTO Delay_Loop RETURN

; Decrease W by 1 ; Is the Zero flag Set? ; - NO. Goto back

Now we have: 248 x 4 + 3 = 995 cycles from the loop, +1 from the "MOVLW d'249'" = 996, +2 from the "RETURN" = 998, +2 from the "CALL Delay_1_mSec", this makes it exactly 1000 instructions!

Calculate
Fosc(Hz) = External or Internal frequency x PLL , Tosc(Sec) = 1/Fosc Fcy = Fosc/4 , Tcy=1/(Fosc/4)
Ex: Fosc 20 MHz Tcy= 1/(20 MHz/4)= 200 nanoSec If required 1 milliSec must x 5000 cycle Careful: Tcy is the instruction cycle time. Tosc is the internal oscillator.

Tosc is derived from the external or internal frequency generating device + PLL/dividers

Crystal = 16MHz , PLL=4X FOSC=16MHzx4=64MHz FCY = FOSC / 4 = 16MHz

NOP = Tcy = TOSC x 4 Tcy(Tstate) means instruction cycle or machine cycle.

The clock cycle used to drive the CPU core (FOSC) is based on the oscillator frequency (OSC) and on some devices a PLL that can be used to scale the frequency (typically 4x on an 18F). So ... FOSC = OSC * PLL For example: 16F device with 4Mhz internal oscillator and no PLL (treat as x1) means FOSC = 4 Mhz * 1 = 4 Mhz 18F device with 10Mhz crystal and 4x PLL enabled means FOSC = 10 Mhz * 4 = 40 Mhz The 8-bit device core takes 4 clock cycles to decode a single word instruction (like a NOP) So the example 4 Mhz 16F device with no PLL can execute 4,000,000 / 4 = 1,000,000 single word instructions per second (e.g. 1 uSec per instruction) and the example 18F device would do 40,000,000 / 4 = 10,000,000 (e.g. 0.1 uSec = 100 nSec per instruction). Some instructions take 8 clock cycles either because they skip over another instruction without executing it (e.g. BTFSS), cause the prefetched instruction to be discarded (e.g. 16F's GOTO, 18F's BRA) or because they contain an memory address that is split over two instruction words (e.g. the 18F's CALL, LFSR, etc).

También podría gustarte