-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvga_controller.vhd
More file actions
204 lines (182 loc) · 7.97 KB
/
vga_controller.vhd
File metadata and controls
204 lines (182 loc) · 7.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
------------------------------------------------------------------------
-- vga_controller_640_60.vhd
------------------------------------------------------------------------
-- Author : Ulrich Zoltán
-- Copyright 2006 Digilent, Inc.
------------------------------------------------------------------------
-- Software version : Xilinx ISE 7.1.04i
-- WebPack
-- Device : 3s200ft256-4
------------------------------------------------------------------------
-- This file contains the logic to generate the synchronization signals,
-- horizontal and vertical pixel counter and video disable signal
-- for the 640x480@60Hz resolution.
------------------------------------------------------------------------
-- Behavioral description
------------------------------------------------------------------------
-- Please read the following article on the web regarding the
-- vga video timings:
-- http://www.epanorama.net/documents/pc/vga_timing.html
-- This module generates the video synch pulses for the monitor to
-- enter 640x480@60Hz resolution state. It also provides horizontal
-- and vertical counters for the currently displayed pixel and a blank
-- signal that is active when the pixel is not inside the visible screen
-- and the color outputs should be reset to 0.
-- timing diagram for the horizontal synch signal (HS)
-- 0 648 744 800 (pixels)
-- -------------------------|______|-----------------
-- timing diagram for the vertical synch signal (VS)
-- 0 482 484 525 (lines)
-- -----------------------------------|______|-------
-- The blank signal is delayed one pixel clock period (40ns) from where
-- the pixel leaves the visible screen, according to the counters, to
-- account for the pixel pipeline delay. This delay happens because
-- it takes time from when the counters indicate current pixel should
-- be displayed to when the color data actually arrives at the monitor
-- pins (memory read delays, synchronization delays).
------------------------------------------------------------------------
-- Port definitions
------------------------------------------------------------------------
-- rst - global reset signal
-- pixel_clk - input pin, from dcm_25MHz
-- - the clock signal generated by a DCM that has
-- - a frequency of 25MHz.
-- HS - output pin, to monitor
-- - horizontal synch pulse
-- VS - output pin, to monitor
-- - vertical synch pulse
-- hcount - output pin, 11 bits, to clients
-- - horizontal count of the currently displayed
-- - pixel (even if not in visible area)
-- vcount - output pin, 11 bits, to clients
-- - vertical count of the currently active video
-- - line (even if not in visible area)
-- blank - output pin, to clients
-- - active when pixel is not in visible area.
------------------------------------------------------------------------
-- Revision History:
-- 09/18/2006(UlrichZ): created
------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- simulation library
library UNISIM;
use UNISIM.VComponents.all;
-- the vga_controller_640_60 entity declaration
-- read above for behavioral description and port definitions.
entity vga_controller_640_60 is
port(
rst : in std_logic;
pixel_clk : in std_logic;
HS : out std_logic;
VS : out std_logic;
hcount : out std_logic_vector(10 downto 0);
vcount : out std_logic_vector(10 downto 0);
blank : out std_logic
);
end vga_controller_640_60;
architecture Behavioral of vga_controller_640_60 is
------------------------------------------------------------------------
-- CONSTANTS
------------------------------------------------------------------------
-- maximum value for the horizontal pixel counter
constant HMAX : std_logic_vector(10 downto 0) := "01100100000"; -- 800
-- maximum value for the vertical pixel counter
constant VMAX : std_logic_vector(10 downto 0) := "01000001101"; -- 525
-- total number of visible columns
constant HLINES: std_logic_vector(10 downto 0) := "01010000000"; -- 640
-- value for the horizontal counter where front porch ends
constant HFP : std_logic_vector(10 downto 0) := "01010001000"; -- 648
-- value for the horizontal counter where the synch pulse ends
constant HSP : std_logic_vector(10 downto 0) := "01011101000"; -- 744
-- total number of visible lines
constant VLINES: std_logic_vector(10 downto 0) := "00111100000"; -- 480
-- value for the vertical counter where the front porch ends
constant VFP : std_logic_vector(10 downto 0) := "00111100010"; -- 482
-- value for the vertical counter where the synch pulse ends
constant VSP : std_logic_vector(10 downto 0) := "00111100100"; -- 484
-- polarity of the horizontal and vertical synch pulse
-- only one polarity used, because for this resolution they coincide.
constant SPP : std_logic := '0';
------------------------------------------------------------------------
-- SIGNALS
------------------------------------------------------------------------
-- horizontal and vertical counters
signal hcounter : std_logic_vector(10 downto 0) := (others => '0');
signal vcounter : std_logic_vector(10 downto 0) := (others => '0');
-- active when inside visible screen area.
signal video_enable: std_logic;
begin
-- output horizontal and vertical counters
hcount <= hcounter;
vcount <= vcounter;
-- blank is active when outside screen visible area
-- color output should be blacked (put on 0) when blank in active
-- blank is delayed one pixel clock period from the video_enable
-- signal to account for the pixel pipeline delay.
blank <= not video_enable when rising_edge(pixel_clk);
-- increment horizontal counter at pixel_clk rate
-- until HMAX is reached, then reset and keep counting
h_count: process(pixel_clk)
begin
if(rising_edge(pixel_clk)) then
if(rst = '1') then
hcounter <= (others => '0');
elsif(hcounter = HMAX) then
hcounter <= (others => '0');
else
hcounter <= hcounter + 1;
end if;
end if;
end process h_count;
-- increment vertical counter when one line is finished
-- (horizontal counter reached HMAX)
-- until VMAX is reached, then reset and keep counting
v_count: process(pixel_clk)
begin
if(rising_edge(pixel_clk)) then
if(rst = '1') then
vcounter <= (others => '0');
elsif(hcounter = HMAX) then
if(vcounter = VMAX) then
vcounter <= (others => '0');
else
vcounter <= vcounter + 1;
end if;
end if;
end if;
end process v_count;
-- generate horizontal synch pulse
-- when horizontal counter is between where the
-- front porch ends and the synch pulse ends.
-- The HS is active (with polarity SPP) for a total of 96 pixels.
do_hs: process(pixel_clk)
begin
if(rising_edge(pixel_clk)) then
if(hcounter >= HFP and hcounter < HSP) then
HS <= SPP;
else
HS <= not SPP;
end if;
end if;
end process do_hs;
-- generate vertical synch pulse
-- when vertical counter is between where the
-- front porch ends and the synch pulse ends.
-- The VS is active (with polarity SPP) for a total of 2 video lines
-- = 2*HMAX = 1600 pixels.
do_vs: process(pixel_clk)
begin
if(rising_edge(pixel_clk)) then
if(vcounter >= VFP and vcounter < VSP) then
VS <= SPP;
else
VS <= not SPP;
end if;
end if;
end process do_vs;
-- enable video output when pixel is in visible area
video_enable <= '1' when (hcounter < HLINES and vcounter < VLINES) else '0';
end Behavioral;