1 -- Module Name: vga_timing_decode.vhd
2 -- File Description: Takes in VGA timing signals, outputs pixel oriented
3 -- signals. Valid output starts at the beginning of the next valid frame.
4 -- Project: FPGA Image Registration
5 -- Target Device: XC5VSX50T (Xilinx Virtex5 SXT)
7 -- Synthesis Tool: Xilinx ISE 9.2
8 -- Copyright (C) 2008 Brandyn Allen White
9 -- Contact: bwhite(at)cs.ucf.edu
10 -- Project Website: http://code.google.com/p/fpga-image-registration/
12 -- This program is free software: you can redistribute it and/or modify
13 -- it under the terms of the GNU General Public License as published by
14 -- the Free Software Foundation, either version 3 of the License, or
15 -- (at your option) any later version.
17 -- This program is distributed in the hope that it will be useful,
18 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
19 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 -- GNU General Public License for more details.
22 -- You should have received a copy of the GNU General Public License
23 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
26 USE IEEE.STD_LOGIC_1164.ALL;
27 USE ieee.numeric_std.ALL;
29 ENTITY vga_timing_decode IS
31 HEIGHT : integer := 480;
32 WIDTH : integer := 640;
33 H_BP : integer := 117;
35 HEIGHT_BITS : integer := 10;
36 WIDTH_BITS : integer := 10;
37 HCOUNT_BITS : integer := 11;
38 VCOUNT_BITS : integer := 11;
39 DATA_DELAY : integer := 0
41 PORT (CLK : IN std_logic;
45 X_COORD : OUT unsigned(WIDTH_BITS-1 DOWNTO 0);
46 Y_COORD : OUT unsigned(HEIGHT_BITS-1 DOWNTO 0);
47 PIXEL_COUNT : OUT unsigned(HEIGHT_BITS+WIDTH_BITS-1 DOWNTO 0);
48 DATA_VALID : OUT std_logic;
49 DONE : OUT std_logic);
50 END vga_timing_decode;
52 ARCHITECTURE Behavioral OF vga_timing_decode IS
53 SIGNAL hcount : unsigned(HCOUNT_BITS-1 DOWNTO 0) := (OTHERS => '0');
54 SIGNAL vcount : unsigned(VCOUNT_BITS-1 DOWNTO 0) := (OTHERS => '0');
55 SIGNAL pixel_count_reg : unsigned(HEIGHT_BITS+WIDTH_BITS-1 DOWNTO 0) := (OTHERS => '0');
56 SIGNAL x_coord_reg : unsigned(WIDTH_BITS-1 DOWNTO 0) := (OTHERS => '0');
57 SIGNAL y_coord_reg : unsigned(HEIGHT_BITS-1 DOWNTO 0) := (OTHERS => '0');
58 SIGNAL prev_hsync, prev_vsync : std_logic := '0';
59 SIGNAL data_valid_reg : std_logic := '0';
60 SIGNAL vsync_asserted, done_reg : std_logic := '0'; -- Used to ensure that we only signal the output as valid when we have started from the beginning of a frame
62 X_COORD <= x_coord_reg;
63 Y_COORD <= y_coord_reg;
64 PIXEL_COUNT <= pixel_count_reg;
65 -- Output data as valid only starting at the first full frame we receive
66 DATA_VALID <= data_valid_reg WHEN vsync_asserted = '1' ELSE '0';
70 IF CLK'event AND CLK = '1' THEN
72 hcount <= (OTHERS => '0');
73 vcount <= (OTHERS => '0');
74 pixel_count_reg <= (OTHERS => '0');
75 x_coord_reg <= (OTHERS => '0');
76 y_coord_reg <= (OTHERS => '0');
78 data_valid_reg <= '0';
79 vsync_asserted <= '0';
84 -----------------------------------------------------------------------
85 -- Zones w.r.t. hcount
86 -- 0<=X<H_BP-1 - Back Porch of H
87 -- H_BP-1=<X<H_BP+WIDTH-1 - Active horizontal data
88 -- H_BP+WIDTH-1<=X - Front Porch/HSYNC
90 -- The backporch -1 is due to the register delay
91 IF HSYNC = '0' AND VSYNC = '0' AND hcount >= H_BP-DATA_DELAY-1 AND hcount < H_BP+WIDTH-DATA_DELAY-1 AND vcount >= V_BP AND vcount < V_BP+HEIGHT THEN
92 IF vsync_asserted='1' THEN
93 data_valid_reg <= '1';
96 IF data_valid_reg = '1' THEN -- This makes the first valid pixel 0,
98 x_coord_reg <= x_coord_reg + 1;
101 -- This makes the first valid pixel 0, and properly increments the
102 -- first pixels of every other line
103 IF (data_valid_reg = '1' AND vcount = V_BP) OR vcount > V_BP THEN
104 pixel_count_reg <= pixel_count_reg + 1;
107 data_valid_reg <= '0';
108 x_coord_reg <= (OTHERS => '0');
112 IF HSYNC = '1' AND prev_hsync = '0' AND vcount >= V_BP AND vcount < V_BP+HEIGHT-1 THEN
113 y_coord_reg <= y_coord_reg + 1;
116 vcount <= (OTHERS => '0');
117 pixel_count_reg <= (OTHERS => '0');
118 y_coord_reg <= (OTHERS => '0');
119 vsync_asserted <= '1';
120 -- We are done when we have been in the VSYNC='1' region previously,
121 -- and the last CT we were in the VSYNC='0' region, which means we
122 -- have been through all of the coordinates. It will be high for one
123 -- CT, then reset to 0.
124 -- NOTE: This assumes that the VSYNC level has no glitches
125 -- NOTE: Done will be high for one CT every full frame processed
126 IF prev_vsync = '0' AND vsync_asserted = '1' THEN
134 hcount <= hcount + 1;
136 hcount <= (OTHERS => '0');
137 IF prev_hsync = '0' THEN
138 vcount <= vcount + 1;