Skip to main content

Graphics Hardware

Structure

The graphics unit consists of three submodules that interact with each other:

  • The counter module, consisting of the clock and counters for x and y, as well as the comparators for generating hsync, vsync, and the blanking intervals
  • The output module that handles the actual image generation
  • The memory module, which contains the two RAM chips and handles the switching of CPU and GPU access

As the output module needs access to both the counter and the memory module, it is located in the middle in the final build.

Integration With the Full Build

The graphics unit, like other I/O devices, is not placed in a fixed location in the final build. Instead, it can be moved around separately or even disconnected when not needed.

When the graphics unit is used, it must be connected to

  • The 16-bit address bus
  • The 8-bit data bus
  • BUSREQ
  • IO/MEM_FROM_DBUS
  • ADDR16
  • FB_SEL and ~FB_SEL

All these connect to the memory submodule of the graphics unit, as it is the only part that communicates with the CPU.

tip

The inverted FB_SEL line seems redundant. However, we chose to use this instead of an additional chip, as there was an unused D-flip-flop in the control unit.

tip

It is not important whether FB_SEL is low or high initially, which means that it can be safely swapped with the inverted version.

Hardware Oddities

In the final build, the inverted FB_SEL line was very noisy for no apparent reason (other than a very long cable) and had to be smoothed with a capacitor.

Final Build Differences

After the graphics unit was designed and built, the I/O group decided that all their devices would use a 30-pin cable that carries the two busses and all necessary control signals (including FB_SEL). However, this cable does not carry ADDR16 - instead, the address on this cable is set to zero when ADDR16 is not set.

We decided to use their cable as well, as it was already connected to the CPU and we did not want to do this work twice. As the graphics unit only listens to addresses where the highest bit on the address bus is set (in addition to ADDR16), we could just set ADDR16 to high instead of connecting it to the CPU.

Lessons Learned

We encountered several issues while building the graphics unit, most notably:

  • Breadboard power rails are not very reliable, especially when multiple are connected together. A slightly unstable power rail is very problematic for active-low signals (like write enable). In the end, we could only get everything stable by using two power rails, one on each side.
  • The Keyestudio Mega 2560's outputs were not stable enough for our purposes. When they were high, they would still dip low enough to be recognized as low, causing many spurious writes.
    These issues only occurred with the Mega 2560, and do not persist in the final build. We did not try original Arduinos or other clones.
  • If a signal is too noisy, the oscilloscope's capacitance can smooth it out, hiding the issue. If connecting the oscilloscope makes things work, this might be the cause.
  • VGA timings don't need to be exact, however, it can be trial and error to see what deviance a monitor accepts and at what point it rejects the signal.

Known Issues

Our build starts outputting image data too soon (before the intended image in both x and y direction). We did not find a way to resolve this without adding more comparators, which would require more space. As a workaround, the image can be manually adjusted in the monitor settings.

Build Photo

Graphics Unit