Data memory and Instructions on PIC18F4321 - memory

We are studying the PIC18F4321, and at some point my professor drew the following diagram on the board:
He made it look like instructions (such as ADDLW 0X02, MOVWF 0X24, etc) will take two addresses in data memory, because memory addresses in the PIC18F4321 only take a byte and instructions are 16 bits wide.
But in the datasheet of the PIC18F4321, I cannot find where it says that these 16 bits instructions will ever be stored in data memory. Before he said that, I had in mind that the data memory was for storing register values, not full instructions. On the other hand, I know that there is also program memory, but program memory it is not 8 bits wide, which makes his drawing even more confusing.
1) Are 16 bits instructions ever stored in Data Memory?
2) One way I found of trying to explain the picture is that perhaps the memory in question is not necessarily 8 bits wide, it is just that every address can only take 8 bits. So <8> would be simply stating how many bits you can hold in that address. Would this be a reasonable explanation?

1) Are 16 bits instructions ever stored in Data Memory?
No. Data memory is not used for storing instructions - you cannot execute any code from data memory. All instructions are stored in program memory, which consists of 16 bit instruction words. The datasheet details the format and layout of the different instructions. Some instructions are single word, some require multiple words. The program memory is addressed by a 21 bit program counter, which encompasses a 2Mbyte space although for the PIC18F4321 there is just 8Kbytes of program memory, which equates to 4096 single-word instructions.
Data memory consists of 8 bit bytes, addressed by a 12 bit bus, which allows up to 4096 bytes of data memory although the PIC18F4321 has just 512 bytes of data memory, split into two banks of 256 bytes. This data memory contains the SFR's (special function registers) and the general purpose registers (GPR) that you use in your application.
All of this is explained in greater detail in the datasheet for this device, specifically in Section 5.
The way that program memory is addressed by the program counter (PC) enforces the 16-bit instruction word alignment by forcing the least significant bit of the PC to zero, which forces access in multiples of two bytes. Quoting from the datasheet:
The PC addresses bytes in the program memory. To prevent the PC from
becoming misaligned with word instructions, the Least Significant bit
of PCL is fixed to a value of ‘0’. The PC increments by 2 to address
sequential instructions in the program memory.
I suggest that you thoroughly read Section 5 of the linked datasheet and see if you have any remaining doubts. It contains a lot of detail, but it is well described even though it will take more than one reading to understand it completely.

Related

how ram and rom size is depend on cpu? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
I am very interested to know how CPU is working. let say in 8-bit microcontroller(8051) how ram and rom in depends on cpu? according to these topics, I have some question in my mind which is confusing me. like
1 = how to ram and rom size is defined(in 8051 microcontroller)?
2 = what means of 8-bit controller?
3 = is rom size is depend on CPU size? if not so how much rom I interface with 8-bit controller?
I searched more regarding to this my questions but not found any solutions so please help me
and is there any have some document and books(microcontroller) so please suggest me
Thanks,
Not much different than the above answer...
In all of this there are no definitive definitions, they are often a slang or engineer speak or marketing speak for things. 8-bit is a little bit more firm, with exceptions. It implies that the processor operations or maximum size of the bulk of the operations is 8 bits wide, so an 8 bit wide alu if you will. Some folks try to make the register size define the bit size, the instruction size, some the number of address bits on the cpu core, etc. So is an x86 an 8-bit, 16-bit, 32-bit, 64-bit, 128, 256, 512 or 1024 based on above notions? could be any depending on who you ask...
The 8051 is considered 8-bit based on the time frame and that most things in it are 8 bit in size.
The 8051 has been so heavily cloned and as mentioned banking is sometimes used to expand the memory space, so it depends on the specific cpu/part/core you are using as to how much total it can access. ROM/RAM sizes are also specific to the part you are using, you start with the datasheet from the part vendor and then as needed other documentation. The part/IP vendor is the definitive source for RAM/ROM information for the 8051 variant you are using at any particular time.
Microcontrollers in general not just 8051s will tend to have more ROM/FLASH than RAM, it should be obvious why when you start writing applications and see that you need more of one than the other.
As answered by Guna the maximum addressing space is determined by the number of address bits on "the bus", but as mentioned above that can/will vary by implementation, there are some that can address a megabyte some that can only address some number of K bytes.
Some CPU architectures are more controlled than others, either by documentation and versions or by ownership and control of the IP (no clones that survive lawsuits for example). So some will have a fixed address space size and currently have no exceptions, but then there are those like the 8051 that have been cloned so heavily (8051s are still widely in use, there is a good chance your computer has at least one, if not the servers along the internet and websites like this definitely will) both their original clocking scheme and address space options vary from implementation to implementation. So this is not a case of the CPU name/type/brand determines maximum amount of ram/rom, and it almost never will determine the exact amount of each you have in a specific implementation, a specific chip or board.
It is very easy to find 8051 information, countless websites, more than there is space to provide links. Start with some chip vendors still actively producing 8051 chips. Silicon labs, microchip, cypress, and perhaps others.
For example it took only a few seconds to find a datasheet for a specific part that states:
512 bytes RAM
8 kB (F990/1/6/7, F980/1/6/7), 4 kB (F982/3/8/9), or 2 kB (F985) Flash; in-system programmable
The price of the part is heavily influenced by the ROM/FLASH size and the RAM size, so a particular family of parts will essentially have the same design with different sized memories depending on your needs, if you can keep the program smaller you can buy a part that is say a dollar less than another in the family but may have the same footprint so that design for the larger one and switch to the smaller one or vice versa hope for the smaller one and if your program is too big then have to switch to the bigger one and deal with the profit loss.
Please find below answers for your questions as per my knowledge.
1) The 8051 microcontroller's memory is divided into Program Memory and Data Memory. Program Memory (ROM) is used for permanent saving program being executed, while Data Memory (RAM) is used for temporarily storing and keeping intermediate results and variables.
2) an 8-bit microcontroller processes 8-bits of data at any particular time. The number of bits used by an MCU (sometimes called bit depth or data width) tells you the size of the registers (8 bits per register), number of memory addresses (only 2^8 = 256 addresses), and the largest numbers they can process (again, 2^8 = 256 integers, or integers 0 through 255). An 8-bit microcontroller has limited addressing, but some 8-bit microcontrollers use paging, where the contents of a page register determines which onboard memory bank to use.
3) Yes, The maximum rom size can be addressed by CPU depending of the width of address bus. for example in 8085 microprocessor the width of the address bus is 16bit so it can address upto 2^16 = 65536 (8 Bit values).

