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: 2006-01-24
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;
218 if hsync_counter = TIME_BC then
219 hsync_state_next <= pre_D_STATE;
222 v_enable_next <= ENABLE;
223 hsync_state_next <= D_STATE;
225 v_enable_next <= ENABLE;
226 if hsync_counter = TIME_BCD then
227 hsync_state_next <= E_STATE;
230 v_enable_next <= not(ENABLE);
231 if hsync_counter = TIME_A then
232 hsync_state_next <= pre_B_STATE;
236 v_enable_next <= not(ENABLE);
237 hsync_state_next <= B_STATE;
243 HSYNC_FSM_out : process(hsync_state) -- output logic
245 set_hsync_counter <= not(ENABLE); -- default assignments
246 set_column_counter <= not(ENABLE);
249 when RESET_STATE => -- outputs for each state are defined here
250 set_hsync_counter <= ENABLE;
252 set_column_counter <= ENABLE;
254 set_hsync_counter <= ENABLE;
261 ----------------------------------------------------------------------------
262 -- Vsync_Counter: generates time base for VSYNC State Machine
263 ----------------------------------------------------------------------------
265 VSYNC_COUNT_syn: process(clk, reset, vsync_counter_next)
267 if clk'event and clk = '1' then
268 if reset = RES_ACT then -- synchronous reset
269 vsync_counter <= (others => '0');
271 vsync_counter <= vsync_counter_next; -- synchronous capture
276 VSYNC_COUNT_next: process(set_vsync_counter, vsync_counter, set_hsync_counter)
278 if set_vsync_counter = ENABLE then -- reset counter
279 vsync_counter_next <= (others => '0');
281 if vsync_counter < VSYN_CNT_MAX then
282 if set_hsync_counter = '1' then -- if enabled
283 vsync_counter_next <= vsync_counter + '1'; -- ... increment time
285 vsync_counter_next <= vsync_counter;
288 vsync_counter_next <= VSYN_CNT_MAX; -- ... but do not count beyond max period
294 ----------------------------------------------------------------------------
295 -- VSYNC STATE MACHINE: generates vsync signal and controls vsync counter & line counter
296 ----------------------------------------------------------------------------
298 VSYNC_FSM_syn : process (clk, reset) -- synchronous capture
300 if clk'event and clk = '1' then
301 if reset = RES_ACT then
302 vsync_state <= RESET_STATE;
304 h_enable_sig <= not(ENABLE);
306 vsync_state <= vsync_state_next;
307 v_sync <= v_sync_next;
308 h_enable_sig <= h_enable_next;
313 VSYNC_FSM_next : process(vsync_state, vsync_counter, v_sync, h_enable_sig)
314 begin -- next state logic
315 vsync_state_next <= vsync_state; -- default assignments
316 v_sync_next <= v_sync;
317 h_enable_next <= h_enable_sig;
319 case vsync_state is -- state transitions and next signals are defined here
322 h_enable_next <= not(ENABLE);
323 vsync_state_next <= P_STATE;
326 if vsync_counter = time_p then
327 vsync_state_next <= Q_STATE;
331 if vsync_counter = time_pq then
332 vsync_state_next <= pre_R_STATE;
335 h_enable_next <= ENABLE;
336 vsync_state_next <= R_STATE;
338 h_enable_next <= ENABLE;
339 if vsync_counter = time_pqr then
340 vsync_state_next <= S_STATE;
343 h_enable_next <= not(ENABLE);
344 if vsync_counter = time_o then
345 vsync_state_next <= pre_P_STATE;
349 h_enable_next <= not(ENABLE);
350 vsync_state_next <= P_STATE;
356 VSYNC_FSM_out : process(vsync_state)
357 begin -- output logic
358 set_vsync_counter <= not(ENABLE); -- output values for each state defined here
359 set_line_counter <= not(ENABLE);
363 set_vsync_counter <= ENABLE;
365 set_line_counter <= ENABLE;
367 set_vsync_counter <= ENABLE;
375 -- signal wiring for entity (introduced _sig to allow readback of output signals)
377 column_counter <= column_counter_sig;
378 v_enable <= v_enable_sig;
379 line_counter <= line_counter_sig;
380 h_enable <= h_enable_sig;
386 -----------------------------------------------------------------------------
388 -----------------------------------------------------------------------------
389 d_hsync_state <= hsync_state;
390 d_vsync_state <= vsync_state;
391 d_hsync_counter <= hsync_counter;
392 d_vsync_counter <= vsync_counter;
393 d_set_hsync_counter <= set_hsync_counter;
394 d_set_vsync_counter <= set_vsync_counter;
395 d_set_column_counter <= set_column_counter;
396 d_set_line_counter <= set_line_counter;
400 -------------------------------------------------------------------------------
402 -------------------------------------------------------------------------------