+--------------- | Aside: does anyone know why the "Harvard" approach was promoted from | being a trivial but important variation of Von Neumann to being of | equal rank, starting about 20 years ago?
+---------------
My guess would be the rise of separate I & D on-chip caches, which naturally leads to a Harvard approach inside the CPU/ALU pipeline, while the external memory interface remains (mostly) von Neumann [except for details of cache-flush/-invalidate ops needed to make the external memory be *truly* von Neumann].
Coincidentally, it was just over 20 years ago that AMD brought out the Am29000, which was a odd little Harvard hybrid (with *no* caches) with separate instruction & data busses and a *shared* address bus [and burst mode on both the I- & D-busses so once you'd started a burst on one you could use the address bus to start a burst for the other]. It may have had a small contribution to the terminology change in the
1987-1992 timeframe or so.
Though if the 29k had any real effect on long-term Marketing language, it was probably just that it caused other vendors with on-chip primary caches to look up and say, "Oh, *we* have a Harvard Architecture *too*, inside our CPU pipeline." [Which they did, all along, though nobody had talked about it that way much before.]
+--------------- | so, despite the nonsense in Wikipedia...
+---------------
Well, they did get this bit right, IMHO:
Modern high performance CPU chip designs incorporate aspects of both Harvard and von Neumann architecture. On-chip cache memory is divided into an instruction cache and a data cache. Harvard architecture is used as the CPU accesses the cache. In the case of a cache miss, however, the data is retrieved from the main memory, which is not divided into separate instruction and data sections. Thus, while a von Neumann architecture is presented to the programmer, the hardware implementation gains the efficiencies of the Harvard architecture.
+--------------- | and almost all programming languages have used separate code and data | "address spaces" since the invention of COBOL and FORTRAN, and were/are | always talked about as using the Von Neumann model (as they do).
+---------------
This seems to be conflating a number of issues which were more nearly orthogonal than your statement would lead one to believe:
- How programming languages [other than assembler] talked about "code" versus "data". Mostly, they didn't! They only talked about "data". How the code got into memory in the first place was magic buried in the operating system and/or the linker. [One exception was Lisp, which usually included a full compiler/linker within the run-time system, and thus needed to know how to get "data" to become "code". But even there the user programmer didn't worry about it. You said (COMPILE 'FOO) and FOO was now a compiled code object instead of an interpreted s-expression data object. Not really "separate" at the language level, then.]
- Sometimes "code" and "data" were split by (virtual) addressing only to separate access capabilities, as with the read-only "high segment" and read-write "low segment" of the DEC PDP-10. But note that even with this split, it was still a pure von Neumann machine: code could be fetched from either segment and a data LOAD from the high seg worked fine. There was still only one address bus & one instruction/data bus.
[Well, except in later models where the high seg could be read- and execute-protected if the program counter wasn't
*in* the high seg, and it could only get there by jumping to specific locations containing "PORTAL" instructions.]
- Some small-address-space machines needed to split the address space to get beyond the word-length limits of the machine. A classic example is the DEC PDP-11, which was initially a 16-bit von Neumann machine with 16-bit addressing, but which was later given 22 bits (or more) of physical addressing on the bus. User-mode (well, mapped) addressing was split into "code" and "data" accesses, and addresses could thus be re-used to double the effective virtual address space. [Since there was no way to store into "code" space, it became effectively read-only.] It was still von Neumann, though, even with that split.
Even weirder was the DEC PDP-8, which was a also pure von Neumann machine with 12-bit instructions/data, but in larger models with up to 15 bits of bus address. The CIF (Current Instruction Field) register held the upper 3 address bits of the current program counter. The CDF register held the upper 3 address bits used by *indirect* data references, but the upper 3 address bits for any direct data references came from the CIF.
- True Harvard splits at the hardware level the physical paths by which "code" enters the CPU and the physical paths by which "data" enters the CPU. The Am29000 was such a machine, although it *shared* the virtual address space [and the address bus itself] between code & data, and thus was Harvard in hardware and von Neumann in software. [Well, except that there really was *no* way for the software to read instruction memory as "data" if the system designer hadn't provided some "sneak path" between the I- & D-busses, so in its pure form the only way to store "data" in "code" space was as a sequence of load-immediate instructions.]
[Note that the 29000 was almost
*perfectly* tuned to be connected to video DRAM (VRAM or VDRAM) as its main memory, with the I-bus connected to the "serial" port of the VRAM and the A- & D-busses connected to the normal A & D ports of the VRAM. Besides giving the separate I- & D-busses needed for the Harvard architecture, it also provided the "sneak path" that you needed to be able to write "data" that could be later treated as "code".]
[Note#2: The Am20930 added on-chip I-cache (though
*not* D-cache!), and eliminated the separate I-bus pins. So at the bus level it was back to von Neumann. But the microarchitecture remained the same as the Am29000, so at that level it was still "Harvard".]
- Sometimes I & D were split because instructions and the data were of different widths!! E.g., the 8X300 with 16-bit instructions, 13-bit instruction addresses, 8-bit data, and just 9-bit data addresses (actually, two data spaces with 8-bit addressing on each, but sharing a single 8-bit data bus); the Microchip PIC 8-bit series, with 8-bit data and 12-, 13-, or 14-bit instructions (depending on model) and a mishmash of instruction addressing (depending on model/ROM size); etc.
Anyway, "code" & "data" were split or not for many different reasons, not just one, and sometimes it was just a partitioning of (virtual) addresses, sometimes a physical separation between busses; sometimes it was to increase bandwidth, sometimes to increase address space, and sometimes to separate access capabilities. If you look across all the architectures of the past 2-3 decades, somewhere you'll find a mix & match of almost all possible combinations of these reasons.
-Rob
----- Rob Warnock
627 26th Avenue San Mateo, CA 94403 (650)572-2607