Determine how many memory slots are available in a specific computer?

Im studying assembly langauge on my own with a textbook, and I have a question that talks about the memory of a computer. It says the possible memory in a 32-bit PC is 4,294,967,296, which is 4GB. This is because the last memory location is FFFFFFFF base 16 (8 F's there). It also goes on to say that 2^10 is 1KB, 2^30 is 1GB etc. It also addresses 64-bit machines, saying 64 bit mode can internally store 64-bit addresses and "that at the time this book was written, processors use at most 48 bits of the possible 64". It goes on to say that this limitation is no match, because it could address up to 2^48 bytes of physical memory (256TB) which is 65,536 times the maximum in 32-bit systems. It also finally talks about RAM and how it basically provides an extension of memory. Okay okay, so I just wanted to tell you what my book has been telling me, and so it possesses a questions:
Suppose that you buy a 64-bit PC with 2 GB of RAM. What is the 16-hex-digit of the "last" byte of installed memory?
And I tried to tackle it by saying we know from the boook that 2^30 = 1GB and I said, 2^x = 2GB. I then knew that one physical address is one byte, so I converted 2GB to the respective amount of bytes. I then I took the log of base 2 of how many bytes I got to solve for x. I got 2^31 in the end, but that was a lot of work. I then converted it to hex giving me 80000000 base 16. And I was stumped then. I look at the answer in the back of the book and it says this:
2 * 3^20 = 2^31 = 80000000 base 16, so the last address is 000000007FFFFFFF.
how did the book get 3^20? and that doesnt even equal 2^31 when you times it all out by 2. How do you solve this problem.
In addition how does RAM correspond to memory, is it an extension of the physical memory? the book doesnt actually say that, just says its wiped from the computer every time the computer shuts off, etc. Could you give me more insight on this?
Thanks,
-Dan

32-bit PC, size of pointer

For a 4G ram, there is 4 * 1024 * 1024 * 1024 * 8 = 2^(32+3) bits. My question is how could a 32-bit PC can access a 4G memory. What I can think of this is "a byte is the storage unit, one can not store a data in a bit". Is this correct?
Another question is: in such PC, does a pointer always have size 32 bit? It seems reasonable for me, because we have 2^32 storage units to store the data. But in this answer and the next with their remarks, this is said to be wrong. If it is wrong, why?
Individual bits are accessed by reading the address of the byte containing it, modifying the byte and writing back if necessary.
In some architectures the smallest addressable unit is double word, in which case no single byte can be accessed "as is". Theoretically one could design an architecture that would address 16 GB of memory with 32-bits of unique addresses. And similar things happened years ago, when the addressable units of a Hard Drive were limited to bare 2^28 units of 512 byte sectors or so.
It's not completely wrong to say that PC's have 32-bit pointers. That's just a bit old information, as the newer models are internally 64-bit systems and can access depending on the OS up to 2^48 bytes of memory. Currently most existing PCs are 32-bit and nothing can be done about it.
Well, StuartLC remainded about paging. Even in the current 32-bit systems, one can use 48-bits of addressing using old age segment registers. (Can't remember if there was a restriction of segment registers low three bits being zero...) But anyway that would allow 2^45 bytes of individual addresses, out of which just a small fraction could ever be in the main memory simultaneously. If an OS supporting that addressing mode was developed, then probably full 64 bits would be allocated for the pointer. Just like it is today with 64-bit processors.
My question is how could a 32-bit PC can access a 4G memory
You may be confusing address bus (addressable memory) and the size of the processor registers. This superuser post details the differences.
Paging is a technique commonly used to allow memory to be addressed beyond the size of the OS's capabilities, e.g. see PAE
does a pointer always have size 32 bit
No, not necessarily - e.g. on 16 bit DOS and Windows, and also pointers could be relative to a segment.
Can one can not store a data in a bit?
Yes, you can, e.g. in C, bit packing in structs can be done, albeit at the cost of performance and portability.
Today performance is more important, and compilers will typically try and align data to its machine word size, for performance reasons.

HLSL: Memory coalescing with structured buffers

I'm currently working on an HLSL shader that is limited by global memory bandwidth. I need to coalesce as much memory as possible in each memory transaction. Based on the guidelines from NVIDIA for CUDA and OpenCL (DirectCompute documentation is quite lacking), the largest memory transaction size for compute capability 2.0 is 128 bytes, while the largest word that can be accessed is 16 bytes. Global memory accesses can be coalesced when the data being accessed by the threads in a warp fall into the same 128 byte segment. With this in mind, wouldn't structured buffers be detrimental for memory coalescing if the structure is larger than 16 bytes?
Suppose you have a structure of two float4's, call them A and B. You can access either A or B, but not both in a single memory transaction for an instruction issued in a non-divergent warp. The layout of the memory would look like ABABABAB. If you're trying to read consecutive structures into shared memory, wouldn't memory bandwidth be wasted by storing the data in this manner? For example, you can only access the A elements, but the hardware coalesces the memory transaction so it reads in 128 bytes of consecutive data, half of which is the B elements. Essentially, you're wasting half of your memory bandwidth. Wouldn't it be better to store the data like AAAABBBB, which is a structure of buffers instead of a buffer of structures? Or is this handled by the L1 cache, where the B elements are cached so you can access them faster when the next instruction is to read in the B elements? The only other solution would be to have even numbered threads access the A elements, while odd numbered elements access the B elements.
If memory bandwidth is indeed wasted, I don't see why anyone would use structured buffers other than for convenience. Hopefully I explained this well enough so someone could understand. I would ask this on the NVIDIA developer forums, but I think they're still down. Visual Studio keeps crashing when I try to run the NVIDIA Nsight frame profiler, so it's difficult to see how the memory bandwidth is affected by changes in how the data is stored. P.S., has anyone been able to successfuly run the NVIDIA Nsight frame profiler?

Is there merit to having less-than-8-byte pointers on 64-bit systems?

We know that in 64bit computers pointers will be 8bytes,
that will allow us to address a huge memory.
But on the other hand, memories that are available to usual people
now are up to 16G, that means that at the moment we do not need 8 bytes for
addressig, but 5 or at most 6 bytes.
I am a Delphi user.
The question (probably for developers of 64 bit compiler) is:
Would it be possible to declare somewhere how many bytes you would like to
use for pointers, and that will be valid for the whole application.
In case that you have application with millions of pointers and you will
be able to declare that pointers are only 5 bytes, the amount of memory
that will be occupied will be much lower.
I can imagine that this could be difficult to implement,
but I am curious anyway about it.
Thanks in advance.
A million 64-bit pointers will occupy less than eight megabytes. That's nothing. A typical modern computer has 6 GB of RAM. Hence, 8 MB is only slightly more than 1 permille of the total amount of RAM.
There are other uses for the excess precision of 8-byte pointers: you can, for example, encode the class of a reference (as an ordinal index) into the pointer itself, stealing 10 or 20 bits from the 64 available, leaving more than enough for currently available systems.
This can let the compiler writer do inline caching of virtual methods without the cost of an indirection when confirming that the instance is of the expected type.
Actually, it wouldn't save memory. Memory allocations have to be aligned based on the size of what you're allocating. E.g., a 4 byte section of memory has to be placed at a multiple of 4. So, due to the padding to align your 5-byte pointers, they'd actually consume the same amount of memory.
Remember actual OSes don't let you use physical addresses. User processes always use virtual addresses (usually only the kernel can access physical addresses). The processor will transparently turn virtual addresses into physical addresses. That means you can find your program uses pointers to virtual addresses large enough that they don't have a real address counterpart for a given system. It always happened in 32 bit Windows, where DLLs are mapped in the upper 2GB (virtual process address space, always 4GB), even when the machine has far less than 2GB of memory (actually it started to happen when PC had only a few megabytes - it doesn't matter).
Thereby using "small" pointers is a nonsense (even ignoring all the other factors, i.e. memory access, register sizes, instructions standard operand sizez, etc.) which would only reduce the virtual address space available. Also techniques like memory mapped files needs "large" pointers to access a file which could be far larger than the available memory.
Another use for some excess pointer space would be for storing certain value types without boxing. I'm not sure one would want a general-purpose mechanism for small value types, but certainly it would be reasonable to encode all 32-bit signed and unsigned integers, as well as all single-precision floats, and probably many values of type 'long' and 'unsigned long' (e.g. all those that would could be precisely represented by an int, unsigned int, or float).

Resources