Subtitles section Play video Print subtitles In a previous video we built this circuit that generates a valid VGA signal, and when we plugged a monitor in we saw that the monitor recognized that it was in 800 by 600 mode. And that's because we're sending at the right horizontal and vertical sync pulses for that mode. We're sending a 3.2 Âµs horizontal sync pulse 38-whatever thousand times per second and we're sending a 0.1056 ms sync pulse 60 times per second. And the way this all works is we have a binary counter here that's counting from 0 to 264 you know over and over again, and it's counting at exactly 10 million times per second. So we can look for these particular values to get the pulse width and the pulse frequency to match exactly; and then same thing in the vertical direction, you know we've got another counter here that counts each line on the screen from 0 to 628 and of course, you know we measured all the timing and everything in the last video to make sure it matched the specs and it did and so we saw the monitor recognize it as a valid signal. So if you want to know more about what's going on here, I definitely recommend you check out the first video, but now you know we probably want to actually display something on the screen. And to do that, the VGA interface has a few more signals for red, green and blue. and Because we're using the sync signals here to stay synchronized with the monitor we can use our horizontal and vertical counters to keep track of what part of the screen the monitor is currently "painting" at the moment. And so the 0 to 200 tells us where it is from left to right, and then the 0 to 600 Will tell us where it is from top to bottom and so as the monitor paints the screen You know, left to right, top to bottom: the same way you'd read a page in a book. These red green and blue signals is how we tell the monitor what colour pixel we want at that particular location. In other words: because we're synchronized, we can use our counters to know exactly what pixel the monitor is.painting at the moment So for example if I take just one bit from one of these counters (so this is the the vertical counter) if I take those, you know 1 2 4 8 16s place Let's say this 16 s placed bit right here you know as we count down the screen from 0 to 600 down the screen this bit is going to flip on or off every 16 scan lines. So if I take that bit and hook it up to the the green signal and I'm hooked it up through a resistor (for reasons that I'll get into here in a minute) There we go You know You can see every 16 lines the green flips on and off and that's because as our article counter counts from 0 to 600 every 16 counts this 16 places bit flips on and off because that's how binary counters work Now if I hooked the red up here to the eights place in the same way There we go and now you now you can see the green and the red as well as Yellow when the two mix and then of course, you know, I can also hook up blue So, let me just do that for the sake of completeness And now you can see the three primary colors mixed to give us actually 16 distinct colors but you know as much fun as colorful stripes are what I really want to do is display a more complex picture and for that to work We need the pixel data stored in some memory somewhere Normally in a computer the data for whatever's on the screen is stored in a part of RAM that way the software running on the computer could just write new data to the same Ram location and the image on the screen will Change right away, but I'm not gonna hook this to a computer at least not yet So I'm just gonna store the image on an EEPROM and this is a 28 C 256 EEPROM so it'll hold 32 k of data which should be enough for an image of some sort and the way this will work is we already have our horizontal and vertical counters giving us an x and a y position and if we feed all of those signals into the addresses of the EEPROM Then the EEPROM will give us a byte stored at that address and that byte could be the color of the pixel for that particular XY location So that's how we'll store the image in the EEPROM But there's one weird issue which is because we went with the 10 megahertz pixel clock instead of 40 megahertz we only have 200 pixels by 600 instead of 800 by 600 and 200 by 600 is kind of a weird resolution No The pixels would be kind of stretched out because really what we're doing is we're repeating each pixel four times as we go across So it'd be nice to maybe slow our vertical counter down. So we repeat each line four times as well And it's actually pretty easy to do if we have our counter counting in binary like this You know here we're just counting 0 1 2 3 all the way up to 16, you know, just counting in binary Well, if we lop off that last bit now it goes 0 0 1 1 2 2 and so forth up to 8 and if we lop off another bit Then it repeat each number four times and only counts up to 4 instead of counting to 16 So if we just ignore the bottom 2 bits of our Y counter that all divided the counter by 4 We actually still have another problem which is the EEPROM. I have the 22:56 it actually only has 15 address lines so we couldn't fit all these address lines here Even if we wanted to so we've actually got to get it rid of at least three address lines in order For it to actually fit in this EEPROM So given what we've got with this EEPROM and to keep the right proportions end up having to drop three bits from our Y counter and one bit from the X counter and that leaves us with a Final image resolution of 100 pixels by 75 pixels which you know, I don't know it's maybe not the most impressive resolution But I mean, what do you want for me? I'm trying to build a video card on bread boards So 100 by 75 is is what we get. So let's hook the EEPROM up like this I'll start by adding another breadboard and connecting power and ground to the EEPROM Then I'll tie the right enable pin high since it will only be reading and it's active low and Output enable and chip enable are both active low as well So I'll tie them both low, so everything's enabled for output Then the first seven address lines go down to our horizontal counter and again We're skipping the first bit and the next seven address lines go to the vertical counter and this time skipping the first three bits So that's 14 address lines 7 for X 7 for Y. There is a 15th address line, which we're not going to use So I'll just tie that to ground So now we've got all of our address lines connected like this So for each of our 100 by 75 pixels, we should be getting a byte of data out here That'll presumably tell us what color that pixel should be But how are we going to turn this 8-bit data into the signal that the VGA monitor expects? well the VGA interface has three pins red green and blue and each expects a voltage between zero and point 7 volts and Depending on what that voltage is Whether it's closer to 0 volts are closer to 0.7 volts Determines how much of each color is mixed together to determine the color of the pixel? But we've got eight bits here of data that are either 0 volts or 5 volts. How do we get something that's point 7 volts well is the case where we have one voltage and we need a lower voltage and so we can use a voltage divider and A voltage divider is just two resistors like this. So relative to ground down here We've got 0 volts and up at the top. We've got 5 volts and in the middle here It's going to be somewhere between 0 and 5 volts and how far it is from 0 volts to 5 volts Depends on how big r2 is compared to the total resistance So if r2 is half of the total resistance that is r1 and r2 or the same value then in the middle here We're gonna have half the voltage. So two and a half volts if r2 were 10% of the total resistance Then we'd have 10 percent of the total voltage or half a volt So this expression just describes that? You look at the proportion of r2 to the total resistance And then that tells you how much of the total voltage you get Now the VGA spec says that the red green and blue signals it says, you know zero to 0.7 volts It also says it's got this 75 ohm input impedance and You can roughly think of that as meaning that inside the monitor Those red green and blue inputs are kind of connected to ground like this through a 75 Ohm load of some kind so if we've got five volts and we want to get it down to 0.7 volts as it's going into the monitor here. We can just add a resistor like this and that creates a voltage divider, right? So we've got five volts at the top We've got ground here at the bottom and we want this to be 0.7 volts here in the middle Now if the monitors input impedance is 75, ohms we can't change that but we can put whatever resistor we want here between our 5 volts and the input to the monitor and You know to figure out what resistor that needs to be in order to get 0.7 volts well, we could just look at this expression here and say you know When would this expression equal 0.7 volts given that r2 is is going to be 75, ohms well, we can put 75 ohms in here for r2 and set it equal to 0.7 volts and we just need to solve for R So 5 times 75 is is 375 and then R + 75 times 0.7 is gonna be 0.7 R + 52 and 1/2 Subtract that 52 and a half from both sides we get 0.7 R Equals 3 22 and a half we can divide that by 0.7 and we get R equal to four hundred and sixty point seven. Ohms So if we take five volts and we put it through a four hundred and sixty point seven Ohm resistor will have point seven volts here going into our monitor, you know given that there's a 75. Ohm load inside that monitor But ideally we don't just want point seven volts or zero volts going into the monitor here, you know ideally we'd be able to have a range of voltages between zero and point seven volts so we can get different brightnesses of red green and Blue, yeah, so that we're able to have different shades of colors so for example If we wanted four different voltages from zero at 0.7 Evenly-spaced so we could get four different shades of red green and blue We'd have to solve this equation essentially for each of those different voltages to find out what resistor we need to get that particular voltage So that's what I've done here. That's what these different resistances are and This is for you know, one-third brightness two thirds brightness, and then of course full brightness at 0.7 volts Which is what we just we just figured out is four hundred sixty point seven And we could use these different resistances to get these different voltages so that we end up with these different Brightness levels for each of the colors and of course, you know, they don't make fifteen hundred fifty five point four Ohm resistors they make you know fifteen hundred. Ohm resistors and they don't make 720 two point nine. Ohm resistors, but you know, I've got 680 ohms which is maybe close enough So if we use those resistors to build something like this that's got two inputs over here that can be you know Either 0 or 5 volts and an output over here and check this out You know if both inputs are zero like this then the output table. These are going to be 0 volts, right? But if one input here is 5 volts So the one hooked to the 1.5 cave' resistor is 5 volts and this is a zero then essentially we're kind of in this scenario Here where we have, you know, approximately 1,500 1,500 ohm resistor and we're gonna get about 0.23 volts over here But if we flip that around and we we don't have anything here and we have five volts down here Then we're going through the 680 Ohm resistor and we're gonna have you know about 700 or well we're gonna have about 0.47 volts But then if we have ones on both of these inputs, so both of these inputs are 5 volts Well, then these resistors are going to combine in parallel and to combine resistors in parallel You use this expression here, which is sort of the sum of the reciprocal of the sum of the reciprocals So to combine 1,500, ohms and 680. Ohms in parallel like this It's going to appear as a single resistance from 5 volts to this point over here of 468 Which is pretty close to here and so we're going to get 0.7 volts, so this takes two inputs that can either be 0 or 5 volts and gives us the 4 different possibilities that give us these 4 different voltage levels from 0 up to 0.7 volts and So with just a couple resistors we can take 2 bits of binary data and convert that into one of 4 different voltage levels from 0 to 0.7 volts and If we do that for red green and blue we can use six bits of data coming out of our EEPROM to get four different shades of red green and blue which combine into 64 different colors and so this is the mapping for those different colors If you're familiar with these hex codes for colors But you can see the last two bits here controls how much blue there is now the middle two bits controls how much green there is and then the first two bits controls how much red there is and Then this here is what those actual colors look like And so those are the 64 colors that were able to generate with a circuit like this So let's actually hook these resistors up to the outputs of our EEPROM and to here the 1.5 K resistors And of course, there's three of them one for red green and blue and here are the 680 Ohm resistors and so hook the first two data bits up for blue And the first one is going to go to a 1.5 K resistor and then the next one will go to a 680 Ohm resistor, then the next two bits will be for green. So go to a 1.5 K resistor and then to a 680 Ohm resistor and then finally the last two bits are gonna be for red The 1.5 k resistor and the 680 Ohm resistor and then we just need to tie this side of the the resistors for each color together So they'll do blue Green and red. And so now over on this side we should be getting that voltage between zero and 0.7 volts So now we can try hooking this up to the monitor again So here's our 15 pin vga connector and i've got the the same sync signals before in the ground, of course But now i've got the red green and blue hooked up to pins 1 2 & 3 so we can hook up ground and hook up our sync signals as before so the horizontal sync and The vertical sync and then the colors we could just hook up over on this side of the resistors So there's blue there's green and there's red now if we power up our circuit and plug in the monitor So we basically see the same thing as before so the monitor comes alive so it's detecting the sync signal but it's still a blank screen and Of course, that could be because what's in the EEPROM is just blank But I happen to know that this is an erased EEPROM and when you were to race an EEPROM it it just writes all one's So we should actually see a white screen and we're not but I think the problem is that if every address in the EEPROM is Set to all ones then We're gonna be outputting a white for every position and that includes even in the blanking time here And we really shouldn't be putting out any pixels in this blanking time because well it should be blank And in fact, this is one of those things that might actually damage a CRT monitor and hopefully we won't damage my monitor But the way we can fix that Is use these signals that were detecting here for the blanking intervals, right? Because we're actually detecting when we're in this horizontal blanking interval Right here with this flip-flop and we're detecting when we're in the the vertical blanking interval down here So really what we need to do is we need to figure out are we in the blanking interval and those together? and we could actually use the result of that for the output enable signal for our EEPROM so we can essentially turn the output of The EEPROM off if we're in that blanking interval so what I'm going to do is add a NAND gate here and I'm using a NAND gate so that the output is inverted because our chip enable or not our tripping well actually both But the output enable which is the one we're going to use the output enable is active low So that way if if two inputs here are high then the output will be low and then the two inputs that we'll use is well look at if we're in the display period for