| Lab 4 : Video Graphics Array and Image BufferIntroduction
				The Video Graphics Array (VGA) protocol is a simple 
				protocol for displaying graphics to a CRT and/or most LCD computer 
				displays. The protocol involves "scanning" the screen and using 
				two signals called hsync and vsync to synchronize 
				the exact location on the screen where cursor is ready to draw. 
				The user guide shows the technical specifics of how the signals 
				are generated for the VGA protocol. You will have to read the Xilinx 
				Spartan-3E user guide pages to be more familiar with what you are 
				working with for this lab. VGA timing information can be found at
				
				VGA Timing and a VGA resolution calculator can be found at
				VGA to 
				RGB. 
 The FPGA board comes with a standard VGA connector and use five 
				signals to communicate with the display. The signals are hsync, 
				vsync, red, green, and blue. With these three signals, 
				we can successfully generate eight different colors, which is admittedly 
				somewhat limiting, but useful for instructional purposes.
 
 A VGA Driver is typically nothing more than some logic that drives 
				horizontal and vertical sync signals on and off so the scan gun 
				behind your monitor knows when to start shooting the next row or 
				column.
 
 
  Figure: Shows the timing diagram of hsync.
 The timing table for the horizontal sync is shown in the figure 
				below (you will see later that the vertical sync works exactly the 
				same).
 
 
  Figure: Shows the timing table for hsync.
 At the start of a line, the horizontal sync signal drops to a logical 
				low for a certain amount of time. The horizontal sync signal then 
				gets pulsed to a logical high, but at this point, the VGA scan gun 
				is not ready to draw onto the screen; this is called the front porch. 
				After a specified front porch period, the screen is ready to display 
				onto the screen. The horizontal sync allows for 640 distinct pixels 
				to be displayed before going into the back porch stage. In the back 
				porch stage, the VGA scan gun has actually passed the viewable portion 
				of the screen, and cannot paint to the screen. Finally, the pulse 
				is dropped again, and the process is repeated.
 
 Your first (and most difficult) task will be to capture the VGA 
				Driver behavior as sequential logic. Before we go into details, 
				shown below is a block diagram of the VGA Driver component you will 
				be designing. The inputs into the VGA Driver will be a clock and 
				reset. The clock will be operating at 25 MHz, but as we learned 
				in the previous lab, we can assume that we can input an exact 25MHz 
				clock using the clock generator or DCM component. The outputs from 
				your VGA driver will be a hsync and vsync signals. These are single 
				bit values. The last two outputs will hcount and vcount. hcount 
				will be N bits wide, since we need to be able to count to at least 
				800 for an entire row of display information. Similarly, vcount 
				will be N bits. Both hsync and vsync, you need to be able to implement  
				timing diagram in figure below.
 
 
  Figure: Shows the timing diagram for hsync and vsync.
 You'll notice several different widths specified for this timing 
				diagram:
 
					Both the horizontal and vertical sync signals capture the same timing 
				model, the only difference being the lengths of each of the pulse 
				width, front porch, back porch, display time, etc. You can find 
				the exact timings for each signal in the Spartan 3E Users Manual.Tpw: Time of the pulse width: How long to keep the signal 
					lowTs : Time period: One complete row/column of informationTdisp : Time of Display: This is the time we can actually 
					display informationTfp: Time front porch: The amount of time for the front 
					porchTbp: Time back porch: The amount of time for the back porch 
 You will also need to maintain counters for both the vertical and 
				horizontal count, because these are what actually allow other components 
				to display information at the correct time. For instance, if your 
				VGA driver gave an hcount = 500, and vcount = 400, another component 
				could color that appropriate pixel.
 
 So how do we actually model this component using the techniques 
				you have learned in class? Well, first you need to decide whether 
				you can capture the behavior with a HLSM, FSM, or combinational 
				logic. Can the VGA display be captured with one state machine, multiple 
				state machines? What's easier? This lab will be the first where 
				you basically need to make all the design decisions. The hardest 
				part of this lab will be coming up with design on paper. Translating 
				your design to VHDL will be the easy part.
 
 Note: VGA pixels must be set to black outside the coloring region, if you fail to do so the driver may not work.
 Part 1 - Design a Synchronous Counters
				 Figure: Shows a high-level view of the first VGA driver to create.
 Inputs: Clock, Reset, Enable
 Outputs: Hsync, Vsync, Hcount, Vcount
 
 Note: Timing for 640 by 480 VGA display. The horizontal 
				counter is the fast counter and the vertical counter is the slower 
				counter.
 
 
  Figure: Shows how hcount and vcount correspond to the screen.
 For this lab, you will allow several methods: behavioral by FSM 
				or structural using counters and a datapath.
 
 Method 1: Single Behavioral FSM
 
 Constants for Horizontal Synchronization
 
					Constants for Vertical Synchronization
						Note:H_PIXELS  = 640H_SYNC_PULSE_WIDTH = 96H_FRONT_PORCH_WIDTH = 16 H_BACK_PORCH_WIDTH = 48H_POLARITY = 0 The horizontal increment increases by one when is exclusively 
					less than (H_PIXELS + H_FRONT_PORCH_WIDTH + H_SYNC_PULSE_WIDTH 
					+ H_BACK_PORCH_WIDTH), otherwise reset to zero.
 
 The horizontal sync should be low when (horizontal increment 
					is exclusively less than H_PIXELS + H_FRONT_PORCH_WIDTH + H_SYNC_PULSE_WIDTH) 
					and (horizontal increment is greater than or equal to H_PIXELS 
					+ H_FRONT_PORCH_WIDTH), when others it is high.
 
					
						Note: The vertical increment increases by one 
					when the horizontal increment reset to zero and vertical 
					increment is exclusively less than (V_PIXELS + V_FRONT_PORCH_WIDTH 
					+ V_SYNC_PULSE_WIDTH + V_BACK_PORCH_WIDTH), otherwise reset 
					to zero.V_PIXELS  = 480V_SYNC_PULSE_WIDTH = 2V_FRONT_PORCH_WIDTH = 11V_BACK_PORCH_WIDTH = 31V_POLARITY = 0 
 The vertival sync should be low when (vertical increment 
					is exclusively less or equal than H_PIXELS + H_FRONT_PORCH_WIDTH 
					+ H_SYNC_PULSE_WIDTH) and (vertical increment is greater than 
					or equal to H_PIXELS + H_FRONT_PORCH_WIDTH), when others it 
					is high.
 Method 2: Mini-Timer Circuits
 
 VGA protocol in VHDL is simply a timer circuit with an FSM. In fact, 
				you should have implement the VGA protocol in lab 1. The output 
				of the faster running timer is for hsync and the one of the slower 
				running timer is for vsync. The counter value from the faster running 
				timer when valid signal is high is the double of the horizontal 
				position inside the display time (the counter counts up to 1280), 
				and the counter from the slower running timer is for vertical. To 
				make the counter from the faster timer represents the horizontal 
				position, we can divide the counter by 2 (which is simply ignore 
				the last bit of the counter).
 
 If you designed the VGA protocol correctly in lab 1, the remaining 
				step is to create a second syncfsm. Remember in syncfsm, we had 
				{96, 48, 640, 16} each minus one; in syncfsm2, you will use {2, 
				33, 480, 10} each minus one. The reasoning for this is because we 
				want the next state at the values not lagging behind by one. It 
				is recommended to start using generics when you can because the 
				generality allows for portability and core re-use.
 
 
  Figure: Shows block diagram of VGA driver using Mini-Timer Circuits. 
				The only important outputs for this diagram are hsync, hcount, 
				vsync, and vcount; the others can be discarded by port mapping 
				them to open in VHDL.
 
 When Completed
 A test bench check is not required, however it would if you design 
				a test bench to test your VGA syncs operate correctly before you. 
				If you ask the TA later on during the download phase why your VGA 
				component isn't working, we will first ask to see your test bench 
				to verify you have the correct behavior. Here is a sample test bench:
				vga_tb.vhdl
 Part 2 - TV Bars
				
				
				Figure: TV bars
 
 The next part of the lab will be simulate colored bars 
				on your VGA monitor to see if everything works correctly. In order 
				to do this, you are going to include your VGA driver in a higher 
				level component since at this point, we have no way to actually 
				output color information. Recall your VGA driver only outputs horizontal 
				and vertical counters, and hsync and vsync signals. To create the 
				color illusion, divide the  The bars component has two inputs 
				for horizontal and vertical counters (which will come from your 
				VGA driver). The bars component then outputs three signals: a red, 
				green, and blue signal.
 
 
  Figure: RGB Code Table.
 
 You will output these signals directly out of your high level component 
				which encapsulates your VGA driver and the bars components. With 
				RGB, we can have at most 8 colored states so divide the horizontal 
				pixels into 8 parts from left to right with each color section. 
				Each color section will have a unique RGB setting corresponding 
				to the horizontal count range. As a reminder, you should only write 
				the color value when you are within the valid hcount and vcount 
				range, otherwise you might get a flickering VGA screen (this means 
				the VGA pixel mist be "black" during the other regions).
 
 
  Figure: TV bars Block Diagram
 
 Inputs: Clock, Reset, Enable
 Outputs: Hsync, Vsync, R, G, B
 
 Note: Do not forget, the VGA is based on a 25mhz, so once 
				again use the Xilinx DCM or Clock Generator component!
 
 Download your design to the board, taking into account the proper 
				pins for the onboard clock, and VGA (see the user guide).
 Part 3 - BRAM Image
				Now that you have some basic knowledge of how the VGA component 
				works and how to use the hcount and vcount signals to our advantage, 
				lets make a slightly more complicated design. In this part, you 
				will a Block RAM (BRAM) to draw a image of your choosing. BRAMs 
				are configurable memory unit that has configurable depth, width, 
				latency and ports. We will use the BRAM to store an image of your 
				choosing. The image can be small, maybe about 100 pixels wide and 
				in height, although you are free to do whatever you want. Google 
				Images has lots of pictures if you search and do not use colored 
				bars, noise, or other non-trivial designs...
 A nice way to access the memory is take advantage of the hcount 
				and vcount signals generated by the VGA component, and concatenate 
				the two signals into one BRAM address which will address the BRAM 
				with your name in it. For example, if you wanted to put your image 
				in the top left corner, and you concatenate hcount and vcount together, 
				you will address the 0th element in memory, which is 
				exactly what you wanted. Placing your image in the middle of the 
				screen works the same way, but you might have to do a few other 
				computations to generate your address. Think about it a bit before 
				doing anything else. You can use a sample
				memory.vhdl or generate your own 
				BRAM, just select RAMB16_S1 in the IPCore Generator. Also here is 
				an example of a checkerboard (checkerboard.vhdl).
 
 Note: It might be to your advantage to write a small script 
				that converts a simple image you get off the internet to the BRAM 
				format. Then, you can just plug the BRAM contents into your code 
				and it should work just fine Perl and Python should have some utilities 
				to read an image, although you are free to use whatever you want.
 Recommended C++ program steps:
 1. EasyBMP to data 
				structure then to .coe format
 Read the images color channels using the EasyBMP library and put 
				values into a data structure. The libraries, documentation, and 
				a example for EasyBMP is provided below.
 EasyBMP_1.06.zip
 EasyBMP_Documentation_1.06.00.zip
 BMP_Image_Parce_to_RGB.cpp
 
 Xilinx provides a library of pre-made components for us to use; 
				one such component is the Block RAM. Add a BRAM to your design by 
				selecting New Source, then IP (Core Generator). Select Memories>RAMS 
				& ROMS>Block RAM Generator. A configuration manager will open to 
				allow you to customize the BRAM component. Make sure to select 'single 
				port ROM' as the memory type. You should configure the depth (number 
				of addresses) and width (number of RGB value bits) appropriately 
				for the image size and quality that you want.
 
 Inside of the BRAM configuration wizard you must specify a .coe 
				file to load the memory with. The .coe files specifies the contents 
				of your memory (your image). It would be helpful to write yourself 
				a script program that converts a bitmap image file into a .coe file. 
				A nice bitmap (BMP) 
				image processing library for C++ is EasyBMP.
 
 An example .coe file for a 2x2 pixel image would resemble the test 
				below. The first two lines must be copied exactly. The following 
				lines specify the value of each address in numerical order starting 
				with 0.
 
 
					
						| Memory_initialization_radix=2; Memory_initialization_vector=
 00,
 00,
 01,
 01;
 |  Once you have configured the BRAM, you can view the instantiation 
				template in ISE to add the component to your top-level design. The 
				BRAM should have 3 ports if correctly generated: clock, input address, 
				and data output. The functionality of the BRAM is the data output 
				will reflect the value found at the address input after 1 clock 
				cycle latency.
 Extra Credit
				 
 
       
 Make an animated character by storing 2 or more images 
				and alternating between them. For even more bonus credit, make you 
				character move across the screen (simulate walking or running, for 
				example).
 OR
 Make a screen saver, where your image moves completely around the 
				screen in a bouncing manner. For even more bonus credit, have several 
				images bouncing off each other and the screen boundaries.
 OR
 Make the character change directions as the bounce from the boundaries. 
				You can do this by reversing the order you read the image. For even 
				more bonus credit, make two or more characters do this across the 
				screen taking into account when the collide with each other.
 OR
 Become more creative and attempt to use this
				sync_ram.vhdl with some of the 
				ideas above!
 Here is the test bench sync_ramtb.vhdl
 |