Avr instruction timing

Go To Last Post
37 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am trying to create a precise (10% tolerance) delay subrouting using assembler in AvrStudio 7.0.1188.

The purpose for this routine is to learn about the instruction timing and in the end, integrate it into a custom sw-uart library.

 

Using Attiny85, I have written the code in [1]. For the instruction timings, I have checked the #Clocks column in Paragraph Instruction Set Summary (Attiny85 datasheet Rev. 2586Q–AVR–08/2013, page 202 [2]) and the AVR Instruction set Reference [3]. 

 

As far as I understand, the repeat loop in my code should take 100 repetitions *3cc (dec (1) + brne(2, condition false)) = 300 cc. Since my tiny85 is running at 1Mhz (internal osc, CKDIV8 not set), I am expecting around 300us delay for a pin toggle. Instead, I am seeing a 144us delay using an oscilloscope.

 

What could be the root cause here? I assumed a pipeline speedup, but the tiny85 clearly states close to 1MIPS at 1Mhz (about 1 instruction per cc) and not more.

 

Many thanks in advance.

 

[1]

.include "tn85def.inc" 

.cseg
.org $000
rjmp initAndStart

; Replace with your application code
initAndStart:
    sbi DDRB, 1 // PORTB.1 output

    start:
        sbi PORTB, 1 // PORTB.1 high
        rcall delay
        cbi PORTB, 1 // PORTB.1 low
        rcall delay
        rjmp start
        delay:
            ldi r16, 100
            repeat:
                dec r16
                brne repeat
            ret

[2] http://www.atmel.com/images/atme...

 

[3] http://www.atmel.com/images/Atme...

 

Last Edited: Mon. Apr 24, 2017 - 08:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Run in simulator, it has a cycle counter.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Already ran oh in the Simulator. Takes about 300cc for toggling a pin, as expected. I'm baffled as to the oscilloscope readings -150ms for pin toggle at 1Mhz. Perhaps I've configured something incorrectly?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Before re-inventing the wheel,  what is the tolerance on the delays already provided by avr-libc ?

 

http://www.nongnu.org/avr-libc/u...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mihaigalos wrote:
Since my tiny85 is running at 1Mhz (internal osc, CKDIV8 not set)

With that code, and CKDIV8 not set, why do you say your AVR is running at 1MHz?  I see no manipulation of CLKPR...

 

So, why not just set CLKPR to the value you want?  And also, it is good practice in general to set the stack pointer.  Yes, it has a default value after reset.  But consider a real application where your code "runs away"...

 

clawson wrote:
Run in simulator, it has a cycle counter.

Studio7 simulator indeed comes up with 307 cycles for each "rcall delay".

 

That doesn't really fit with 1MHz (~300us) or 8MHz (~38us) AVR clock.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I can confirm the tiny85 is running at 1Mhz since the pin toggle takes 1us without delay. I am interested in understanding what is going on..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mihaigalos wrote:
I can confirm the tiny85 is running at 1Mhz since the pin toggle takes 1us without delay.
Nope. The 1µs is another evidence that it is running at 2Mhz (sbi and cbi take 2 cycles each).

 

Isn't there a Div4 setting for the clock when in Attiny15 compatibility mode? (I seem to remember something like that)

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mihaigalos wrote:
I can confirm the tiny85 is running at 1Mhz since the pin toggle takes 1us without delay.
sternst wrote:
Nope.

As hinted, show the pin-toggle test program as a sanity check, and tell what you are watching on your 'scope.

 

