1 -------------------------------------------------------------------------------
2 -- Title : vga_driver architecture
3 -- Project : LU Digital Design
4 -------------------------------------------------------------------------------
5 -- File : vga_driver.vhd
6 -- Author : Thomas Handl
8 -- Created : 2004-12-15
9 -- Last update: 2007-09-13
10 -------------------------------------------------------------------------------
11 -- Description: generate hsync and vsync
12 -------------------------------------------------------------------------------
13 -- Copyright (c) 2004 TU Wien
14 -------------------------------------------------------------------------------
16 -- Date Version Author Description
17 -- 2004-12-15 1.0 handl Created
18 -- 2006-01-24 2.0 ST revised
19 -------------------------------------------------------------------------------
21 -------------------------------------------------------------------------------
23 -------------------------------------------------------------------------------
26 use IEEE.std_logic_1164.all;
27 use IEEE.std_logic_unsigned.all;
28 use IEEE.std_logic_arith.all;
32 -------------------------------------------------------------------------------
34 -------------------------------------------------------------------------------
36 architecture behav of vga_driver is
38 attribute syn_preserve : boolean;
39 attribute syn_preserve of behav : architecture is true;
41 constant TIME_A : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "1100011111";
42 constant TIME_B : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "0001011010";
43 constant TIME_BC : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "0010000111";
44 constant TIME_BCD : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "1100000111";
46 constant TIME_O : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "1000001000";
47 constant TIME_P : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "0000000001";
48 constant TIME_PQ : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "0000100001";
49 constant TIME_PQR : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "1000000001";
51 signal h_sync : std_logic;
52 signal h_sync_next : std_logic;
54 signal hsync_state : hsync_state_type;
55 signal hsync_state_next : hsync_state_type;
57 signal h_enable_sig : std_logic;
58 signal h_enable_next : std_logic;
60 signal set_hsync_counter : std_logic;
61 signal hsync_counter : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0);
62 signal hsync_counter_next : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0);
63 constant HSYN_CNT_MAX : std_logic_vector(HSYN_CNT_WIDTH-1 downto 0) := "1111111111";
65 signal column_counter_sig : std_logic_vector(COL_CNT_WIDTH-1 downto 0);
66 signal column_counter_next : std_logic_vector(COL_CNT_WIDTH-1 downto 0);
67 signal set_column_counter : std_logic;
69 signal v_sync : std_logic;
70 signal v_sync_next : std_logic;
72 signal vsync_state : vsync_state_type;
73 signal vsync_state_next : vsync_state_type;
75 signal v_enable_sig : std_logic;
76 signal v_enable_next : std_logic;
78 signal set_vsync_counter : std_logic;
79 signal vsync_counter : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0);
80 signal vsync_counter_next : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0);
81 constant VSYN_CNT_MAX : std_logic_vector(VSYN_CNT_WIDTH-1 downto 0) := "1111111111";
83 signal line_counter_sig : std_logic_vector(LINE_CNT_WIDTH-1 downto 0);
84 signal line_counter_next : std_logic_vector(LINE_CNT_WIDTH-1 downto 0);
85 signal set_line_counter : std_logic;
91 ----------------------------------------------------------------------------
92 -- Column_Counter [0..639]: calculates column number for next pixel to be displayed
93 ----------------------------------------------------------------------------
95 COLUMN_COUNT_syn: process(clk, reset, column_counter_next)
97 if clk'event and clk = '1' then
98 if reset = RES_ACT then -- synchronous reset
99 column_counter_sig <= (others => '0');
101 column_counter_sig <= column_counter_next; -- synchronous capture
106 COLUMN_COUNT_next: process(set_column_counter, column_counter_sig)
108 if set_column_counter = ENABLE then -- reset counter
109 column_counter_next <= (others => '0');
111 if column_counter_sig < RIGHT_BORDER then
112 column_counter_next <= column_counter_sig + '1'; -- increment column
114 column_counter_next <= RIGHT_BORDER; -- ... but do not count beyond right border
119 ----------------------------------------------------------------------------
120 -- Line_counter [0..479]: calculates line number for next pixel to be displayed
121 ----------------------------------------------------------------------------
123 LINE_COUNT_syn: process(clk, reset, line_counter_next)
125 if clk'event and clk = '1' then
126 if reset = RES_ACT then -- synchronous reset
127 line_counter_sig <= (others => '0');
129 line_counter_sig <= line_counter_next; -- synchronous capture
134 LINE_COUNT_next: process(set_line_counter, line_counter_sig, set_hsync_counter)
136 if set_line_counter = ENABLE then -- reset counter
137 line_counter_next <= (others => '0');
139 if line_counter_sig < BOTTOM_BORDER then
140 if set_hsync_counter = '1' then -- when enabled
141 line_counter_next <= line_counter_sig + '1'; -- ... increment line
143 line_counter_next <= line_counter_sig;
146 line_counter_next <= BOTTOM_BORDER; -- ... but do not count below bottom
152 ----------------------------------------------------------------------------
153 -- Hsync_Counter: generates time base for HSYNC State Machine
154 ----------------------------------------------------------------------------
156 HSYNC_COUNT_syn: process(clk, reset, hsync_counter_next)
158 if clk'event and clk = '1' then
159 if reset = RES_ACT then -- synchronous reset
160 hsync_counter <= (others => '0');
162 hsync_counter <= hsync_counter_next; -- synchronous capture
167 HSYNC_COUNT_next: process(set_hsync_counter, hsync_counter)
169 if set_hsync_counter = ENABLE then -- reset counter
170 hsync_counter_next <= (others => '0');
172 if hsync_counter < HSYN_CNT_MAX then
173 hsync_counter_next <= hsync_counter + '1'; -- increment time
175 hsync_counter_next <= HSYN_CNT_MAX; -- ... but do not count beyond max period
181 ----------------------------------------------------------------------------
182 -- HSYNC STATE MACHINE: generates hsync signal and controls hsync counter & column counter
183 ----------------------------------------------------------------------------
185 HSYNC_FSM_syn: process (clk, reset) -- synchronous capture
187 if clk'event and clk = '1' then
188 if reset = RES_ACT then
189 hsync_state <= RESET_STATE;
191 v_enable_sig <= not(ENABLE);
193 hsync_state <= hsync_state_next;
194 h_sync <= h_sync_next;
195 v_enable_sig <= v_enable_next;
200 HSYNC_FSM_next : process(hsync_state, hsync_counter, h_sync, v_enable_sig) -- next-state logic
201 begin -- default assignments
202 hsync_state_next <= hsync_state; -- ... hold current state
203 h_sync_next <= h_sync; -- ... and values
204 v_enable_next <= v_enable_sig;
208 h_sync_next <= '0'; -- next signal values are defined here
209 v_enable_next <= not(ENABLE);
210 hsync_state_next <= B_STATE; -- ... as well as state transitions
213 if hsync_counter = TIME_B then
214 hsync_state_next <= C_STATE;
216 -- C_STATE instead of D_STATE
219 if hsync_counter = TIME_BC then
220 hsync_state_next <= pre_D_STATE;
223 v_enable_next <= ENABLE;
224 hsync_state_next <= D_STATE;
225 -- D_STATE instead of C_STATE
227 v_enable_next <= ENABLE;
228 if hsync_counter = TIME_BCD then
229 hsync_state_next <= E_STATE;
232 v_enable_next <= not(ENABLE);
233 if hsync_counter = TIME_A then
234 hsync_state_next <= pre_B_STATE;
238 v_enable_next <= not(ENABLE);
239 hsync_state_next <= B_STATE;
245 HSYNC_FSM_out : process(hsync_state) -- output logic
247 set_hsync_counter <= not(ENABLE); -- default assignments
248 set_column_counter <= not(ENABLE);
251 when RESET_STATE => -- outputs for each state are defined here
252 set_hsync_counter <= ENABLE;
254 set_column_counter <= ENABLE;
256 set_hsync_counter <= ENABLE;
263 ----------------------------------------------------------------------------
264 -- Vsync_Counter: generates time base for VSYNC State Machine
265 ----------------------------------------------------------------------------
267 VSYNC_COUNT_syn: process(clk, reset, vsync_counter_next)
269 if clk'event and clk = '1' then
270 if reset = RES_ACT then -- synchronous reset
271 vsync_counter <= (others => '0');
273 vsync_counter <= vsync_counter_next; -- synchronous capture
278 VSYNC_COUNT_next: process(set_vsync_counter, vsync_counter, set_hsync_counter)
280 if set_vsync_counter = ENABLE then -- reset counter
281 vsync_counter_next <= (others => '0');
283 if vsync_counter < VSYN_CNT_MAX then
284 if set_hsync_counter = '1' then -- if enabled
285 vsync_counter_next <= vsync_counter + '1'; -- ... increment time
287 vsync_counter_next <= vsync_counter;
290 vsync_counter_next <= VSYN_CNT_MAX; -- ... but do not count beyond max period
296 ----------------------------------------------------------------------------
297 -- VSYNC STATE MACHINE: generates vsync signal and controls vsync counter & line counter
298 ----------------------------------------------------------------------------
300 VSYNC_FSM_syn : process (clk, reset) -- synchronous capture
302 if clk'event and clk = '1' then
303 if reset = RES_ACT then
304 vsync_state <= RESET_STATE;
306 h_enable_sig <= not(ENABLE);
308 vsync_state <= vsync_state_next;
309 v_sync <= v_sync_next;
310 h_enable_sig <= h_enable_next;
315 VSYNC_FSM_next : process(vsync_state, vsync_counter, v_sync, h_enable_sig)
316 begin -- next state logic
317 vsync_state_next <= vsync_state; -- default assignments
318 v_sync_next <= v_sync;
319 h_enable_next <= h_enable_sig;
321 case vsync_state is -- state transitions and next signals are defined here
324 h_enable_next <= not(ENABLE);
325 vsync_state_next <= P_STATE;
328 if vsync_counter = time_p then
329 vsync_state_next <= Q_STATE;
333 if vsync_counter = time_pq then
334 vsync_state_next <= pre_R_STATE;
337 h_enable_next <= ENABLE;
338 vsync_state_next <= R_STATE;
340 h_enable_next <= ENABLE;
341 if vsync_counter = time_pqr then
342 vsync_state_next <= S_STATE;
345 h_enable_next <= not(ENABLE);
346 if vsync_counter = time_o then
347 vsync_state_next <= pre_P_STATE;
351 h_enable_next <= not(ENABLE);
352 vsync_state_next <= P_STATE;
358 VSYNC_FSM_out : process(vsync_state)
359 begin -- output logic
360 set_vsync_counter <= not(ENABLE); -- output values for each state defined here
361 set_line_counter <= not(ENABLE);
365 set_vsync_counter <= ENABLE;
367 set_line_counter <= ENABLE;
369 set_vsync_counter <= ENABLE;
377 -- signal wiring for entity (introduced _sig to allow readback of output signals)
379 column_counter <= column_counter_sig;
380 v_enable <= v_enable_sig;
381 line_counter <= line_counter_sig;
382 h_enable <= h_enable_sig;
388 -----------------------------------------------------------------------------
390 -----------------------------------------------------------------------------
391 d_hsync_state <= hsync_state;
392 d_vsync_state <= vsync_state;
393 d_hsync_counter <= hsync_counter;
394 d_vsync_counter <= vsync_counter;
395 d_set_hsync_counter <= set_hsync_counter;
396 d_set_vsync_counter <= set_vsync_counter;
397 d_set_column_counter <= set_column_counter;
398 d_set_line_counter <= set_line_counter;
402 -------------------------------------------------------------------------------
404 -------------------------------------------------------------------------------