EmbeddedRelated.com
Forums

AVR Harvard architecture -- worst of both worlds?

Started by Everett M. Greene September 8, 2007
"Mark L Pappin" <mlp@acm.org> wrote in message
news:m3fy1o146g.fsf@Claudio.Messina...
> Rene Tschaggelar <none@none.net> writes: > > Vladimir Vassilevsky wrote: > > >> The big deal is the lack of the universal *. You have to explicitly > >> use the different kinds of pointers depending on where is the > >> object. > ... > >> the IAR EC++ for AVR tends to keep the constant static objects in > >> RAM rather then in ROM. > > > this is a shortcoming of the C language.
> No, it's a shortcoming of some implementations of the C language. > Nothing in the language requires that RAM and ROM share address space. > > HI-TECH Software (for example) have been doing C compilers for Harvard > architecture machines for a very long time which manage to use 'const > X *' as a "universal" pointer, able to refer to RAM or ROM objects > with no extra work from the programmer.
This implies RTTI in the pointers, with the corresponding tradeoff in performance. Vladimir Vassilevsky DSP and Mixed Signal Consultant www.abvolt.com
Everett M. Greene wrote:
> And we won't even get into Little-Endian vs. Big-Endian... > > An "interesting" situation arises when dealing with constants in programs. > One would like to put these in ROM but with a Harvard architecture, one > can't access the locations as directly (if at all) as one can if the values > are in RAM. Thus, one has to have either special functions to call to copy > the constants to RAM when needed or copy them to RAM at program initialization. > The latter runs the risk of the RAM location getting overwritten and the > constant not being as constant as one wishes. The former adds a layer of > complexity and additional execution time to the programming that one would > just as soon avoid. >
Copying constants to RAM on startup does not run any risk of the locations getting overwritten unless your program is totally messed up, and then "varying constants" is only one of your many problems. If you can arrange for the compiler to see the constant's values before using them, it will generally use the values directly in the code. Otherwise, the only disadvantage of copying them into RAM is the RAM space used - for lookup tables, you might want to make sure they are in flash.
> The AVR just adds to the problem by having word-oriented addressing for the > ROM space and byte-oriented addressing for the RAM space. This makes life > especially "interesting" for linkers which have to be able to distinguish > between ROM and RAM addresses to perform the proper offset calculations.
That's only a problem if you are writing an AVR linker or appropriate low-level library routines. For compiler users, you just read the FAQ for your compiler. The real problem with multiple memory spaces is that C has no standard way of dealing with them, so that every compiler has its own syntax (some misuse "const" to mean data in flash, some have an extra "flash" keyword, others use macros).
Mark L Pappin wrote:
> Rene Tschaggelar <none@none.net> writes: >> Vladimir Vassilevsky wrote: > >>> The big deal is the lack of the universal *. You have to explicitly >>> use the different kinds of pointers depending on where is the >>> object. > ... >>> the IAR EC++ for AVR tends to keep the constant static objects in >>> RAM rather then in ROM. > >> this is a shortcoming of the C language. > > No, it's a shortcoming of some implementations of the C language. > Nothing in the language requires that RAM and ROM share address space. >
The language *does* require a single address space (accessible via a "void*" pointer). It is perfectly possible to embed the separate address spaces into a larger virtual address space, and thus have universal pointers (at a cost in code space and run-time) - that way you are extending the multiple address space cpu into a C-compatible cpu.
> HI-TECH Software (for example) have been doing C compilers for Harvard > architecture machines for a very long time which manage to use 'const > X *' as a "universal" pointer, able to refer to RAM or ROM objects > with no extra work from the programmer. > > mlp > (Yes, I'm currently employed by HI-TECH, but that's not relevant here > - I'm defending the language, not pushing an implementor.)
"David Brown" <david@westcontrol.removethisbit.com> wrote in message 
news:46e502ab$0$3206$8404b019@news.wineasy.se...
> Mark L Pappin wrote: >> Rene Tschaggelar <none@none.net> writes: >>> Vladimir Vassilevsky wrote: >> >>>> The big deal is the lack of the universal *. You have to explicitly >>>> use the different kinds of pointers depending on where is the >>>> object. >> ... >>>> the IAR EC++ for AVR tends to keep the constant static objects in >>>> RAM rather then in ROM. >> >>> this is a shortcoming of the C language. >> >> No, it's a shortcoming of some implementations of the C language. >> Nothing in the language requires that RAM and ROM share address space. > > The language *does* require a single address space (accessible via a > "void*" pointer).
You think so? "void *" is *not* a universal pointer, oh no, no, no. The language does not allow a function pointer to be compatible with void *, no siree. Hence, there is no requirement for CODE and DATA to be in the same address space. The fact that some customers wish const data to be placed in CODE address space is another matter entirely--and I'd agree that a void * is a universal pointer only for data objects, not for function objects. -- Paul.
Paul Curtis wrote:
> "David Brown" <david@westcontrol.removethisbit.com> wrote in message > news:46e502ab$0$3206$8404b019@news.wineasy.se... >> Mark L Pappin wrote: >>> Rene Tschaggelar <none@none.net> writes: >>>> Vladimir Vassilevsky wrote: >>>>> The big deal is the lack of the universal *. You have to explicitly >>>>> use the different kinds of pointers depending on where is the >>>>> object. >>> ... >>>>> the IAR EC++ for AVR tends to keep the constant static objects in >>>>> RAM rather then in ROM. >>>> this is a shortcoming of the C language. >>> No, it's a shortcoming of some implementations of the C language. >>> Nothing in the language requires that RAM and ROM share address space. >> The language *does* require a single address space (accessible via a >> "void*" pointer). > > You think so? "void *" is *not* a universal pointer, oh no, no, no. The > language does not allow a function pointer to be compatible with void *, no > siree. Hence, there is no requirement for CODE and DATA to be in the same > address space. The fact that some customers wish const data to be placed in > CODE address space is another matter entirely--and I'd agree that a void * > is a universal pointer only for data objects, not for function objects. >
Sorry - I was thinking only of data pointers, not function pointers (since that's what was mainly under discussion). You are entirely correct that data and function pointers don't have to be related (they can be different sizes and have different memory spaces).
Jim Granville <no.spam@designtools.maps.co.nz> writes:
> Everett M. Greene wrote: > > I've worked with at least one CPU in the past that had no access to > > the code space at all. > > You might want to rephrase that statement! :) > > A CPU with "no access to the code space at all" cannot > even fetch opcodes, and is thus going to be very easy to work > with, as it is a paper-weight.
Picky, picky, picky,... :-) Alright, it could execute instructions from its program memory but could not access the program memory as data in any way whatsoever. BTW: It wasn't much above the paperweight class as it was.
>> >> >And we won't even get into Little-Endian vs. Big-Endian... >> >> Thank Bog! >> >> >An "interesting" situation arises when dealing with constants in >> >programs. >> >One would like to put these in ROM but with a Harvard architecture, one >> >can't access the locations as directly (if at all) as one can if the >> >values >> >are in RAM. Thus, one has to have either special functions to call to >> >copy >> >the constants to RAM when needed or copy them to RAM at program >> >initialization. >> >> I don't understand how it would even be possible to copy the constants >> to RAM if they can't be accessed "at all" when they are in the flash >> ROM. Good trick. > > I've worked with at least one CPU in the past that had no access to > the code space at all. > >> But of course, all that's necessary is to use the "special function" >> [sic] which is really just another opcode (LPM) to fetch a constant >> from ROM into a machine register vice using LD to fetch a value from >> RAM. What's the big deal? Seriously. > > You left out the steps of having to load the ROM address into the Z > register, execute the LPM instruction, and then move the fetched value > to where you want it if you want it somewhere other than R0. You have > to move the value if you're dealing with a multi-byte entity. >
The AVR mega core allows you to do LD Rn, [Z+] -- Best Regards, Ulf Samuelsson This is intended to be my personal opinion which may, or may not be shared by my employer Atmel Nordic AB
>> >> An "interesting" situation arises when dealing with constants in >> programs. >> One would like to put these in ROM but with a Harvard architecture, one >> can't access the locations as directly (if at all) as one can if the >> values >> are in RAM. Thus, one has to have either special functions to call to >> copy >> the constants to RAM when needed or copy them to RAM at program >> initialization. >> The latter runs the risk of the RAM location getting overwritten and the >> constant not being as constant as one wishes. The former adds a layer of >> complexity and additional execution time to the programming that one >> would >> just as soon avoid. >> > > Copying constants to RAM on startup does not run any risk of the locations > getting overwritten unless your program is totally messed up, and then > "varying constants" is only one of your many problems. > > If you can arrange for the compiler to see the constant's values before > using them, it will generally use the values directly in the code. > Otherwise, the only disadvantage of copying them into RAM is the RAM space > used - for lookup tables, you might want to make sure they are in flash. >
I copy constants to the stack when needed. A little hassle, but not dramatic. I seems to remembed someone telling me that the Harvard architecture of the AVR improved performance by about 35% performance. -- Best Regards, Ulf Samuelsson This is intended to be my personal opinion which may, or may not be shared by my employer Atmel Nordic AB
Ulf Samuelsson wrote:
>>> An "interesting" situation arises when dealing with constants in >>> programs. >>> One would like to put these in ROM but with a Harvard architecture, one >>> can't access the locations as directly (if at all) as one can if the >>> values >>> are in RAM. Thus, one has to have either special functions to call to >>> copy >>> the constants to RAM when needed or copy them to RAM at program >>> initialization. >>> The latter runs the risk of the RAM location getting overwritten and the >>> constant not being as constant as one wishes. The former adds a layer of >>> complexity and additional execution time to the programming that one >>> would >>> just as soon avoid. >>> >> Copying constants to RAM on startup does not run any risk of the locations >> getting overwritten unless your program is totally messed up, and then >> "varying constants" is only one of your many problems. >> >> If you can arrange for the compiler to see the constant's values before >> using them, it will generally use the values directly in the code. >> Otherwise, the only disadvantage of copying them into RAM is the RAM space >> used - for lookup tables, you might want to make sure they are in flash. >> > > I copy constants to the stack when needed. > A little hassle, but not dramatic. >
I'm not sure I can think of any reason why that might help. The only two problems with constants in flash are the awkward syntax (either you've got extra keywords or macros added, or you've got a broken "const" implementation), and for pointers (such as passing around strings in flash).
> I seems to remembed someone telling me that the Harvard architecture > of the AVR improved performance by about 35% performance. >
Having separate buses for code and data is certainly a good thing for making simple and fast processors, although I think that any figure put on it is taken out of thin air (did someone make a complete AVR core with a shared bus for comparison? Any other method will have huge error margins). But having separate memory spaces, which is the issue here, has much less effect (you'd need a little extra decoding of memory accesses, but save the lpm instructions). The extra memory spaces make it easier to get more than 64K memory ranges, but are otherwise a big disadvantage.
David Brown wrote:

> Ulf Samuelsson wrote: >
>> I copy constants to the stack when needed. >> A little hassle, but not dramatic. >> > > I'm not sure I can think of any reason why that might help. The only > two problems with constants in flash are the awkward syntax (either > you've got extra keywords or macros added, or you've got a broken > "const" implementation), and for pointers (such as passing around > strings in flash). >
David, the syntax is a matter of the compiler. The syntax of C has never been phantastic either. Rene