aboutsummaryrefslogtreecommitdiffstats
path: root/include/mips_mem.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/mips_mem.h')
-rw-r--r--include/mips_mem.h54
1 files changed, 14 insertions, 40 deletions
diff --git a/include/mips_mem.h b/include/mips_mem.h
index 1b78c34..a419413 100644
--- a/include/mips_mem.h
+++ b/include/mips_mem.h
@@ -90,15 +90,12 @@ mips_error mips_mem_read(
/*! Perform a write transaction on the memory
The implementation is expected to check that the transaction
- matches the alignment and block size requirements, and return an
- error if they are violated.
+ matches the alignment requirements, and return an error if they are violated.
The input pointer is a pointer to bytes, because the RAM is byte
- addressable, however the transaction size may consist of multiple
- bytes - indeed, for memories with a block size greater than one,
- all transactions must be multiple bytes. To write a larger piece
- of data, you can use pointer casting, or pass in an array. For
- example, if I want to write 0xFF001100 to address 12, I could do:
+ addressable, however the transaction size may be 1, 2, or 4 bytes.
+ To write a larger piece of data, you can use pointer casting, or pass in an array.
+ For example, if I want to write 0xFF001100 to address 12, I could do:
uint32_t xv=0xFF001100;
mips_error err=mips_mem_write(mem, 12, 4, (uint8_t*)&xv);
@@ -175,41 +172,18 @@ void mips_mem_free(mips_mem_h mem);
/*! Initialise a new RAM of the given size.
- The RAM will expect transactions to be at the granularity
- of the blockSize. This means any reads or writes must be aligned
- to the correct blockSize, and should consist of an integer number
- of blocks. For example, choosing blockSize=4 would result in a RAM
- that only supports aligned 32-bit reads and writes.
-
- You can think of the blockSize as being equivalent to the number
- of wires in the data-bus of the memory. If the only wires you
- have are readEnable, writeEnable, address, dataIn, and dataOut,
- then within one cycle you could do a write by asserting writeEnable=1,
- specifying the address, and driving the data to be written onto dataIn.
- Or you could perform a read by asserting readEnable=1, driving the
- address bus, and looking at the value that the RAM drives onto dataOut.
- If blockSize=4, then we would have 32 wires for both dataIn and dataOut,
- and any address would need to have the two least significant bits as zero.
-
- In MIPS the basic unit of transfer is 32-bits, so the granularity of the
- data bus is also 32-bits, and blockSize must be 4.
-
- "Why do we even have this blockSize if it is always 4?" : It is in
- anticipation of a future extension, and a mistake on my part (from
- a teaching point of view). I should have given it the simpler signature of:
-
- mips_mem_h mips_mem_create_ram(uint32_t cbMem);
-
- and stated that it creates a RAM of the given size with a granularity of 4.
-
- "How can MIPS do SH (store half) efficiently if this is the case?" - An
- actual MIPS implementation would have what are called "byte-enables",
- which are extra signals saying which bytes within the data bus are
- valid, but I didn't include them in the API as they complicate things.
+ The RAM will expect transactions to be aligned at the granularity
+ of the transfer, so 4-byte transfers are aligned on 4-byte addresses,
+ 2-byte transfers on 2-byte address, and single byte transfers can
+ have any address.
+
+ This interface is over-simplifying things, and ignoring
+ "byte-enables". These are what allows a CPU to indicate
+ which of the bytes within a 32-bit bus are being actively
+ written.
*/
mips_mem_h mips_mem_create_ram(
- uint32_t cbMem, //!< Total number of bytes of ram
- uint32_t blockSize //!< Granularity of transactions supported by RAM
+ uint32_t cbMem //!< Total number of bytes of ram
);
/*!