RAM & Transfer Register

Figure 1: SAP-1 Block Diagram
Figure 1: SAP-1 Block Diagram


To fetch addresses coming from the Program Counter(PC), the SAP-1 uses a Memory Address Register(MAR) to first store the addresses before accessing them in RAM. My build has no need for a MAR, as it has a dedicated memory/system bus. With a system bus, the PC and all other memory-related modules interface with the RAM and each other directly.

Figure 2: My Build’s Block Diagram
Figure 2: My Build’s Block Diagram


The transfer register, which I call the BR (Bridge), is a 16-bit register that moves data between the 8-bit data bus and the 16-bit system/memory bus in two cycles. The CPU can’t directly read from the data bus into the 16-bit special registers, except for the Segmented Display (SD) register. In my programs, I use little endian to load values into the BR, which is really just an arbitrary preference over big endian. Endianness refers to the order in which bytes are arranged. In little endian, the least significant byte is stored first, while in big endian, the most significant byte comes first. This choice doesn’t change the computer’s performance; it’s just a different way of organizing data.

Implementations

Transfer Register

Control lines involved(5):

  • |← ~BRE Bridge Enable: Enables the address bus to the transfer register’s input.
  • |← BRlW Bridge Lower Write: Writes data from the data bus to the lower byte of the transfer register.
  • |← BRhW Bridge Higher/Upper Write: Writes the content on the data bus to the upper byte of the transfer register.
  • |← ~BRhE Bridge Higher/Upper Enable: Enables the upper byte of the transfer register to the data bus.
  • |← ~BRlE Bridge Lower Enable: Enables the lower byte of the transfer register to the data bus.

The transfer register consists of a 16-bit register made with two 8-bit 74HCT574. The 574’s layout turned out be extremely convenient for this module as the large amount of jumper wires are evenly spread on both sides of the breadboard. Like every module interacting with the address bus; it has two pairs of transceivers; One(The left pair) to load BR from the address bus in one cycle with ~BRE, and the other to either write to or read from the data bus in two cycles using BRlW, BRhW ~BRhE, and ~BRlE.

Figure 3: Transfer Register Schematic
Figure 3: Transfer Register Schematic


RAM

Control lines involved(3):

  • |← ~SPE Stack access control line: Enables stack memory when LOW, and ROM when HIGH.
  • |← ~ME Enables memory output to the data bus.
  • |← ~MW Memory write

My RAM chip is a UM61512A 64K X 8 BIT HIGH SPEED CMOS SRAM, which is perfect for my use case, as it is cheap(About $15 for a set of 10 on Ebay), and very compact! The lower 48K of the memory is used for program memory, and the remaining/top 16K of memory is for either stack memory or a boot loader ROM.

The OS EEPROM (X28C256) is a 32K x 8-bit. However, dedicating 48K of the addressable memory space for RAM means that I can only access half(16K) of the ROM at a time. To work around this, I use a manual switch on the ROM’s most significant address bit. This essentially lets me switch between two 16KB ROMS.

Figure 4: Memory Partitioning
Figure 4: Memory Partitioning


Just like the SAP-1, my build can be set to either Programming or Run mode. When in programming mode, some DIP switches are used to manually point to memory addresses and enter data into RAM. An SPDT switch is used to switch between the two modes, and a push button is used to trigger the RAM’s write pin.

Below is a high level diagram to better illustrate the memory logic.

Figure 5: RAM Overview Diagram
Figure 5: RAM Overview Diagram


As mentioned before; I allocate the lower 48K Bytes of the RAM, spanning address 0X0000 to 0XBFFF, to address memory; and the remaining 16K Bytes, from 0XC000 to 0XFFF, to either the boot loader or stack memory.

In binary:

0X0000        0000000000000000 }
                     |         }   RAM
                     ▌         }  memory
0XBFFF        1011111111111111 }

0XC000        1100000000000000 }       
              ^^     |         } ROM & Stack
                     ▌         }   memory
0XFFF         1111111111111111 }

Note that the ROM/stack address space begins when the 15th and 16th bits of the memory address are HIGH. This means that the boot loader ROM is accessed only when both A14 and A15 are HIGH, and the Stack Pointer Enable ~SPE is inactive(HIGH). This is simply implemented by the three-input NAND at the center of the diagram.

The RAM chip, conveniently has two input enables; one is active-low and the other is active-high. The output of the three input NAND gate is connected to the ROM’s active-low chip enable, and the RAM’s active-high chip enable, meaning that the the ROM chip would always be completely inactive unless the boot loader memory space is addressed.

The UM61512A RAM has all-in-one I/O data pins, which means that, using the appropriate control pins, it can either, be written to, or output data using the same pins.


In Run Mode (PGM node is HIGH)

The RAM is controlled by the control logic, the I/O pins get routed to the data bus, and the address pins to the system bus:

Node D is HIGH, and C alternates between HIGH and LOW inversely to CLK, while B matches CLK. The RAM’s Write Enable (~WE) node is HIGH by default, and goes LOW(At the rising edge of the clock), only when the Memory Write (~MW) control signal is active. And since both PGM and D are **HIGH, the data and address input transceivers for the DIP switches are locked (On high impedance mode).

  • When the Memory Enable(Enables memory content to data bus)(~ME) control line is active and ~MW is inactive, node H goes HIGH, G goes **LOW, and the RAM’s data I/O transceiver directs data flow from the RAM’s I/O pins to the data bus.
  • Inversely, when ~MW is active and ~ME is inactive, node H goes HIGH and the RAM’s data I/O’s transceiver directs data flow from the data bus to the RAM’s I/O pins.
  • When neither ~MW or ~ME is active, node H goes LOW, the RAM’s data I/O’s transceiver switches to high impedance mode, and the RAM chip gets disabled through ~CE1 as G and ~MW are HIGH.

~ME and ~MW being active at the same time is a forbidden state as you can’t read from and write to RAM at the same time(At least not in my build).

Note: ~WE has priority over ~OE, provided the chip is enabled.


In Programming Mode (PGM node is LOW)

The RAM’s I/O pins get routed/connected to the data DIP switches, and the address pins to the address DIP switches:

  • PGM being LOW, the address input transceiver connects the memory address DIP switch’s value to the RAM’s address input. The NAND gate on the far right of the diagram controlling the I/O transceiver outputs LOW, thus keeping the RAM from interacting with the data bus.

  • ~MW and CLK now have no control on the state of ~WE as node A and C are always HIGH. Each time the programming push button is pressed, D goes LOW, simultaneously activating ~WE and routing the value on the data DIP switch to the RAM’s data input pins.

Figure 6: RAM Schematic
Figure 6: RAM Schematic


ICs


«««««««««« Previous Post: RAM & ROM Primer

        Next Post: EPROM Programmer  »»»»»»»»»»

Updated:

back to top