Over the years I have spent time looking at computer design and cpu design.  I dream of building my own computer from scratch, not just buying parts and putting a pc together, using simple logic gates from the 74 series and designing it from the ground up.

I read many articles and websites about this process and started throwing some ideas around, but nearly all these homebrew systems just used LED to show it working.  Something in me wasnt happy with this, I wanted a computer that i could program and play simple games on.  This needed something more than simple lights, it needed a graphic display on a screen.

Having decided on this i set about reading up on VGA output to computer monitors.  I came across a nice little website called tinyvga.com which gave details of the various resolutions and the timing pulses required to generate the signals.  While it was tempting to go for a high resolution screen I had to be realistic.  If i was going to build a system out of 74 series chips then I would need to keep the clock speed around 4Mhz as this gives a time of around 250ns per cycle.  Most RAM chips i looked at need at least 55ns-70ns for access so this would work well.  With all this in mind I opted to go for the industry standard 640x480@60hz resolution.  The tinyvga website gives the following information for this mode…

VGA Signal 640 x 480 @ 60 Hz

General timing

Screen refresh rate 60 Hz
Vertical refresh 31.46875 kHz
Pixel freq. 25.175 MHz

Horizontal timing (line)

Scanline part Pixels Time [µs]
Visible area 640 25.422045680238
Front porch 16 0.63555114200596
Sync pulse 96 3.8133068520357
Back porch 48 1.9066534260179
Whole line 800 31.777557100298

Vertical timing (frame)

Frame part Lines Time [ms]
Visible area 480 15.253227408143
Front porch 10 0.31777557100298
Sync pulse 2 0.063555114200596
Back porch 33 1.0486593843098
Whole frame 525 16.683217477656

To start with alot of this may seem like random numbers, but after reading a bit it turns out that there are 4 sections to horizontal lines of display and 4 sections to vertical lines.  Different websites seem to argue over which comes when, but as long as they are in the right order it doesn’t really matter as far as i can tell.  Ill opt for the Visible area being first (pixels 0 – 639), followed by the front porch (640 – 655), the sync pulse (656 – 751) and finally the back porch (752 – 799).

Horizontal Timing

To generate the screen mode the first thing we need to do is generate the horizontal and vertical sync pulses, these are separate pins on the VGA DB15 connector, we must change the voltage from a low signal during the sync pulses to a high signal outside the sync pulses.  The general timing section gives the pixel frequency as 25.175Mhz so i started off ordering up a clock crystal at this speed.  Using this i can work from the pixel time information rather than the actual timings.  You can use a different clock frequency but then you will need to calculate the pixel counting for your new clock crystal, this often leads to rounding issues and while the timing pulses can be varied slightly i felt it wasnt worth adding extra complexity to the system at the first hurdle.

Using the clock crystal i needed to count up to 800 (0 – 799) so i could time the various signals, this seemed simple enough. Take the output from the clock and feed it into a counter.  The first issue is that the general 74 series chips dont have any 16 bit counters (unless you use the newer 7416 range which i didnt have), so looking at the numbers for the horizontal pixel timings i realised they all divide by 16 nicely.  I first fed the clock crystal output into a 4 bit counter and used bit 3 from this as the new clock pulse, effectively dividing the original clock pulse by 16.  This new clock pulse was fed into an 8 bit counter from where i could compare the pixel number for the sync pulse.

For the horizontal sync pulse i needed to turn the pulse low when the counter got to 41 (656 / 16 = 41) then back high when the counter got to 47 (752 / 16 = 47).  To check when these were reached I took the output from the 8 bit counter and fed it into two 74xx688 (an 8 bit comparator).  To hold the current state of the sync pulse (and all the other signals) i used a D-Type flip flop in the form of a 74xx74 chip.  Grounding the clock and data lines meant i could just use the Set and Reset lines to change the output data, this works well as we have two lines coming from the 74xx688 used to test for the specific pixel counts.  We could feed the output from the 688 chips into the set and reset ports, but due to the ripple counter and other timing issues, its always good to have these change on a specific clock.

Given we have several signals we need to pulse all at the same time i take the output from the 688 chips into a 74xx574 chip.  Each data line is a different signal. To feed this chips clock i used bit 2 from the original 4 bit counter used to divide the clock pulse by 16, using this means there is no conflict with the main timing pulses.  The output enable is grounded, given that is low enabled means the output is always on.

The output of the counter checking for 41 is fed, via the 574, into the reset of one of the 74 D-Type flip flops.  The output of the 688 checking for 47 is then fed, again via the 574, into the set of the flip-flop.  We now have a clean signal to feed the horizontal sync pulse for the VGA circuit.

HSync Generation Schematics