Program Files (ISE 11.1):
The Simple RGB Project:
RGB_VHDL.zip
The Pyro Logo Project:
Pyro_Logo_VHDL.zip
The Simple RGB Project:
RGB_VHDL.zip
The Pyro Logo Project:
Pyro_Logo_VHDL.zip
The code for this tutorial is not too complex, especially if you are familiar with any of the previous FPGA & VGA tutorials I wrote: Creating VGA With VHDL or Advanced VGA On A UP2. The code used is actually copied from those projects. The main change is the clock rate and the number of pixels the screen can display.
The Clock Rate
The PSP LCD requires a clock input of 7.83 to 9.26 MHz, with ideal clock being 50% duty cycle at 9 MHz. The clock speed of the FPGA used in this tutorial is 100 MHz, so the easiest way to get that near 9 MHz is by using a 'clock divider'. We use some VHDL signals/variables to increment every 100 MHz and output its own, slower clock signal, to the PSP Display.
~~~ Clock Divider Code Begin ~~~
.. .. IF(clk_count = 5) THEN clk_out_9mhz <= '0'; end if; IF(clk_count = 11) THEN clk_out_9mhz <= '1'; clk_count := 0; end if; --Clock Counter Increment clk_count:= 1 + clk_count; --Vga Timing Logic Start: IF(clk_count = 1)THEN .. ..~~~ Clock Divider Code Begin ~~~
The code shown above shows you how counting 11 clock ticks can get us to 100/11 => 9.09 MHz. The duty cycle is 45:55 which is right at the border of the min and max values seen in the theory section. An alternative would be to count 12 clock cycles and use 6 clock ticks for logic 1 and 6 for logic 0. The output clock frequency would then be 100/12 => 8.3 MHz with a 50:50 duty cycle for each clock pulse.
Updating The Pixel Limits
The second thing we need to do to the VHDL code from the previous Creating VGA With VGA project is input our new pixel range. For this PSP LCD, as we saw in the theory section, there are 525 clock ticks per horizontal line (480 visible pixels) and 286 horizontal lines (272 visible lines) per screen refresh. So we will need to update these numbers along with some others in order to follow the theory of the timing diagram shown previously.
~~~VGA VHDL Changes In Bold~~~
--Reset Horizontal Counter IF (h_cnt = 525) THEN h_cnt <= "0000000000"; ELSE h_cnt <= h_cnt + 1; END IF; --Generate Horizontal Sync IF (h_cnt <= 523) AND (h_cnt >= 482) THEN h_sync <= '0'; ELSE h_sync <= '1'; END IF; --Vertical Sync And Reset Vertical Counter IF (v_cnt >= 285) AND (h_cnt >= 499) THEN v_cnt <= "0000000000"; ELSIF (h_cnt = 499) THEN v_cnt <= v_cnt + 1; END IF; --Generate Vertical Sync IF (v_cnt <= 283) AND (v_cnt >= 274) THEN v_sync <= '0'; ELSE v_sync <= '1'; END IF; --Generate Horizontal Data IF (h_cnt <= 479) THEN horizontal_en <= '1'; column <= h_cnt; pixel_column <= (h_cnt-20); ELSE horizontal_en <= '0'; END IF; --Generate Vertical Data IF (v_cnt <= 271) THEN vertical_en <= '1'; row <= v_cnt; pixel_row <= (v_cnt+20); ELSE vertical_en <= '0'; END IF;~~~End Code~~~
User Constraints File (Assigning Pins)
The .UCF file allows us to do many things with a Xilinx FPGA, however in this case we're concerned with assigning VHDL module inputs and outputs to actual pins on the FPGA, specifically the pins the ribbon cable is connected to. A quick look at the datasheet for the specific FPGA board I'm using tells me the names of all the pins connected to the I/O port. Here's a look at the UCF file with pins and signals connected:
~~~UCF File For PSP LCD FPGA~~~
NET "clk" LOC = B15; NET "led_1" LOC = D13; NET "led_2" LOC = D12; NET "blue[0]" LOC = AD22; NET "blue[1]" LOC = AC22; NET "blue[2]" LOC = AD21; NET "blue[3]" LOC = AC21; NET "blue[4]" LOC = AC20; NET "blue[5]" LOC = AD19; NET "green[0]" LOC = AA24; NET "green[1]" LOC = Y23; NET "green[2]" LOC = AA23; NET "green[3]" LOC = AC24; NET "green[4]" LOC = AB23; NET "green[5]" LOC = AD23; NET "red[0]" LOC = V20; NET "red[1]" LOC = W21; NET "red[2]" LOC = V22; NET "red[3]" LOC = W24; NET "red[4]" LOC = Y24; NET "red[5]" LOC = W23; NET "clk_out_9mhz" LOC = Y21; NET "hsync" LOC = AC18; NET "vsync" LOC = AC19;~~~End Code~~~
The LEDs are just debug leds to make sure everything is working. They blink after the FPGA code is downloaded. With the code all written and compiled, download the .bit file to the FPGA and see the results!