Merge marina project in subdirectory marina/
[fleet.git] / src / edu / berkeley / fleet / fpga / dvi / vga_timing_generator.vhd
1 -- Module Name:  vga_timing_generator.vhd
2 -- File Description:  Generates VGA timing signals.
3 -- Project:  FPGA Image Registration
4 -- Target Device:  XC5VSX50T (Xilinx Virtex5 SXT)
5 -- Target Board:  ML506
6 -- Synthesis Tool:  Xilinx ISE 9.2
7 -- Copyright (C) 2008 Brandyn Allen White
8 -- Contact:  bwhite(at)cs.ucf.edu
9 -- Project Website:  http://code.google.com/p/fpga-image-registration/
10
11 -- This program is free software: you can redistribute it and/or modify
12 -- it under the terms of the GNU General Public License as published by
13 -- the Free Software Foundation, either version 3 of the License, or
14 -- (at your option) any later version.
15
16 -- This program is distributed in the hope that it will be useful,
17 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
18 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 -- GNU General Public License for more details.
20
21 -- You should have received a copy of the GNU General Public License
22 -- along with this program. If not, see <http://www.gnu.org/licenses/>.
23
24 LIBRARY IEEE;
25 USE IEEE.STD_LOGIC_1164.ALL;
26 USE ieee.numeric_std.ALL;
27
28
29 ENTITY vga_timing_generator IS
30   GENERIC (WIDTH       : integer := 1024;
31            H_FP        : integer := 24;
32            H_SYNC      : integer := 136;
33            H_BP        : integer := 160;
34            HEIGHT      : integer := 768;
35            V_FP        : integer := 3;
36            V_SYNC      : integer := 6;
37            V_BP        : integer := 29;
38            HEIGHT_BITS : integer := 10;
39            WIDTH_BITS  : integer := 10;
40            HCOUNT_BITS : integer := 11;
41            VCOUNT_BITS : integer := 11;
42            DATA_DELAY  : integer := 0
43
44
45            );
46   PORT (CLK            : IN  std_logic;
47         RST            : IN  std_logic;
48         HSYNC          : OUT std_logic;
49         VSYNC          : OUT std_logic;
50         X_COORD        : OUT std_logic_vector(WIDTH_BITS-1 DOWNTO 0);
51         Y_COORD        : OUT std_logic_vector(HEIGHT_BITS-1 DOWNTO 0);
52         PIXEL_COUNT    : OUT std_logic_vector(WIDTH_BITS+HEIGHT_BITS-1 DOWNTO 0);
53         DATA_VALID     : OUT std_logic;
54         DATA_VALID_EXT : OUT std_logic);
55 END vga_timing_generator;
56
57 ARCHITECTURE Behavioral OF vga_timing_generator IS
58   CONSTANT H_TOTAL                  : integer                                     := WIDTH+H_FP+H_SYNC+H_BP;
59   CONSTANT V_TOTAL                  : integer                                     := HEIGHT+V_FP+V_SYNC+V_BP;
60   -- bit more than specified to cover the H_FP
61   SIGNAL   hcount                   : unsigned(HCOUNT_BITS-1 DOWNTO 0)            := (OTHERS => '0');
62   SIGNAL   vcount                   : unsigned(VCOUNT_BITS-1 DOWNTO 0)            := (OTHERS => '0');
63   SIGNAL   vsync_reg, hsync_reg     : std_logic                                   := '0';  -- NOTE These are active high signals
64   SIGNAL   pixel_count_reg          : unsigned(WIDTH_BITS+HEIGHT_BITS-1 DOWNTO 0) := (OTHERS => '0');  -- This is used to keep track of the number of valid pixels that have been output this frame.  Used to allow pixel selection to be made based on 1D memory addresses.
65   SIGNAL   x_coord_reg              : unsigned(WIDTH_BITS-1 DOWNTO 0)             := (OTHERS => '0');
66   SIGNAL   y_coord_reg              : unsigned(HEIGHT_BITS-1 DOWNTO 0)            := (OTHERS => '0');
67   SIGNAL   data_valid_reg           : std_logic                                   := '0';
68 BEGIN
69   HSYNC       <= hsync_reg;
70   VSYNC       <= vsync_reg;
71   X_COORD     <= std_logic_vector(x_coord_reg);
72   Y_COORD     <= std_logic_vector(y_coord_reg);
73   PIXEL_COUNT <= std_logic_vector(pixel_count_reg);
74   DATA_VALID  <= data_valid_reg;
75   PROCESS(CLK)
76   BEGIN
77     -----------------------------------------------------------------------
78     -- Zones w.r.t. hcount
79     -- 0<=X<H_BP-1                        -  Back Porch of H
80     -- H_BP-1=<X<H_BP+WIDTH-1             -  Active horizontal data
81     -- H_BP+WIDTH-1<=X<WIDTH+H_FP+H_BP-1  -  Front Porch/HSYNC
82     -- WIDTH+H_FP+H_BP-1<=X<H_TOTAL-1     -  HSYNC
83
84     -- Horizontal Pixel Count
85     IF (CLK'event AND CLK = '1') THEN
86       IF (RST = '1') THEN
87         vcount          <= (OTHERS => '0');
88         hcount          <= (OTHERS => '0');
89         hsync_reg       <= '0';
90         vsync_reg       <= '0';
91         pixel_count_reg <= (OTHERS => '0');
92         x_coord_reg     <= (OTHERS => '0');
93         y_coord_reg     <= (OTHERS => '0');
94       ELSE
95         -- Data valid signal - This is corrected for the data delay by doing
96         -- everything early by DATA_DELAY CTs.
97         IF (H_BP-DATA_DELAY-1 <= hcount AND hcount < WIDTH+H_BP-DATA_DELAY-1 AND V_BP <= vcount AND vcount < HEIGHT+V_BP) THEN
98           data_valid_reg <= '1';
99           IF data_valid_reg = '1' THEN
100             x_coord_reg <= x_coord_reg + 1;
101           END IF;
102           IF (data_valid_reg = '1' AND vcount = V_BP) OR vcount > V_BP THEN
103             pixel_count_reg <= pixel_count_reg + 1;
104           END IF;
105         ELSE
106           x_coord_reg    <= (OTHERS => '0');
107           data_valid_reg <= '0';
108         END IF;
109
110         -- Data valid external signal (to be in line with HSYNC/VSYNC)
111         IF (H_BP-1 <= hcount AND hcount < WIDTH+H_BP-1 AND V_BP <= vcount AND vcount < HEIGHT+V_BP) THEN
112           DATA_VALID_EXT <= '1';
113         ELSE
114           DATA_VALID_EXT <= '0';
115         END IF;
116
117         -- Horizontal Line Counter
118         IF hcount = (H_TOTAL-1) THEN    -- Reset hcount
119           hcount <= (OTHERS => '0');
120         ELSE
121           hcount <= hcount + 1;
122         END IF;
123
124         -- Vertical Line Counter
125         IF hcount = (H_TOTAL - 1) AND (vcount = (V_TOTAL - 1)) THEN  -- Reset
126                                                                      -- vcount
127           vcount          <= (OTHERS => '0');
128           pixel_count_reg <= (OTHERS => '0');
129           y_coord_reg     <= (OTHERS => '0');
130         ELSIF hcount = (H_TOTAL - 1) THEN
131           vcount  <= vcount + 1;
132           IF V_BP <= vcount AND vcount < HEIGHT+V_BP-1 THEN
133             y_coord_reg <= y_coord_reg + 1;
134           END IF;
135         END IF;
136
137         -- Horizontal Sync Pulse
138         IF hcount = (WIDTH+H_FP+H_BP-1) THEN
139           hsync_reg <= '1';
140         ELSIF hcount = (H_TOTAL-1) THEN
141           hsync_reg <= '0';
142         END IF;
143
144         -- Vertical Sync Pulse
145         IF hcount = (H_TOTAL-1) AND vcount = (HEIGHT+V_FP+V_BP-1) THEN
146           vsync_reg <= '1';
147         ELSIF hcount = (H_TOTAL-1) AND vcount = (V_TOTAL-1) THEN
148           vsync_reg <= '0';
149         END IF;
150       END IF;
151     END IF;
152   END PROCESS;
153 END Behavioral;
154