We successfully programmed an FPGA to accept inputs from rotary encoders and switches to work like an Etch A Sketch of yore to allow users to “draw” multicolored pictures output to a VGA monitor. The project can be defined by three main functional systems: block memory, game controller, and VGA controller. The inputs to the system are the outputs of the rotary encoders, and the output of the system is the visuals seen on the VGA monitor. As we finished ahead of schedule, the ability to change the color of the drawn lines was included as an added functionality.

Table of Contents

1. Introduction, problem statement (p. 3)

2. Design solution (p. 3)

2.1 Specifications (p. 3)

2.2 Operating instructions (p. 3)

2.3 Theory of operation (p. 4)

2.4 Construction and debugging (p. 6)

3. Evaluation of your design (p. 7)

4. Conclusions and recommendations (p. 7)

5. Acknowledgments (p. 8)

6. References (p. 8)

7. Appendices (p. 9)

1. Introduction

The Etch A Sketch is a mechanical toy with two dials that can be used to respectively draw lines horizontally and vertically. We intend to make a digital circuit version that allows users to draw with two rotary encoders on a VGA monitor. We enhanced the traditional Etch A Sketch in our design by also offering 8 different drawing colors, including the background color, simulating the capability to erase portions of drawings or “pick up the pen.”

2. Design Solution

Specifications (Overview):

Rotary encoders allow users to draw a 2-pixel wide line on our VGA screen (See Fig 2), and switches allow users to flip between pen colors. The only inputs to the system are the two rotary encoders, each consisting of a left and a right turn, as well as a button press, and the color-specifying switches. All outputs are viewed on the VGA monitor. The color of the line is controlled by switches one through three, allowing for a total of eight color combinations.

Operating Instructions:

To Begin:

• Plug the FPGA into the computer for power and to load the final_top.bit file

• Make sure VGA cable is plugged into FPGA and monitor, and that rotary encoders are connected to pins as outlined in the UCF (See Fig 1 for wired FPGA photo)

To Draw:

• Turn the left dial clockwise to extend the drawn line horizontally to the right

• Turn the left dial counterclockwise to extend the line horizontally to the left

• Turn the right dial clockwise to extend the drawn line up vertically

• Turn the right dial counter clockwise to extend the line down vertically

To Change Colors:

• Flip the first 3 switches on the FPGA for a total of 8 colors

• Flip all 3 switches to zero to draw in the background color (black) to erase previous work or “pick up” your pen

To Reset:

• Depress both dials at once to clear the screen

• We plan the first pixel to be in the center of the screen. After the Etch A Sketch clears, the line’s first pixel will be wherever the last pixel was before clearing.

Rotary Encoders send signals A and B into the encoder interface. These signals are interpreted into left, right, up, and down signals. Simultaneous button presses together create the clear tick which is passed into the top level controller. The Top Level block is broken down into three processes: Game Control, Memory Read, and Memory Write. The VGA Controller sends column and row signals to the Top Level Controller which are used during the read process. The write process is controller by internal row and column signals. The read process also converts the DOB data into it’s corresponding 8-bit color value, sending that out to the VGA. The VGA also receives horizontal and vertical sync signals from the VGA controller itself.

Rotary Encoders

Although much more complicated code exists online to run rotary encoders, we accomplished the same functionality with a very simple state machine (Appendix 2a.) One state waits to receive the a or b input from the encoders. Depending on whether it receives a or b, it then goes to the left or right state, emits the appropriate pulse output, and goes to the second wait state until both a and b inputs go back low. Then the cycle repeats. The a and b signals are also routed through the same debouncer module we were given for lab, to reduce the copious noise produced by the rotary encoders. The left, right, up, down, and clear signals produced by the rotary encoders’ rotation and buttons, respectively, are then sent to the top level controller.

VGA Controller

The VGA controller was mostly written by Scott Larsen (see citations) but was modified to suit our project. The VGA controller works specifically for our VGA monitor having a 640x480 resolution and 60Hz refresh rate. We also used a pixel clock of 25Mhz which was created using the same clock divider process as given to us in lab. At the top of our module, the corresponding display, front porch, back porch, sync pulse, and polarities are established. Our values were chosen from a table on Scott Larsen’s website (see Appendix 2F). From these declared constants, the VGA controller then creates the appropriate hsync and vsync signals which are sent directly to the VGA.The controller also creates a display enable signal, and also outputs the current column and row pixel which is being updated.

BRAM

Instead of using the RAM wizard, we decided to use a simple array of vectors dual port RAM architecture. The bulk of this code was written by Dave, and distributed to us during one of our working sessions. Since we are blocking the pixels in two, we only needed to store half the amount of information. 640x480 resolution divided by two gives 320x240 = 76800 individual memory slots. In each of these slots, the memory stores a 4-bit vector, which is used to designate a specific color later on. Given correct write and read addresses (addra and addrb), the RAM can then accept a value of data input (DIA) or output the corresponding stored data (DOB.)

Top Level Controller

