EEVblog Electronics Community Forum

Products => Computers => Programming => Topic started by: 741 on August 27, 2020, 09:54:55 am

Title: Data bus width vs address granularity and 'word' size
Post by: 741 on August 27, 2020, 09:54:55 am
"A 16-bit CPU architecture has a 16-bit wide address bus" (https://en.wikipedia.org/wiki/16-bit_computing (https://en.wikipedia.org/wiki/16-bit_computing)). Therefore it can access (at most) up to 2^16 memory locations.

Now, how does it 'spend' that 2^16? If, like a 16-bit PIC, it is able to acess to a byte resolution, memory can only be of size up to 2^16 bytes. If however the machine can only operate at a "memory cell size" resolution, memory size (in bytes) can be a as large as 2^16 * (memory cell size). However in this case, we accept that accessing individual byes must involve 'unpacking' a machine word.

A 16-bit PIC data sheet describes a "DATA SPACE WIDTH" as follows

The data memory space is organized in
byte-addressable, 16-bit wide blocks. Data is aligned
in data memory and registers as 16-bit words, but all
data space EAs resolve to bytes.


Therefore, I notice two other things about the data memory
Is it correct to say it would be possible to have a 16-bit CPU architecture which, whilst it can access up to 2^16 memory locations, has a 'word size' of for example 1 byte, or 4 bytes?
That is: "16-bit CPU architecture" tells us how many memory locations can be accessed but it does not (necessarily) specify the word size of an individual location?

Also the resolution is a separate issue from the "architecture width" as per the micro chip example, where we can address any byte, even part way though a 16-bit 'word'.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: greenpossum on August 27, 2020, 10:06:38 am
Sure, and it's easier for Harvard architectures. Nothing says that the width of an instruction has to be the same as the width of address bus.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: Berni on August 27, 2020, 10:52:25 am
Its mostly from the fact that 16 and 32 bit CPUs can still do computation with 8bit bytes.

They have MOV like instructions that can move around 8bits at a time. So to avoid needing to have separate 8bit move instruction for loading in the top 8bits or the bottom 8bits from a 16bit word its easier to simply have 8bit address granularity.

A lot of data formats used in computing are based around bytes(just look at any ASCII based file format), so they also fit neatly in byte addressable memory. If you had 16bit addressable memory then you would either be using up twice as much memory to store the same thing or you would have to constantly deal with slicing the high and low byte apart as you go along.

So really the reason why byte level addressing is used is pretty similar to the reason why there are 8bits in a byte. Sometime someone decided it was a good idea to do it that way because it made something convenient, everyone else just did the same, it caught on and by now its so ubiquitous that its silly doing it any other way, so its stays that way for legacy reasons.

But not everything sticks to 8bit granularity. Some CPUs will get very upset with you and throw a fault if you try to load a 32bit integer from a memory location that is not aligned to 32bit boundaries(This is because these CPUs often internally have a 32bit bus with 32bit addressing granularity so doing such a operation is annoying, but still possible). There is also external memory with 16, 32, 64bit data buses that have the corresponding addressing granularity, but typically still have byte enable lines for disabling parts of the data bus in 8bit increments. This allows for writing only 8bits to RAM with a 64bit data bus (for reads the extra 56 bits are just ignored).

As for a CPU being 16bit that typically means that it has 16bit CPU registers and has opcodes for doing all of the major calculations on 16bits at a time. This rarely automatically means that it can addresses 16bit worth of memory (64KB). For example most 8bit CPUs can address more than 256 bytes of memory. But yes usually annoying to deal with tricks are often used to make them support more memory. Yet even when the CPUs own maximum address space is completely used up there still are tricks to swap in memory in banks externally (the 8bit and 16bit game consoles often used this to fit giant multi megabyte sized ROMs onto the tiny CPU)
Title: Re: Data bus width vs address granularity and 'word' size
Post by: 741 on August 27, 2020, 11:22:19 am
Thank you - this is starting to make more sense. I have now read ahead in the (PIC24FJ256GB210) data sheet and this is how PIC covers those points
Quote
The PIC24F instruction set supports both word and byte operations. As a consequence of byte accessibility, all EA calculations are
internally scaled to step through word-aligned memory.

For example, the core recognizes that Post-Modified Register Indirect Addressing mode [Ws++] will result in a value of Ws + 1 for
byte operations and Ws + 2 for word operations.

Data byte reads will read the complete word, which contains the byte, using the LSB of any EA to determine which byte to select.
The selected byte is placed onto the LSB of the data path.

That is, data memory and registers are organized as two parallel, byte-wide entities with shared (word) address decode, but
separate write lines. Data byte writes only write to the corresponding side of the array or register which matches the byte address.

All word accesses must be aligned to an even address. Misaligned word data fetches are not supported, so care must be taken when
mixing byte and word operations or translating from 8-bit MCU code. If a misaligned read or write is attempted, an address error
trap will be generated.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: T3sl4co1l on August 27, 2020, 11:38:06 am
You can do byte addressing by, basically, using the upper 15 bits as address in the usual way, and using the low byte to mux between the lower or upper half of the data bus.

On some machines, this was taken out as a bus signal, a byte enable.  For example, the 80386 is a byte-addressable 32-bit machine, and has four byte mask signals (IIRC), so that memory/devices can deliver the data exactly as requested.  An unaligned memory access (e.g., fetching a DWORD (4 bytes) from address 0xXXXXXXX2) causes the CPU to assert two addresses (the upper half of 0xXXXXXXX0 for the two low bytes, and the lower half of 0xXXXXXXX4 for the two high bytes) -- giving a significant speed penalty.

Others, misalignment is strictly prohibited; MIPS and ARM I think are this way?  Accessing a misaligned address triggers a protection fault.  Or enables certain operating modes, for example ARM "thumb" mode is enabled by jumping to 0xXXXXXXX1 or such -- that is, the low bit of the program counter is the instruction size flag.

As for address space, plenty of machines compose registers in some way to access more memory.  The AVR 8-bit ISA composes pairs of registers to work a 16-bit address space, as does Z80 and relatives, and arguably 8086 (the 8086 has 16-bit registers, several of which can be byte accessed; kind of the same thing, but with more emphasis on WORDs than BYTEs).

AVR also extends its address spaces (as a Harvard architecture, the program counter addresses Flash memory only, while everything else addresses the data bus) with special IO registers, allowing up to 24-bit range, though in a somewhat janky way (i.e. you have to load a value to a machine register, then store to the IO register, to form a full 24-bit pointer).

Still other machines address additional memory through mapping: with the help of external hardware, ranges of address space can be assigned to different ranges and different chips.  This was very common in the 8-bit era, when 6502s and Z80s reigned supreme (16-bit hardware address space), when large ROMs and RAMs were needed.  Examples include the Commodore 64, ZX Spectrum 128, NES, Gameboy, etc.  Or, probably most PCs of that time, whether by expansion bus, or onboard hardware.

(This is largely echoing what was said above; take this as agreement and repetition of ideas :) )

