Memory module 2

I have completed the design of the memory module – the last required module to announce the entire design finished. I chose a very simple design, with rudimentary paging mechanism, in a hope it will not turn out to be a significant limitation in the near future.

The machine features a 22-bit physical address bus, meaning that 4MB of physical memory may be addressed. I will be using 512k SRAM chips (the memory board will be populated with up to 8 such chips, constituting its RAM) and one 128k EEPROM (for kernel ROM). Memory is divided into 128 logical pages of 32kB each. Pages 0-3 are ROM (address range $000000h-$01FFFFh) and pages 4-127 are RAM ($020000h-$3FFFFFh). Here is a physical memory layout:

Programmer visible address registers of the CPU are all 16-bit wide, meaning only 64kB of memory may be addressed by a running program. Actually, it is 128kB since the machine has isolated code and memory regions. Which region is accessed is determined by a dedicated bit in the microcode (MEMSEG), which may be treated as a 17-th bit of a logical memory address. Logical memory is divided into four pages of exactly the same size as physical memory pages (32kB). Here is a logical memory layout:

Now, in order to map logical code or data pages onto physical memory pages, special purpose registers were added at the following memory locations:

$2000h (REG_CODEPAGE0) – physical memory page for logical code page #0

$2200h (REG_CODEPAGE1) – physical memory page for logical code page #1

$2400h (REG_DATAPAGE0) – physical memory page for logical data page #0

$2600h (REG_DATAPAGE1) – physical memory page for logical data page #1

These registers are accessible only in supervisor mode and are write-only. Attempt to read them will result in an invalid value. In user mode these locations are standard memory (hardware will not access register chips). In order to map physical memory pages onto logical memory, page number (0..127) must be set in these registers (in bits 0 to 6, most significant bit is ignored). In supervisor mode however, setting for Code Page 0 and Data Page 0 is ignored, and physical pages 0 (first page of ROM, most probably this will be OS kernel) and 4 (first page of RAM) are hard-wired to these logical pages, respectively. Mapping for Code Page 0 and Data Page 0 is only valid in user mode. Mapping for Code Page 1 and Data Page 1 works in both modes. This way, loading user programs to memory when in supervisor mode should be fairly easy. Data Page 1 may be used to load all user program pages one by one, and registers need to be set appropriately before doing the mode switch.

Address translation

Logic to transform logical to physical addresses is simple on hardware level. Here is how it works:

First level of decoding (not displayed above) determines whether physical memory should be accessed, or special purpose address range is selected (this is valid in supervisor mode only, for details see above). If memory was referenced, a 2-to-4 decoder selects appropriate paging register based on MEMSEG signal and MSB of the logical address. The selected register outputs its 7 lower bits as topmost 7 bits of the physical address (indicating physical address page). Lower 15 bits of the physical address (index within a page) are fed directly from logical address bits 0..14.

Memory map

When the CPU is in supervisor mode, some logical address ranges (in data region) have a special meaning and do not reference physical memory. They are used for I/O mapping, or special purpose registers, like the ones used for memory paging described above. Here is the current memory map:

range description
$0000h-$001Fh interrupt vector
$0020h-$0FFFh kernel area
$1000h-$1FFFh I/O area (devices)
$2000h-$2FFFh system registers
$3000h-$FFFFh RAM

The kernel area will be used by a kernel to store its stack and other control data. The I/O area will be further split into device control blocks for individual peripherals. System registers are 512-byte aligned (like 4 paging registers described here), which means 4 register locations are available for future use. Memory range at address $3000h and above is not constrained in any way and may be freely used.

What next?

Well, looks like it’s time to get serious. I will investigate schematic tools available for free and try to post first diagrams as soon as possible. After months of design and simulation work I am really eager to start working with real hardware.

As usual, an updated machine simulator and a set of simple memory paging tests is available on downloads page.

2 thoughts on “Memory module

  1. Reply Steve Mar 22,2011 8:12 pm

    I am trying to understand your design and I am curious as to why you used bits 9, 10, and 11 to determine which system register is used. Could you have used bits 0, 1 and 2 mapping $2000h – $2007h for system registers and the remainder for something else? Was this just to keep your address decoder simple from a hardware perspective?

  2. Reply dawid Mar 24,2011 12:35 am

    That’s exactly the case – I wanted to keep hardware complexity to a minimum. I could have used bits 0, 1 and 2, but mapping system registers to $2000h-$2007h and keeping the remaining addresses for something else would require me to check if bits 3..11 are all zeros. Then to use the remainder (say $2008h-$200fh) I would have to check if bit 3 is set and bits 4..11 are all zeros, etc. That’s extra decoding hardware on bits 3..11 and more propagation delay. Since I don’t need many system registers, I decided to simplify the logic. Obviously I am wasting address space – by ignoring bits 0..8 all adresses in range $2000h-$21ffh map to the same system register REG_CODEPAGE0, $2200h-$23ff maps to REG_CODEPAGE1, etc. With the same hardware it seems better that using bits 0..2 and ignoring 3..11 which would result in awkward interleaved mapping REG_CODEPAGE0, REG_CODEPAGE1, …, REG_CODEPAGE0, REG_CODEPAGE1.

Leave a Reply




Time limit is exhausted. Please reload the CAPTCHA.