(lol -- got the 'scope on the range you think you do?)

 

And, also for sanity:

theusch wrote:
With that code, and CKDIV8 not set, why do you say your AVR is running at 1MHz? I see no manipulation of CLKPR... So, why not just set CLKPR to the value you want?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code in the original post produces screenshot [1] (156us for 100 iterations, each iterations 3cc).

In [2] one can find the simple, no delay program I was talking about, and in [3] its generated waveform. After setting the pin high, the pin stays high for 1us. The pin then stays low for 2us. I don't understand why, since cbi sets the pin low in 1cc and then  rjmp takes 2 cc, which should mean 3cc == 3us at 1Mhz.

 

I'm attaching a screenshot of my settings in [4].

 

Thank you for your precious help.

 

 

[2]

.include "tn85def.inc" 

.cseg
.org $000
rjmp initAndStart

; Replace with your application code
initAndStart:
    sbi DDRB, 1 // PORTB.1 output

    start:
        sbi PORTB, 1 // PORTB.1 high
        cbi PORTB, 1 // PORTB.1 low
        rjmp start

 

[3]

 

[4]

Last Edited: Mon. Apr 24, 2017 - 08:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

This together with the CKDIV8 fuse, it IS running at 2 MHz.

 

mihaigalos wrote:
since cbi sets the pin low in 1cc
Again: cbi takes 2 cycles.

Stefan Ernst

Last Edited: Mon. Apr 24, 2017 - 08:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't understand why, since cbi sets the pin low in 1cc and then  rjmp takes 2 cc, which should mean 3cc == 3us at 1Mhz.

Humm.. Maybe that pipelining does kick in here? Which would mean :

  • sbi gets executed, during its execution cbi gets prefetched (very first execution of sbi lasts 2cc, every other execution is 1cc since sbi was prefetched in previous instruction)
  • during the execution of cbi, rjmp is prefetched (execution of cbi lasts 1cc since it was prefetched in the previous instruction)
  • rjmp is executed in the next cc, since it was already prefetched during execution of cbi

 

Does anybody else think this?

Last Edited: Mon. Apr 24, 2017 - 08:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mihaigalos wrote:
since cbi sets the pin low in 1cc ...

Check again:

sternst wrote:
Nope. The 1µs is another evidence that it is running at 2Mhz (sbi and cbi take 2 cycles each).

 

In [3] 'scope trace, I'm not familiar with that 'scope display, so the best I can say is that the high time appears to be 1us (1us per big division, right?). That is consistent with the "AVR appears to be running at 2MHz" from an earlier response.

 

Why did you say "CKDIV8 not set" when it is checked?

 

[edit]  Good guess earlier, Stefan, and verified once we have all the info (fuse bits in this case).

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Apr 24, 2017 - 08:25 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm not familiar with that 'scope display, so the best I can say is that the high time appears to be 1us (1us per big division, right?)

1us per division, yes. You can also see the computed difference between the two cursors (BX-AX = 1us).

 

Why did you say "CKDIV8 not set" when it is checked?

I'm sorry, by mistake. I thought it was the other way around. It is checked, as you can see in the screenshot, meaning internal 8Mhz gets divided by 8 giving 1Mhz internal clock. 

 

cbi takes 2 cycles.

oh. I see.  

Last Edited: Mon. Apr 24, 2017 - 08:28 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As stated above CBI and SBI takes 2 (TWO) clock ticks EACH (only register-register instructions are 1-clock instructions - ATtiny85 is NOT a "Reduced Core tinyAVR"). Then another two clocks for the RJMP. So for one loop you have 6 clocks, an the pin is high for the two clocks from the SBI to the CBI. Your stated timings and scope screenshot seems consistent with a 2 MHz clock.

Click on the "Copy to clipboard" button in the fuse dialog in Studio and paste in a post here so we can see ALL of your fuse settings.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So for one loop you have 6 clocks, an the pin is high for the two clocks from the SBI to the CBI.

Humm. Seems high for 1us at 1Mhz, meaning 1cc. Can you please review my previous post concerning the pipeline. Could it play any role here?

 

 "Copy to clipboard" button in the fuse dialog in Studio and paste in a post here so we can see ALL of your fuse settings.

I've attached a screenshot of the settings. The fuses should be there, didn't you see them? 

 

[edit] I'm also putting them here in text form

 

SELFPRGEN = [X]
RSTDISBL = [ ]
DWEN = [ ]
SPIEN = [X]
WDTON = [ ]
EESAVE = [X]
BODLEVEL = 2V7
CKDIV8 = [X]
CKOUT = [ ]
SUT_CKSEL = PLLCLK_1KCK_14CK_64MS

EXTENDED = 0xFE (valid)
HIGH = 0xD5 (valid)
LOW = 0x61 (valid)

Last Edited: Mon. Apr 24, 2017 - 08:35 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mihaigalos wrote:
I've attached a screenshot of the settings. The fuses should be there, didn't you see them?

 

(now I'm going to be accused of shouting...)

 

DID YOU READ AND UNDERSTAND #10 ?!?

 

Did you decode your fuse bit settings?

 

What does a low fuse byte of 0x61 mean?

 

 

See post #10, where Stefan posted a picture telling what CKSEL of 0001 means...

 

Your AVR is running at 2MHz.  No more mysteries.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:

Nope. The 1µs is another evidence that it is running at 2Mhz (sbi and cbi take 2 cycles each).

 

Even with pipelining ? are the values given in the datasheed worst-case ? I'm guessing yes. Which would mean they take 1cc with pipeline acceleration.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are our responses being blocked?!? 

 

OP cannot see #10 and following posts?

 

Pipelining has nothing to do with anything in this thread.  (Well, implicitly, the BRNE when taken adds that extra cycle for the pipleline dump.  But still nothing to do with the fact that the AVR is running at 2MHz.)

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Mon. Apr 24, 2017 - 08:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I see. The nominal frequency is 16 which gets didived by 8 with my settings, leading to 2Mhz.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IIRC the copy to clipboard will bring the interpreted fuses values in the scrolling list. ALL of them. My apologies if I'm wrong about this.

Still, if you want to argue about our methods of trying to help you, which must have taken about the same time as actually doing the copy, then its your choice.

Before you continue arguing that you're right and your AVR is wrong about your simplified test (the SBI/CBI one), check the timings of those instructions in the tiny85 data sheet, please. They are on page 202.

Then apply Occham's Razor. If the timings are what you have claimed they are, then they are consistent with a 2 MHz clock.

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Matter got resolved while I was posting the above. Congrats! Lesson to learn: Occham rarely fails..

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Then apply Occham's Razor.

LOL -- or Sherlock Holmes?

 

"Once you eliminate the impossible, whatever remains, no matter how improbable, must be the truth."

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

No worries, I have reposted it anyway. I feel the tone of the conversation could be more constructive, though. I wish you all good luck in your edeavours.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ah, Sherlock Holmes! You are a man of exquisite taste, Mr Theusch! :-)

As of January 15, 2018, Site fix-up work has begun! Now do your part and report any bugs or deficiencies here

No guarantees, but if we don't report problems they won't get much of  a chance to be fixed! Details/discussions at link given just above.

 

"Some questions have no answers."[C Baird] "There comes a point where the spoon-feeding has to stop and the independent thinking has to start." [C Lawson] "There are always ways to disagree, without being disagreeable."[E Weddington] "Words represent concepts. Use the wrong words, communicate the wrong concept." [J Morin] "Persistence only goes so far if you set yourself up for failure." [Kartman]

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mihaigalos wrote:
I feel the tone of the conversation could be more constructive, though.

Re-read the whole thread.  INCLUDING your responses.

 

I only started shouting after you ignored the SBI/CBI cycle count several times, and ignored the repeated 2MHz analysis.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

but you did shout. Period.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mihaigalos wrote:
but you did shout. Period.
Indeed.  [did it get your attention?  apparently so]  And twisted, too.  A Beatles fan, after all.  Probably waaay before you were born...

Well, shake it up, baby, now (Shake it up, baby)
Twist and shout (Twist and shout)
C'mon C'mon, C'mon, C'mon, baby, now (Come on baby)
Come on and work it on out (Work it on out)

Well, work it on out, honey (Work it on out)
You know you look so good (Look so good)
You know you got me goin', now (Got me goin')
Just like I knew you would (Like I knew you would)