The top level controller has several process blocks to do the necessary processing of those signals. The BRAM, VGA Controller, and Encoders are all instantiated within this VHDL module, and are appropriately linked with internal signals and system inputs.

The first process takes into account the current location of the “cursor” and, depending on whether it gets a right, left, up, or down signal from the rotary encoder controller will move the current cursor location. This process also establishes a 4 pixel wide perimeter from the edge of the screen so that the final product has a clear boundary and defined drawing space. The current row and column signals are declared as integers, and set to start the cursor at the center of the screen first, and then leaves the cursor at its last location after each reset.

The second process writes to the RAM. The write address is selected using the equation: Write_Address = Current_Column * ( Current_Row * 320), translating from our x-y coordinates to our 1-D memory array. Data in is selected by the current value of switches one through three on the FPGA. The switches are linked together and appended with a ‘0’ to create a 4-bit vector. This process is set to run on each rising clock edge, so the data is constantly being written as the current location changes. This process also contains the reset condition: if both buttons are depressed, continuously loop through all the addresses and set each data slot to zero.

The final process reads the memory and sends color to the VGA. This process takes the current column and row signals sent from the VGA controller as inputs. The read address is selected using the same equation as previously used to assign the write address. Finally, the color is then interpreted from the read output data, and linked to the VGA.

Construction and Debugging

We divided and conquered; Nadav spearheaded the VGA Controller, Liam the Rotary Encoder Controller, and then we worked together to meet in the middle with our Top Level Controller and Memory Block. Before moving on to the top level section, both the VGA controller and Rotary interface were robustly tested with sample images and oscilloscope tests (appendix 4a). For the most part, the project was very straight forward. There were some problems with the rotary encoders at first, as we tried to make use of code found online that turned out to be a wild goose chase. In the end, writing our own code for that purpose was much easier, and after debouncing, the encoders worked flawlessly. We had similar, but more minor issues updating VGA controller code we found online. There was some initial weirdness creating hsync and vsync signals, which was cleared up by minor changes to the signals lengths. These measurements were made manually using the VHDL simulation tools. After those two ends of our circuit were finished, it was entirely smooth sailing to integrate them with a controller and embed additional functionality.

3. Justification & Evaluation:

Our design is better than the original Etch A Sketch in that we can draw in 8 colors, erase portions of drawings, and simulate picking up our pen. It may not have the same form factor, timeless style, or mechanical simplicity of the original Etch A Sketch, but it does have markedly more room for customization and added features than the original. There is not much we would do differently if we had a redo, except maybe to add better knobs to our encoders or make an enclosure for the FPGA and knobs to make it a little easier to use. All things considered, the project went very smoothly and the final design met all our initially stated functionality and more.

4. Conclusions

The project was a complete success. We managed to not only meet our originally proposed specs, but also to include additional functionality (multiple colors) into our final product. When we began the project, we had no experience with either the VGA or Rotary Encoders, yet as predicted we managed to integrate our design fairly simply after figuring out these basic elements. We would definitely recommend this project to future groups, as it covers a wide range of VHDL concepts and also has a fun final outcome. In general, we attribute most of our success to figuring out the VGA and rotary encoders early on, and would recommend the same to future groups. These are the hardest parts of the project but simply require sitting down and working through them in order to moves forward.

5. Acknowledgements:

Professor Luke and our lab instructor Dave were both incredibly valuable resources. Dave gave us the structure of our memory block and our VGA test pattern. We also built our VGA controller from online code by Scott Larson. Nadav Hendel focused on making our VGA controller and Liam Grace-Flood focused on implementing the rotary encoders. Then both worked together to integrate under one top-level controller, debug, and add more functionality. And last but not least, none of this would have been possible without our wonderful lab TA Quinn.

No state machines were used in our project, except for in our rotary encoder controller:

(b) VHDL Code

VGA Controller

(2) Rotary Encoder Controller

(3) RAM

(4) Top Level Controller

(5) UCF

(c) Resource utilization for your FPGA on the following pages

(d) Critical timing path

(e) Analysis of residual warnings

There are a few warnings left in our code. There are a few sensitivity list warnings, all which don’t actually affect the performance of the processes as demonstrated by the functionality of our product. There are also more than a few latch warnings in which Row/Column values are trimmed in our VGA controller. We are unclear why these warnings are occurring, yet they have had no effect on our final product.

(f) Waveform graphs

Scope output showing the working rotary encoders.

D14 and D13 are A and B, respectively, from the rotary encoder. D5 and D7 are our Left and Right outputs. We can see here if A goes high first, we get a left signal for a single clock cycle, and if B goes high first, we get a right signal for a single clock cycle.

(2) Scott Larsen’s VGA timing table we referenced.

(3) This simulation shows the correctly working horizontal and vertical sync signals as sent by the

VGA controller

(4) A zoomed in picture from above, you can see the display enable working as the row is incremented. This image also shows how the h sync signal pulses twice during the sync pulse section of our vertical sync, which is an indicator that our signals are working correctly.

(5) This Simulation shows our overall top file working. Curr. Col. and Curr. Row. are initialized properly, and the addresses can be see incrementing.