Learning how to directly drive a VGA monitor with an FPGA opens up a window for many potential projects: video games, image processing, a terminal window for a custom processor, and many more. To get started, we will need to learn how to drive the necessary signals to display things on a VGA monitor. We will then use a test circuit to display some colors on the screen. In future posts I will detail how to design pixel generating circuits for displaying custom graphics and animations. More on that soon!
Computer monitors used to be bulky cathode ray tube (CRT) devices. VGA technology was developed with driving the physical CRT in mind, so knowing how that device works can be instructive in understanding why VGA signals are driven the way they are. That being said, computer monitors nowadays are LCD monitors without a CRT, yet the VGA interfaces for these monitors still use the same signals to display images on their screens. Instead of going into the details of CRTs in this post, we will instead inspect the necessary signals for a VGA monitor and their timing diagrams, and implement a synchronization circuit in Verilog HDL.
Keep in mind that different FPGA development boards have different color depth capabilities. I will focus here on using the Basys 2 which has 8-bit color and the Basys 3 which has 12-bit color. While I am covering the Basys 2 here, in the future I will focus on and use the more capable Basys 3 for my VGA projects.
The keyboard is a tool whose utility needs no introduction. Right now I using a keyboard to type this blog post. I find the keyboard to be an interesting device that deserves a look into how it works. By learning a little about the insides we can then plan to interface the keyboard with an FPGA and use it as an input device. I for one am really looking forward to learning how to drive VGA signals, and eventually making an FPGA based game that plays on a VGA monitor and uses keyboard as a controller. Until then, let’s start learning how to interface with the keyboard.
The keys on a keyboard have various purposes, with the majority being alphanumeric or symbol keys. There are also common modification keys, such as space, enter, shift, caps lock, backspace, etc. Many of the other key groups such as the F#, directional, and navigation keys serve special purposes within a computer system (i.e. Print Screen).
We will implement an FPGA keyboard interface that is simplified to process the alphanumeric & symbol keys, as well as the space, backspace, enter, tab, shift, and capslock keys. The keyboard used will have a PS2 connection, so we will need to implement a PS2 receiver circuit to receive scan codes from the keyboard when a key is pressed. We will then implement a keyboard interface circuit that processes the scan codes in a way that will make the keystroke responses natural and akin to how they would be in a simple text editor. Finally to test the keyboard circuit we will interface it with a UART transmitter to send the corresponding ASCII codes (converted from scan codes) to a PC serial monitor for viewing. This will allow us to type characters, words, and sentences, with the basic functionality of the text modification keys.
Being able to interface an FPGA project with a device that has a serial port allows for a basic means of sending and receiving data between the FPGA and a PC. For this we need to implement a Universal Asynchronous Receiver Transmitter (UART) circuit within the FPGA system. You can then use a PC with an RS232 Serial port (shown above) to interface the FPGA with a PC, assuming your development board has the port and voltage conversion circuitry.
Because RS232 is a dated protocol that sometimes isn’t available on modern PC’s, another option is to use a USB-Serial converter chip, which connects to a USB port.
In this post I will detail a UART controlled stopwatch, designed for the Basys 2, using the same stopwatch implementation as in my previous post. To communicate with the PC through serial we will implement a UART receiver and transmitter circuit, as well as a master control circuit that routes all the pieces together. We will then be able to control the stopwatch’s start, stop, and clear functions by sending ascii characters from the PC to the FPGA’s UART receiver circuit, and also send the current stopwatch time from the FPGA’s Transmitter circuit to the PC for viewing.
Reaction time is the duration of time it takes for the brain to interpret a stimulus and do something in reaction to it. The stimulus may be something visual such as a light turning on, something auditory such as a beep, or a touch cue such as a poke. The time it takes for the brain to interpret a stimulus and respond to it can be used as a basic benchmark to measure and compare mental acuity.
We will be implementing a reaction timer on an FPGA that turns on an LED after a psuedorandom period of time, and uses a pushbutton as a reaction input. There will be 3 input buttons: clear, start, and stop. The system will begin in an idle state waiting for the user to press the start button. When the start button is pressed, a random time interval will elapse before the LED turns on. When the LED turns on a reaction timer will begin counting the number of milliseconds until the user presses the stop button. When the stop button is pressed, the reaction time will be shown on a 4 digit 7-segment display in the format “0.000” seconds, up to a value of 9.999 seconds. The user can then press the clear button to reset the time display and go back to the idle state.
For this project we will be using the Basys 2 FPGA development board to implement the design, as it has the 4 digit display, pushbuttons, and LED that we need onboard.
Binary Coded Decimal format is a binary encoding of decimal numbers that represents each decimal digit by a fixed binary number. For example, 42 is represented in BCD format by the binary representations of 4 and 2, as shown above. The BCD format is common in electronic systems where numeric digits are displayed, as well as in systems where the rounding and conversion errors introduced by binary floating point representation and arithmetic are undesirable.
We will focus on designing a conversion circuit that converts a BCD formatted number to to a binary formatted number. I chose to detail this direction of conversion as binary to BCD conversion circuits are easily be found by a quick web search.
We will consider two algorithms to perform the conversion, the first being a direct arithmetic approach, and the second an iterative algorithm using a finite state machine with data path (FSMD).
We will be designing for the Basys 2 FPGA board which has 8 input switches. We can use the 8 input switches to encode 2 BCD numbers of 4 bits each. We will therefore concern ourselves with designing a circuit to convert a 2 digit BCD number to a 7 bit binary representation (27 = 128 > 99, the largest 2 digit BCD number we can input).