11
\$\begingroup\$

Most of the ARM Cortex-M core based MCUs have Harvard architecture (except for Cortex-M0 and M0+.)

The thing I do not understand is that why we see only one memory address space. For example, in tge STM32F4 we see only a unified memory address space:

enter image description here

If ARM Cortex-M based MCUs have Harvard architecture (in most cases,) why do we not see two separate memory address spaces - one for data and one for code instructions - instead of one?

\$\endgroup\$
5
  • \$\begingroup\$ are you sure it's actual Harvard and not modified Harvard? \$\endgroup\$
    – user253751
    Apr 21 at 16:14
  • 3
    \$\begingroup\$ seems like modified Harvard - they call it "Harvard bus": community.arm.com/support-forums/f/… \$\endgroup\$
    – user253751
    Apr 21 at 16:18
  • \$\begingroup\$ yes, thanks for the clarification, I wasn't precise enough, it is modified Harvard \$\endgroup\$
    – gvg
    Apr 21 at 16:38
  • \$\begingroup\$ There you go, then. "Modified Harvard" usually just means a performance optimization on a unified address-space, e.g. split L1d/i cache and/or split buses to RAM and Flash. (As en.wikipedia.org/wiki/… points out, having split address spaces would mean you'd need a load-program-memory instruction if you wanted to access it as data and thus still be "modified harvard", which ARM doesn't have, but AVR does. Without that, with split address spaces would be true Harvard.) \$\endgroup\$ Apr 22 at 4:30
  • \$\begingroup\$ I think the term “Harvard architecture” is kinda obsolete in this decade since hardly any architecture is that simple \$\endgroup\$
    – Navin
    May 31 at 11:16

3 Answers 3

13
\$\begingroup\$

When you pick a STM32F4 chip at random and look at the datasheet, in section 2.2 we see a block diagram of the chip.

We see that the CPU has three (!) buses - labeled I-BUS, D-BUS and S-BUS. All of them go to the "AHB bus matrix" and the D-BUS also goes to some "CCM data RAM".

I searched for "Cortex-M4 S-bus" and found this page from ARM describing the buses which describes the difference between the buses: For addresses lower than 0x20000000, the D-Bus is used for data access and the I-Bus is used for instruction accesses. For addresses 0x20000000 or higher, the S-Bus is used for both instruction and data accesses.

So the processor acts as a Harvard architecture below 0x20000000 and von Neumann above that.

However, if we go back to the chip datasheet, in section 2.2.7 (after the page break) we see a diagram of the AHB bus matrix which interconnects the different buses to different memory components on the chip. We see that the I-Bus and D-Bus have access to the same memory components: Flash memory (via ACCEL), SRAM1, and FSMC Static MemCtl. So by taking a Harvard architecture and then connecting the I and D buses to the same memory, we turn it into what may as well be called a von Neumann architecture. We can assume that each memory region has the same address on all buses where it can be accessed, because otherwise the datasheet would say otherwise. It's convenient that each piece of memory only has one address. It would be possible to connect the processor so that the instruction at 0x00000000 is different from the data at 0x00000000, but the designers of the STM32F405xx did not do that.

There is a slight difference: the "data CCM" memory cannot be used for instructions as it's only attached to the D-bus. Your memory map does not show "data CCM" below 0x20000000 so I guess on your chip this difference does not exist. However there may be other differences between the I-bus and D-bus.

\$\endgroup\$
5
  • \$\begingroup\$ Thanks for your detailed answer! Just one more thing: if the instruction at 0x00000000 were different from the data at 0x00000000 that would mean that in the memory layout we were seeing two memory address spaces, right? \$\endgroup\$
    – gvg
    Apr 21 at 21:14
  • 2
    \$\begingroup\$ @gvg yes but I don't think the chip is doing that. Note the address space would be the same at 0x20000000 and upwards, because it uses the same bus. \$\endgroup\$
    – user253751
    Apr 22 at 9:26
  • \$\begingroup\$ yes I meant this last question in general, not in the specific case you described previously. Many thanks for your help and answers again! \$\endgroup\$
    – gvg
    Apr 22 at 9:39
  • 1
    \$\begingroup\$ Some STM32 models have instruction CCM, which also has access restrictions. But even then the addresses are not used for other purposes on the main bus. With 4 GB of address space for a chip with less than 1 MB of memory, there is no need to double-use. \$\endgroup\$
    – jpa
    Apr 22 at 9:45
  • 1
    \$\begingroup\$ Yes, even if the busses were connected to completely separate memory sections, it would be a good idea for the chip designer to give them different addresses to help catch programming mistakes. \$\endgroup\$
    – user253751
    Apr 22 at 9:46