Tim
Title: Re: Data bus width vs address granularity and 'word' size
Post by: T3sl4co1l on August 27, 2020, 11:43:59 am
Thank you - this is starting to make more sense. I have now read ahead in the (PIC24FJ256GB210) data sheet and this is how PIC covers those points
Quote
The PIC24F instruction set supports both word and byte operations. As a consequence of byte accessibility, all EA calculations are
internally scaled to step through word-aligned memory.

Ahh, heh... speaking of hacked-together machines!

If you have the option, I would suggest migrating away from PIC, for this and other reasons.

AFAIK, Microchip evolved the PIC design over many decades.  It started as a register-lean 8-bit platform, much like the 6502, but with its own specializations and quirks; over the years, it was upgraded to sort-of-16-bit operation, and even 24.  So you'll see weird stuff, well, like that.  (The quoted portion does at least sound pretty reasonable; read carefully to see if other instructions don't support the same addressing modes, for example.  And always, ALWAYS, read the errata!)

I've not worked with PIC, and only read about it lightly, so take this with a grain of salt.

(My understanding is also that the 24E is, for some reason, the real ugly one of the series... which some coworkers had to deal with to some extent, on a project some years back.  Thankfully, I'm a hardware guy, not software? :-DD )

Tim
Title: Re: Data bus width vs address granularity and 'word' size
Post by: tggzzz on August 27, 2020, 11:47:30 am
Just to ram home the points that others have made, consider two "big iron" machines.

The DEC alpha originally accessed only words; I believe that was later modified.

The Elliott 803 (and similar) had a maximum of 8192 words, each containing 39 bits. Each word contained two 18 bit instructions plus a modifier bit.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: Berni on August 27, 2020, 01:04:43 pm
Yeah the Microchip PIC architecture is often... well... special in its own way.

The 8bit PIC designs come from back from the dark ages of chip fabs where they needed to keep the transistor count as low as possible in order to produce these MCUs for such a cheep price. As a result the design for them is really cut down to the bare minimum of what a still useful MCU could be. Most of the weird design choices in PICs are in some way connected towards saving transistors. Later on as these tiny designs moved onto more modern fab nodes they got some impressively low power chips as there was barely anything inside to use up power.

The 16bit PICs are the first pics that are reasonably nice to program for and are much better suited for running C code. I even ran FreeRTOS on one and it worked well.

But these days if you are developing a project from the ground up its best to just go for a 32bit ARM. There are plenty small cheap and low power ARM chips out there. its a more modern powerful architecture, C compiler support is 2nd only to x86, the addressable memory space is essentially infinite from a MCU viewpoint, a lot of chips even have proper hardware floating point. Its pretty much the power of a 486 PC in a single chip that draws miliwatts.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: SiliconWizard on August 27, 2020, 03:47:18 pm
A 16-bit CPU architecture has a 16-bit wide address bus (https://en.wikipedia.org/wiki/16-bit_computing (https://en.wikipedia.org/wiki/16-bit_computing)).

This is starting off badly IMHO. I remember an earlier (somewhat "heated"?) thread about what was really called an n-bit CPU. I would, in general, disagree with the fact it's about the width of the address bus, although it's sometimes used this way. Most CPUs that I know of are not defined this way actually, at all, be they 8-, 16-, 32- or 64-bit CPUs. It's a lot more common that this refer to the data bus width, or sometimes even the register width. Remember the 68000. They were considered 32-bit CPUs (sometimes called 16/32 though), with a 16-bit data bus, 32-bit register width and 24-bit address bus. Dang.

Many 8-bit CPUs had a 16-bit address bus. We wouldn't call them 16-bit CPUs. Likewise, 16-bit CPUs usually had address busses wider than 16-bit. These days, 64-bit CPUs often have address busses that are only 48-bit.

The width of the data and address bus match only on a limited range of CPUs out there actually. They often don't. In any case, a given CPU of course needs some kind of bridge between the two spaces unless they are strict Harvard. But even just for data, a decent CPU usually has instructions to deal with 8-bit to n-bit words whatever the native width is, otherwise programming would be very clunky and inefficient for a whole range of applications.

So yeah, not only do I not agree with your "definitions", but accessing words with a different width than the "native" width has been very common for decades. Am I missing anything?
Title: Re: Data bus width vs address granularity and 'word' size
Post by: radiogeek381 on August 28, 2020, 02:42:46 am
Quote
The DEC alpha originally accessed only words; I believe that was later modified.

Yup.  The 21064 did all memory references as 64 bit transfers.  It made manipulation of byte strings problematic. Getting rid of all the byte-merge-read-modify-write-merge machinery for stores simplified implementation but spilled too much performance. Byte load and store were added in the 21164 generation.

Not to pour oil or gasoline on the fire -- interpret N-bit processor however you want. 

but

As a designer, modeler, and programmer of processors with 8, 12, 16, 32, 64 and other word sizes over the past 40 years, when you tell me I'm going to design an N-bit machine, I'll assume that the programmer-visible width of the register file is N bits.  That is, for the bread-and-butter operations, the data size is N.  There may be sub-word operations.  There may be extended word operations.  There may even be SIMD or vector operations.  But the register file(s), and the adder(s) are going to be optimized as N bits wide. 

External interfaces don't really play into it with "larger" processors, as the transfer width in and out of memory is a bandwidth-latency-power-pincount tradeoff if it isn't already determined by external market forces.  And any machine with a cache is going to have a block size bigger than one word: the block size will have some influence on the width.

Some will remember the "16-bit" 8088 -- an 8086 inside with an 8 bit data path on the outside. It was intended to ease the transition from 8080 designs to the new 16 bit product line.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: helius on August 28, 2020, 04:02:08 am
The Intel 8088 has an 8-bit data bus, a 20-bit address bus, and 16-bit registers that overlay 8-bit registers. So is it 8-bit, 16-bit, or ???
The more interesting question, apart from just how many bits are used for various things, is how they get there. In the 8088, the addresses are generated from pairs of 16-bit registers, with the upper register holding a "segment" that is shifted left by 4 bits and added to the address operand. So to get 20 bits of address, it takes 32 bits and wastes 12! There's an interesting story around the ill-starred APX432 that sort-of explains why it was done that way.

Even more egregious, you now hear people talking about "8-bit graphics" referring to Apple ][ or IBM CGA era. 2 bits per pixel isin't nearly 8...
Title: Re: Data bus width vs address granularity and 'word' size
Post by: Berni on August 28, 2020, 05:44:20 am
Yep the strange 20bit addressing leading to the 640KB memory wall(the rest reserved for BIOS and IO) on PCs that made using more memory than that in DOS really annoying.

But pretty much all tricks of making a 8 or 16bit CPU support more than 256 or 64K of memory tend to be annoying in some way. One of the rare non annoying ones is Intel PAE (Physical Address Extension) that uses the 32bit era well established virtual memory addressing to map in memory above 4GB without the applications even knowing it. This only really makes sense on modern multitasking OSes where no single application uses up all of the memory for itself. Tho Windows didn't really support it properly like Linux did.

At least now that we got to 64bit we have plenty of memory addressing space to last us quite a while.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: JPortici on August 28, 2020, 06:13:48 am
Sure, and it's easier for Harvard architectures. Nothing says that the width of an instruction has to be the same as the width of address bus.

Case in point, the PIC24/dsPIC program memory is 24bit wide, with at most 24bit wide address (i don't remember exactly, but between 20 and 24)
They made the flash to be accessible from the data bus so it was easy to read constants (with, i think, no cycle or one cycle penality. have to recheck) but due to the limited address bus size you again have to resort to memory paging. the lower 32k or memory are ALWAYS RAM, containing also the SFRs. The upper 32k can be either the upper 32k of RAM or program memory, in 32k wide pages. Good thing about this is that then the dsp can fetch constants from flash with no higher cycle penality. However it makes acces slower for really, really big applications where mixed access is required

Tim, try dsPIC. They're amazing in terms of hardware and software. They're my most favourite controllers for dealing with hardware. What many ARM do by increasing clock speed to absurd levels, dsPICs can do with the peripherals and dsp. I'll leave arm to fancy UIs and networking
Title: Re: Data bus width vs address granularity and 'word' size
Post by: Berni on August 28, 2020, 06:43:38 am
Yep the 32KB RAM addressing barrier is about the only annoying part i have with 16bit PICs. When i was doing FreeRTOS on one i resorted to only using the bottom 32K as stack and heap since this made C pointers way easier.

I think i had 48KB of RAM in total on that one so the upper 16KB ended up being used for large buffers like FIFOs that got specifically designed to handle this higher RAM area and its special ways of accessing it.

The upper memory being a window into flash is actually very useful tho. This finally fixes the issue that Harward architectures have with constants in flash. The C compilers never had any elegant way of handling it so they either had you use weird special flash pointers, special macros, or simply just copied over all of your string constants into RAM on startup eating up tons of memory. But with this flash window it can now handle them just like a von neuman machine.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: JPortici on August 28, 2020, 07:40:21 am
Agree 100%
Modified harvard is the best
(oh, by "try dsPIC" i mean the dsPIC33E and dsPIC33C the 30F and 33F were shit, just fancy PIC24
Title: Re: Data bus width vs address granularity and 'word' size
Post by: 741 on August 28, 2020, 08:15:37 am
I asked the original question because I was wondering about the size of a C pointer on a given machine. The data "address range" is 2^16 bytes for the PIC mentioned. Therefore I think a C compiler must use 16-bit pointers - and all 16 bits in that pointer are potentially significant (depending on how much data memory is implemented).

As I see it though: On a Harvard machine, a function pointer might conceivably need a different size (from a data pointer)  but the size of the program memory bus would need to differ from the data memory bus by at least 8 bits for this to make a difference to the size of a pointer (as measured in 8-bit bytes).


After seeing Silicon Wizard's comments I have (now) placed quotation marks around "my" definition, with which this thread began, to emphasise it is taken from the link given - Wikipedia. (I gave the link because I was unsure of the definition). I had never been certain of what N-bit architecture meant, although terms like that are often used. After reading the comments on this thread, I think there is no single correct answer.

Microchip (and others) categorise their processors by "bits". Is there inconsistency in the way say Microchip, ARM, Intel etc list their products as being N-bit?
Title: Re: Data bus width vs address granularity and 'word' size
Post by: JPortici on August 28, 2020, 08:54:30 am
From MPLAB: XC16 C Compiler User’s Guide
All standard data pointers are 16 bits wide. This is sufficient to access the full data
memory space.
These pointers are also able to access const-qualified objects, although in the program memory space, const-qualified objects appear in a unique memory range in the
data space using the PSV window. In this case, the -mconst-in-data option should
not be in force (see Section 5.7.1 “Options Specific to 16-Bit Devices” for more information.)
Pointers which access the managed PSV space are 32-bits wide. The extra space
allows these pointers to access any PSV page.
A set of special purpose, 32-bit data pointers are also available. See Chapter
10. “Memory Allocation and Access.” for more information

the 32bit data pointers are those that can access the extended data space (over the first 32k of ram, also including the external memory interface/parallel master port)

regarding "bits", as i probably said in that heated argument mentioned earlier, i define the "bitness" of a CPU the size of the internal registers. PIC16 is 8bit, the accumulator and CPU work on 8bit at a time. dsPIC is 16bit (and even though the DSP is 40bit you have to load it 16bit at a time, or the dual data fetch operate on two 16bit words). PIC32, ARM cortex M is 32 bit.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: Berni on August 28, 2020, 09:49:43 am
I asked the original question because I was wondering about the size of a C pointer on a given machine. The data "address range" is 2^16 bytes for the PIC mentioned. Therefore I think a C compiler must use 16-bit pointers - and all 16 bits in that pointer are potentially significant (depending on how much data memory is implemented).

As I see it though: On a Harvard machine, a function pointer might conceivably need a different size (from a data pointer)  but the size of the program memory bus would need to differ from the data memory bus by at least 8 bits for this to make a difference to the size of a pointer (as measured in 8-bit bytes).


After seeing Silicon Wizard's comments I have (now) placed quotation marks around "my" definition, with which this thread began, to emphasise it is taken from the link given - Wikipedia. (I gave the link because I was unsure of the definition). I had never been certain of what N-bit architecture meant, although terms like that are often used. After reading the comments on this thread, I think there is no single correct answer.

Microchip (and others) categorise their processors by "bits". Is there inconsistency in the way say Microchip, ARM, Intel etc list their products as being N-bit?

On weird harvard architecture machines like PICs it really depends on how the C compiler wants to deal with it. The address 0x10 points to something in RAM while address 0x10 in flash points to somewhere in flash. So for C to be able to tell those apart extra stuff needs to be done on top. Often they implement a special proprietary pointer type that can point to flash and as said above this pointer may need to be larger to cover all of the address space.

On 8 bit PICs pointers are even more annoying because the pointer needs to first be decoded into what bank it points to, switching the bank correspondingly and then grabbing the data from the right location in the bank. Combined with its tiny number of registers this makes the line "*some_ptr = 5;" take a crap ton of cycles to execute. But these CPUs ware never designed to execute such high level C code.

But in general a pretty well agreed upon definition of the number of bits of a CPU is the size of the registers and the data size all the common opcodes can work with (Like mov,add,and,xor,bitshift), this is usually because the internal data buses inside the CPU are that size. But you have to ignore any special snowflake opcodes that work with more bits. For example modern Intel chips that support AVX512 have opcodes that do SIMD math with 512bits at a time, yet we still call them 64bit CPUs
Title: Re: Data bus width vs address granularity and 'word' size
Post by: magic on August 28, 2020, 10:16:10 am
But pretty much all tricks of making a 8 or 16bit CPU support more than 256 or 64K of memory tend to be annoying in some way. One of the rare non annoying ones is Intel PAE (Physical Address Extension) that uses the 32bit era well established virtual memory addressing to map in memory above 4GB without the applications even knowing it. This only really makes sense on modern multitasking OSes where no single application uses up all of the memory for itself. Tho Windows didn't really support it properly like Linux did.
It sounds non-annoying to an application programmer. It's a PITA to a kernel which needs access to all of that RAM but can't have it mapped into its own address space permanently.

Furthermore, if a kernel is written to use simple 32 bit pointers for its internal allocations (like any pre-PAE x86 kernel such as Linux or Windows) then it simply cannot use memory above 4G for its internal allocations, or it uses it only for a few subsystems which have been rewritten to deal with PAE. So you might be able to use your 8GB for applications and maybe page cache, but not for the in-kernel network stack or hardware drivers.

IIRC Linux also insists (or insisted in the past) on keeping page tables in the "low" memory, and those alone clogged up most of it on a fully loaded (64GB?) PAE system. I think I have seen such warning in documentation somewhere.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: T3sl4co1l on August 28, 2020, 10:47:47 am
Indeed, pointers can have different sizes; which is no shortage of annoyance to a C compiler I'm sure.  How much is a size_t?  How much do you want it to be?...

Like the 8086's short and long pointers (16 and 32 bits).  I know the usual DOS approach was specified with a range of strategies: "tiny", "compact", "large", "huge"... these being motivated by how many segments you used in your program, for code and data.  (Or at least MASM used these terms.)  A small program might use one code segment and one data segment, and never have to worry about setting segment registers; a "large" or "huge" program is expected to have many, and to handle segments and long pointers as a matter of fact.  For C, the compiler would need to know segment allocation in order to generate the appropriate jumps/calls and pointers.  Maybe this was specified with command line switches, maybe it was determined at compile time, I don't know (I've not used a 8086 C compiler, actually).

Tim
Title: Re: Data bus width vs address granularity and 'word' size
Post by: andersm on August 28, 2020, 02:06:12 pm
The MSP430X is another oddball - a 16-bit architecture with 20-bit pointers.

Even more egregious, you now hear people talking about "8-bit graphics" referring to Apple ][ or IBM CGA era. 2 bits per pixel isin't nearly 8...
It's shorthand for "graphics typical of 8-bit computers and game consoles of the early- to mid-80s."
Title: Re: Data bus width vs address granularity and 'word' size
Post by: SiliconWizard on August 28, 2020, 04:28:00 pm
I asked the original question because I was wondering about the size of a C pointer on a given machine. The data "address range" is 2^16 bytes for the PIC mentioned. Therefore I think a C compiler must use 16-bit pointers - and all 16 bits in that pointer are potentially significant (depending on how much data memory is implemented).

This is entirely implementation-defined. There is certainly no general rule here.

A "pointer" may not even fit into a single register. Typically, for segmented memory. The x86 comes to mind, but not just that. Even some PIC MCUs have some kind of segmented memory (I'm of course thinking of the early PIC 8-bitters, but also the 16-bitters with some "extended" memory). In this case, a "pointer" will actually hold several values, typically such as an 'offset' and a 'segment' or 'page'.

The "size" of a pointer will not just depend on the memory model of the CPU, but also on the "memory model" used by the compiler. For instance, for CPU using segmented memory, it's common that the compilers offer different "memory models" - often a "small" one, in which "pointers" will typically hold only an offset, then a "large" one, in which pointers will hold the offset+page+anything else needed for memory access, and sometimes models in between, optimized for different use cases. So that really depends not just on the architecture of the CPU, but often on compiler options as well.

A final thought about this - if this is what you're wondering about: when in doubt, always look that up in the compiler's user guide, as (as I said) it will always depend not just on the CPU itself but on the compiler as well and often on associated options. If you need to know the "size" of a pointer within the code, use sizeof(). This will guarantee that your code is portable whatever the compiler and options. And if you need to store pointers into integers for some reasons, please use the standard (since C99) types intptr_t/uintptr_t instead of having to guess (and taking the risk of truncating your pointers and/or make your code absolutely non-portable and hard to maintain.)
Title: Re: Data bus width vs address granularity and 'word' size
Post by: Doctorandus_P on August 28, 2020, 10:59:11 pm
(almost ?) all micro processors use byte addressing for "logical" addresses, but use "word" addressing for accessing the hardware.

32-bit class processors are (usually) attached to 32-bit wide memory, but the internal address layout is often still in bytes. x86 bumped into a problem that 32 bit OS could not address more then 4GiB, which is 2^^32 in Bytes, not 32 bit "words". The 2 least significant bits are then not connected to the external memory, but only used for indexing into the words read from the external memory. Writing to a single byte requires a read / modify / write cycle.

But there are variations on this. For example some Flash based microcontrollers which read data in 128 bit wide chunks to reduce wait states because Flash is slow. When you keep everything on the die, you can do all kinds of tricks transparent to the user.

Very early computers often had deviating word sizes. for example https://en.wikipedia.org/wiki/PDP-8 (https://en.wikipedia.org/wiki/PDP-8) had a word size of 12 bits. Possibly the concept of a "Byte" with 8-bits was not even in common use back then.

The historical Cray-1 used 32 bit memory, and probably 32 bit was the only addressing mode. But that one is also from the '70ies and pretty old (though impressive at that time).
https://en.wikipedia.org/wiki/Cray-1 (https://en.wikipedia.org/wiki/Cray-1)

Some small harvard based microcontrollers such as PIC and AVR use 12 or 14 bit words for program memory and 8bit wide Bytes for data.

Then there is also compiler optimization.
With some ASM instructions, a part of the instruction itself can be reserved for indirect addressing, relative to the location of the instruction in memory.
Because all code is in Flash and therefore has static addresses, compilers can do fancy tricks with optimization and figure out a way to put the pointer you use in C directly into such an ASM instruction.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: tggzzz on August 29, 2020, 01:01:26 am
Very early computers often had deviating word sizes. for example https://en.wikipedia.org/wiki/PDP-8 (https://en.wikipedia.org/wiki/PDP-8) had a word size of 12 bits. Possibly the concept of a "Byte" with 8-bits was not even in common use back then.

Some machines did indeed have 6-bit bytes.

Quote
The historical Cray-1 used 32 bit memory, and probably 32 bit was the only addressing mode. But that one is also from the '70ies and pretty old (though impressive at that time).
https://en.wikipedia.org/wiki/Cray-1 (https://en.wikipedia.org/wiki/Cray-1)

There were many word sizes, I can think of 1, 4, 8, 12, 16, 24, 32, 36, 39, 60, 64 bit words, and the intel 3000 and AMD2900 could be whatever was convenient. I expect there were others.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: westfw on August 29, 2020, 07:12:22 am
Quote
A 16-bit CPU architecture has a 16-bit wide address bus (https://en.wikipedia.org/wiki/16-bit_computing (https://en.wikipedia.org/wiki/16-bit_computing)).
It actually doesn't say exactly that.  Which is good, because it would be wrong.  It does go on to explain that various means can be used to extend the address range.  (but especially: an "8-bit CPU Architecture" has NEVER meant an 8-bit address bus.  Even the 8008 had a 14bit address bus.)

My first love, the DEC PDP-10, had a 36bit word and an inherently 18-bit address bus (addressing a word at a time.)It also had special instructions for dealing with bytes within words, including a special "byte pointer" pointer that included bit position and byte size (so aside from 36bit words and 18bit halfwords that were "commonly used", it could deal with bytes of any size from 1 to 36.  Six (uppercase "sixbit" codes), and seven (ASCII - 5 bytes per word.  And an extra bit to tag, say, line numbers rather than actual content.)

Quote
how does it 'spend' that 2^16? If, like a 16-bit PIC, it is able to acess to a byte resolution, memory can only be of size up to 2^16 bytes. If however the machine can only operate at a "memory cell size" resolution, memory size (in bytes) can be a as large as 2^16 * (memory cell size). However in this case, we accept that accessing individual byes must involve 'unpacking' a machine word.
"it varies."  For example, if you look at a lot of 32bit processors (like the ARM), they'll usually implement a form of indexed addressing like:
Code: [Select]
  LDRx destRegister, [indexRegister, offset]
"indexRegister" is 32bits wide, so the final address is going to be 32bits.  But "offset" is a constant, and has to fit into the instruction, which is as most 32bits itself, so "offset" is smaller than 32bits, limiting the range FROM the index.  It's desirable to have the range be as large as possible, so for LDRs of "words", the offset is multiplied by 4, for halfwords it's multiplied by 2, and for load byte it's just added.(the "load reg, memoryAddress" where memoryAddress is a full-width constant number (like AVR's LDS R1, 0x1234) doesn't exist!)

IIRC, x86 has something similar where an index can be multiplied by the operand size (but it's not as limited to range, since x86 has variable length instructions. (?)) 

Quote
I asked the original question because I was wondering about the size of a C pointer on a given machine. The data "address range" is 2^16 bytes for the PIC mentioned. Therefore I think a C compiler must use 16-bit pointers - and all 16 bits in that pointer are potentially significant (depending on how much data memory is implemented).
Writing a C compiler for a chip that doesn't have byte addressing is really annoying; C really wants pointers to be consistent, and point to the smallest accessible object size (this is one of the reasons that C doesn't have "bit" variables.  Not enough chips support a "pointer to a bit.")  8086 was pretty painful (two pointers to the same memory might not be identical.)   There was a really smart guy who wrote a C compiler for the PDP-10, but it took a long time...
Title: Re: Data bus width vs address granularity and 'word' size
Post by: 0db on August 31, 2020, 04:12:09 pm
the DEC PDP-10, had a 36bit word

Why did it have 32+4 bit word rather than just 32?
Title: Re: Data bus width vs address granularity and 'word' size
Post by: helius on August 31, 2020, 04:19:18 pm
the DEC PDP-10, had a 36bit word

Why did it have 32+4 bit word rather than just 32?

32 bit words were not popular at the time. It's easy to suppose that they are "natural" today when every computer settled on 8-bit bytes and 32-bit words, but at the time there was much more diversity.

With 36 bits, you can write the contents very nicely in octal, as 012345,,012345 (left and right 18-bit halves). Since each instruction word contains an 18-bit address, you can access any of 262,144 addresses directly, which is also nice. That was a huge amount of memory in 1968. If your word was 32 bits, byte addressed, and you only had a 16-bit address field, you would have been limited to 64KB, which is 18 times smaller.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: T3sl4co1l on August 31, 2020, 05:54:24 pm
There have been some odd machines through history; like one was a, 29-bit instruction?, basically every bit was a different enable for the various buses and latches in the CPU (registers, ALU, buses).  Drum based storage wasn't it?  Makes for very fast code (aside from the cycle time of the storage medium!), but quite bulky, and leaves little room for immediate values or addressing.

(The way CPUs are usually designed, is a state machine associated with each module.  Instructions come in, are decoded into a short sequence of enable signals, out of the hundreds of enables total; and these do the various things, direct data here and there, activate buses, read and write data, compute values, etc.  The states are often stored in ROM -- microcode.  Some of the enables decode the ROM itself, so the microcode can control itself arbitrarily -- allowing them to implement lengthy operations, like longhand multiplication or division, without having to synthesize logic for it.  This is very typical of 80s era CPUs, the 8086 for example has a huge chunk of microcode ROM on it.  I suppose modern CPUs still do things the same general way, but mind they are far more complicated thanks to pipelining, and the great variety of modules (instruction decode and dispatch, micro-ops, cache..) used.)

Tim
Title: Re: Data bus width vs address granularity and 'word' size
Post by: tggzzz on August 31, 2020, 07:30:47 pm
The Intel iapx432 had instruction lengths between 6 and 321 bits.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: helius on August 31, 2020, 07:50:53 pm
Pikers... the VAX can have instructions up to 4 gigabytes long!
Title: Re: Data bus width vs address granularity and 'word' size
Post by: westfw on August 31, 2020, 11:18:25 pm
Quote
Why did it have 32+4 bit word rather than just 32?
If you don't care about byte addressability, word size doesn't matter.   There were actually several 36bit CPUs around at the time - apparently (WP) 36bits matched up well with the 10digit accuracy of mechanical calculators.  A fair number of printers and etc were uppercase only, so you could represent a pretty complete alphabet in 6bit characters.  There were CDC mainframes with 60bit words...
Title: Re: Data bus width vs address granularity and 'word' size
Post by: SiliconWizard on September 01, 2020, 12:11:13 am
Quote
Why did it have 32+4 bit word rather than just 32?
If you don't care about byte addressability, word size doesn't matter.   There were actually several 36bit CPUs around at the time - apparently (WP) 36bits matched up well with the 10digit accuracy of mechanical calculators.  A fair number of printers and etc were uppercase only, so you could represent a pretty complete alphabet in 6bit characters.  There were CDC mainframes with 60bit words...

Yes of course. In this case the smallest usable word size is the native size, which can be anything. Although it can be quirky (or inefficient/a waste of resources) in some applications, it can be a good fit for others. Especially for calculators as you mentioned. If you only manipulate "numbers", and those are represented with words of a given size larger than a byte or not even a multiple of a byte, what's the problem? Some CPUs made for calculators were designed this way.

And even so, given you have the usual set of arithmetic and logic operators, you can usually always manipulate those words to access smaller chunks if needed - it will just be "inefficient".
Title: Re: Data bus width vs address granularity and 'word' size
Post by: rsjsouza on September 01, 2020, 12:13:49 am
On modern days, the C5000 and (IIRC) the C2800 families of DSPs from TI have a 16-bit byte.
Title: Re: Data bus width vs address granularity and 'word' size
Post by: T3sl4co1l on September 01, 2020, 07:07:51 am
That's pretty common, even; I'm just playing with a Flash chip that's organized that way.  It's 512k x 16 bits, addressed with lines A0-A18.  So, word addressable.  In a byte-addressable 16-bit system, these would be A1-A19.  There is an 8-bit mode, in which case D8-D15 are always tristate, and D15 is repurposed as... "A-1"! :-D

I'm also playing with a display controller, that's organized in the latter way.  It has a 16-bit bus, which is byte or word addressable.  The interface manifests as 4 contiguous (byte) addresses in the IO space: index register low, index register high, data register low, data register high.  (The index/data selection is made with a single pin (D/C#) wired to A1.)  As it happens, the high byte is completely unused for all internal registers, except for writing the graphics data port.  When wired to a byte-addressable 16-bit bus, the chip presents both bytes at once; the bus itself decides which byte (or both) to take.

Tim