assemblymicrocontrollercpu-architecturecircuit

How do microcontrollers store and retrieve data from RAM?


I am developing my own academic processor for myself and a problem arose. And I don't know how to implement reading and writing data from memory to a register. I can do exactly the order of instructions, in the loop, but how do I take an arbitrary address, write and read data from it? I need this because the data doesn't fit into the registers.

I need an example of how this is done at least on asembler level in microcontrollers, i.e. where 1 operand is used in operation and not 3 as in RISC-V, as this will be done in my processor.

By the way, the processor is 8 bit, the maximum memory for addressing is 256 words. The word length will most likely be 14 bits(6 for op code).


Solution

  • How do microcontrollers store and retrieve data from RAM?

    In general you will have some kind of "address bus" (or maybe "address link") to connect the CPU (directly, or indirectly via. a memory controller) to RAM.

    That address bus will transfer messages. The messages will be vaguely like "READ (address, size)" followed by a "READ_REPLY(size, data)", or like "WRITE (address, size, data)" (possibly with an "ACK()" reply?). It might be high speed serial with everything broken into bits. It might be a parallel bus. It might be a combination (e.g. 8 parallel lines, but then "one byte at a time in series"). There might be control lines for various purposes.

    This same address bus might also handle things that are not RAM at all - e.g. ROM, "IO port space", empty/nothing (if someone only wants to install 128 bytes of RAM instead of 256 bytes), IRQs requests from devices, etc; and may also be used for instruction fetch (instructions also need to be loaded from somewhere, not just data).

    Note: For general purpose CPUs a full Harvard architecture is relatively awful; but for a small microcontroller it might be extremely good - e.g. all code comes from ROM using one interface, and all data uses RAM with a different interface, with 256 bytes of ROM for code plus 256 bytes of RAM for data.

    Whatever you decide the hardware interface is, your CPU is going to have to support it by translating instructions (e.g. maybe "LDX [y]") into messages on the address bus (e.g. maybe a "READ (address_that_came_from_register_Y)") and then (probably, for a simple CPU) waiting for the reply to come back. For reads (which are harder) when the reply comes back you need to put the data somewhere (e.g. move the data from RAM into the "register X").

    You will also have to decide what the instructions are. For an absolute minimum you might (e.g.) have a "LDXY" instruction with 2 implied operands ("read data at the address in the Y register into the X register"), but you might have crazy/complex stuff (e.g. "load x, [y + z <<256]" to support 64 KiB of RAM by using 2 different registers as the address), and might have some special purpose stuff (like POP, PUSH, CALL and RET that all use the stack pointer as an implied operand for the address).