...

https://www.youtube.com/watch?v=...

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

JohanEkdahl wrote:
Occham's Razor.

Surely, "Occam" (or "Ockham") ?

 

https://en.wikipedia.org/wiki/Oc...

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Since you have access to the fuses on the Tiny85 and you are running a test program, try setting the CKOUT fuse.  This will put the system clock out on pin 3.  Here you can measure it with your oscilloscope.

 

If you are getting a @150 microsecond measurement for a 300 cycle loop, then your clock is running a 2MHz.  The question is how did it get to be running at this speed.

 

I agree with user: sternst.  The PLL clock has been selected on the Tiny85.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Even with pipelining ? are the values given in the datasheed worst-case ?

I don't think that the AVR has "pipelining" in the modern sense.  It has "deterministic pre-fetch", so all the values in the datasheet are "always."

The net effect of AVR pipe-lining is that jump and skip instructions take an extra cycle even though you might think they qualify as "register-to-register" instructions.  (and the extra cycle re-loads the pre-fetch...)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Something I find odd, and needs to be remembered is that

 

SBI DDRB, 0 is 1T

 

and

 

SBI PINB, 0 is 2T

 

so there must be an architectural shortcut in there for the DDR's.

 

Edit, this was rubbish.  I did not investigate this properly when I first thought it may have been the case.

(signature pending)

Last Edited: Mon. Jul 15, 2019 - 07:02 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you talking about the cycles for the opcode itself to execute? Or the cycles for the result to be seen in the GPIO registers? This has nothing to do with the cycle time of SBI itself does it?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The execution, the cycles that elapsed before the program counter advances. This is reflected in the cycle counter in Atmel Studio when running with the simulator for many devices.

I've never actually done a benchmark comparison to verify it.

I suppose I will have to now.

(signature pending)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


OK so I tried this very simplistic test:

 

 

 

The only thing that changed was "SBI 0x04,0" became "SBI 0x03,0" in the second case. Each time I reset the cycle counter at entry to main then just ran to the breakpoint. Both are exactly 800002 cycles. So the SBI execution length did NOT change whatever the target.

 

Your go...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0


Yes, I was wrong, I'll have to retract the statement. I'd fallen into bad habits. 

 

The cycle counter seems to lose a count at the start of any debug session ?

 

Only one cycle if it is the first operation.

 

 

Two cycles.

 

 

 

So apologies.

 

 

(signature pending)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Apparently the delays in avr-libc suffer from a number of issues:  https://savannah.nongnu.org/patch/?6418

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

strontiumdog wrote:

Apparently the delays in avr-libc suffer from a number of issues:  https://savannah.nongnu.org/patch/?6418

You are quoting a bug report from 2008-2009 ???

 

Because of __builtin_avr_delay_cycles() the Libc delay routines have been cycle accurate for many years.

 

In fact the history on:

 

http://svn.savannah.gnu.org/viewvc/avr-libc/trunk/avr-libc/include/util/delay.h.in?view=log

 

shows that delay.h was changed to add "builtin" support in 2010 in fact,  at commit #2103

 

(anyway this thread is not about C delay() accuracy but AVR opcode timing?)

Last Edited: Tue. Jul 16, 2019 - 02:00 PM