15
\$\begingroup\$

The ARM Cortex parts are advertised as "Harvard Architecture", but they're really modified Harvard architecture.

Specifically, they use separate data and instruction caches, and (if I recall correctly) some memory areas are restricted from being used as instruction memory. But the entire memory space is available as data, even while at least some of it is available as instructions.

Most machines today that call themselves "Harvard Architecture" don't have fully separate memory spaces, and are thus some form of modified Harvard.

\$\endgroup\$
14
  • \$\begingroup\$ And how should I imagine this? I mean, there is 1 memory, attached to it separate D and I buses (that's why Harvard, or more precisely modified Harvard in our case, as you explained before) and the memory can solve that it can give us both data and instruction at the same time? I mean for some reason, it feels odd to me that it is just one memory / memory space but still it can give data and instruction at once. \$\endgroup\$
    – gvg
    Apr 21 at 16:38
  • 1
    \$\begingroup\$ @gvg no, the chip would manage to route the request to the correct memory unit instead depending on the address, but there would be a speed penalty if the chip had to fetch instructions and data from the same memory unit because it couldn't do both in the same clock cycle. If the chip worked this way. I don't know if it works this way. \$\endgroup\$
    – user253751
    Apr 21 at 17:21
  • 2
    \$\begingroup\$ @gvg The memory on your PC is composed of at least 16 and sometimes more than 128 individual DRAMs. The memory controller handles combining these into a unified memory space because having nonunified memory is annoying from a software perspective. MCUs typically work the same way, with tons of different stuff memory mapped into a single address space. \$\endgroup\$ Apr 21 at 17:24
  • 2
    \$\begingroup\$ @gvg Harvard isn't just having separate instruction memory and data memory. That's a good simplification. But it doesn't accurately convey the specific details for the delineation, which is the CPU's internal architecture, itself. ... What happens outside is then a matter of balancing a wide variety of engineering concerns. And it is here that you will find variations on themes. If TIm doesn't expand his answer, and if I find time to write something, I may add something to help clarify. But keep in mind this is inside-baseball CPU design, defining only a few necessary details. +1 on your Q. \$\endgroup\$
    – jonk
    Apr 21 at 18:06
  • 1
    \$\begingroup\$ @jonk as I see it "von Neumann" means one bus, "Harvard" means two completely separate busses, and everything in between is "modified Harvard" (for some reason never "modified von Neumann") \$\endgroup\$
    – user253751
    Apr 22 at 9:47
1
\$\begingroup\$

Many programs need the ability to use hard-coded constants within them. For example, to perform an operation like "x=12345" (in just about any common language), one needs a means of getting the number 12345 into a register. There are at least four approaches by which this may be accomplished:

  1. Some architectures like older versions of the PIC have instructions which are larger than the largest immediate value one might want to load, and thus allow any desired values to be included as part of the instruction without needing any means to treat the code space as data.

  2. Some architectures like MIPS and some newer ARM variants have instructions that can load half of a register, and which can be used along with a following "OR immediate" to load the other half, again without needing any means to treat the code space as data.

  3. Some architectures like older versions of the ARM include an instruction to fetch an arbitrary value from an address which is near the currently-executing code. While the ARM has facilities to express some numbers as immediate constants, code which needs to use larger values would be expected to have the required numbers placed in code space near the code that needs them, so they can be fetched with the "load nearby value" instruction. This approach requires the ability to treat code and data space interchangeably.

  4. It would be possible for an architecture to use constants stored at some read-only or pre-initialized area of the data space. This approach would not require the ability to treat code and data space interchangeably, but if applied to a microcontroller might require having a hard-wired partition between code and data storage (e.g. 12K of code and 4K of data). I don't know of any current designs that use such an approach, but would not be surprised if some early computers did this. If an instruction set included an instruction to load a value from a designated one of the first 1024 locations, a compiler and linker could arrange things so that if two compilation units both needed the value 0x08675309, it would only need to be stored once within that table. Architectures which expect constants to be stored near code blocks may be able to accommodate a larger total number of different constants, but would require that constants which are used by different functions be duplicated in every function where they are used.

While most of these approaches would work just fine with unrelated code and data address spaces, the ARM was designed approach #3 which requires the ability to place and load arbitrary constants at addresses which are located among the addressed where code will be placed and executed.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.