Seminar Topics & Project Ideas On Computer Science Electronics Electrical Mechanical Engineering Civil MBA Medicine Nursing Science Physics Mathematics Chemistry ppt pdf doc presentation downloads and Abstract

Full Version: The AVR Microcontroller and C Compiler Co-Design pdf
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
The AVR Microcontroller and C Compiler Co-Design

[attachment=45299]

Abstract

High Level Languages (HLLs) are rapidly becoming the standard methodology for
embedded microcontrollers due to improved time-to-market and simplified
maintenance support. In order to ensure that the new ATMEL AVR family of
microcontrollers was well suited as a target for C compiler, the external C compiler
development was started before the AVR architecture and instruction set were
completed. During the initial development of the C compiler, several potential
improvements in the AVR were identified and implemented. The result of this
cooperation between the compiler developer and the AVR development team is a
microcontroller for which highly efficient, high performance code is generated.
This paper describes the AVR architecture, and the changes that were undertaken in
the architecture and instruction set during the compiler development phase in order to
make the AVR family of microcontrollers very suitable targets for a C compiler.

The AVR Microcontroller

The AVR enhanced RISC microcontrollers [1] are based on a new RISC architecture
that has been developed to take advantage of semiconductor integration and software
capabilities of the 1990's. A block diagram of the AVR architecture is given in figure 1.
The memory sizes and peripherals indicated in the figure are for the AT90S8414
microcontroller.
Central in the AVR architecture is the fast-access RISC register file, which consists of
32 x 8-bit general purpose working registers. Within one single clock cycle, AVR can
feed two arbitrary registers from the register file to the ALU, do a requested operation,
and write back the result to an arbitrary register. The ALU supports arithmetic and
logic functions between registers or between a register and a constant. Single register
operations are also executed in the ALU.
As can be seen from the figure, AVR uses a Harvard architecture, where the program
memory space is separated from the data memory space. Program memory is accessed
with a single level pipelining. While one instruction is being executed, the next
instruction is being pre-fetched from the program memory.

Fine tuning AVR

There are several advantages in using HLLs in stead of using Assembly language when
developing microcontroller applications. There has, however, traditionally been one
major disadvantage: the size of the code increases. The AVR microcontroller was
developed with the C language in mind in order to make it possible to construct a code
efficient C compiler for AVR. To improve this feature even more, the development of
the C compiler was started before the architecture and the instruction set were
completed. By allowing professional compiler developers at IAR Systems in Sweden
to comment on the architecture and instruction set, we were able to make a
microcontroller very well suited for C compiler generated code.

Addressing modes

In order for the compiler to generate efficient code, it is important that the supplied
addressing modes matches the needs of the C language. The AVR architecture was
originally equipped with two pointer registers. These two pointers could be used for
indirect addressing, indirect addressing with post increment, indirect addressing with
pre-decrement, and indirect addressing with displacement, giving good support for
operation on pointers. In addition, there was a paged direct addressing mode for
accessing variables placed in the data memory.

Displacements

The indirect addressing mode with displacement is a very useful addressing mode, also
from a C compilers point of view. For example, by setting the pointer to the first
element in a struct, you can reach as far in the struct as the displacement allows
you, without having to change the 16-bit pointer. The indirect addressing with
displacement mode is also frequently used for accessing variables placed on the
software stack. Function parameters, and autos are often placed on the software stack,
and can be read and written without having to change the pointers. The displacement
addressing is also very useful in addressing elements in an array.
Even though the displacement mode is very useful in many cases, there was a problem
with the reach of this addressing mode. Originally, the displacement was limited to 16
locations, whereas the displacement needed in real applications often exceeds this
number. In the case where the location can not be reached by the displacement mode, a
new pointer needs to be loaded. To expand the reach of the displacement mode, we
needed to change other parts of the instruction set to get enough coding space. At the
same time, we were informed that the paged direct accessing mode was difficult to use
from the compilers point of view. By removing the paged direct addressing mode,
space was made available for expanding the displacement to 64 locations, which is
large enough to meet most demands for indirect addressing. The paged direct
addressing mode was changed to a two word unpaged direct addressing mode, see
below.

The number of memory pointers

The AVR microcontrollers were originally equipped with two 16-bit memory pointers.
From a C Compilers point of view, one of these pointers must be used as a dedicated
software stack, leaving only one memory pointer for general usage. In many cases, you
need to copy memory from one area to another. Having only one memory pointer, you
would need to read one byte, set the pointer to the destination area, write the byte and
then set the pointer back to the source data area. By including a third memory pointer
(with reduced functionality), data can be copied from one memory area to another
memory area without having to set the pointers.

Direct addressing

As described in the displacement section, we originally had a paged direct addressing
mode which was difficult and inefficient to use by the compiler. Since we needed
coding space for an increased displacement, the paged direct addressing mode was
removed. It is, however, inefficient not having any direct addressing mode, since we in
some cases need to access variables placed in the data memory area. Especially when
dealing with static characters, the code overhead will be large (50%), since
static variables needed to reside in data memory and can not automatically be
placed in registers. In order to overcome this problem with inefficient code, we
decided to include unpaged direct addressing instructions taking a 16-bit address,
making it possible to address 64KByte data memory in one instruction. In order to
access such a large amount of memory, these instructions had to be two 16-bit words.
Using this addressing mode is more efficient than using pointers when the number of
bytes to be accessed is small, for instance when a character is read. For larger areas, it
may still be more effective to use indirect addressing (see example below).

Zero flag propagation

In order to make conditional branches, a number of the instructions manipulates the
AVR status register, which consists of a number of flags. A conditional branch
instruction following such an instruction, will branch or not branch, depending on the
settings of these flags. The arithmetic instructions manipulate the flags, making it
possible to check whether a number A is smaller than, equal to or greater than another
number B. When the numbers in question are eight bit numbers, there are no problems,
since all the flags are depending on the flag setting done by one instruction only. When
using 16 or 32 bit numbers, which is common in the C language, the problem is
somewhat more tricky, since a 32 bit subtraction, for instance, is calculated as 4
consecutive 8 bit subtractions, and after each subtraction, a new set of flags is
generated.

Conclusions

We have constructed a microcontroller well suited for High Level Languages. The
final tuning of the microcontroller done in cooperation with the C compiler developer
has given an additional improvement to the design. Evaluating the code generated from
the compiler, it turns out that the modifications that were done after discussions with
the compiler developer were successful, as the generated code exploits the
improvements frequently.