4er slot (3. bsp fertig)
[dide_16.git] / bsp3 / Designflow / src / vga_driver_arc.vhd
1 -------------------------------------------------------------------------------
2 -- Title      : vga_driver architecture
3 -- Project    : LU Digital Design
4 -------------------------------------------------------------------------------
5 -- File       : vga_driver.vhd
6 -- Author     : Thomas Handl
7 -- Company    : TU Wien
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 -------------------------------------------------------------------------------
15 -- Revisions  :
16 -- Date        Version  Author  Description
17 -- 2004-12-15  1.0      handl   Created
18 -- 2006-01-24  2.0      ST      revised
19 -------------------------------------------------------------------------------
20
21 -------------------------------------------------------------------------------
22 -- LIBRARIES
23 -------------------------------------------------------------------------------
24
25 library IEEE;
26 use IEEE.std_logic_1164.all;
27 use IEEE.std_logic_unsigned.all;
28 use IEEE.std_logic_arith.all;
29
30 use work.vga_pak.all;
31
32 -------------------------------------------------------------------------------
33 -- ARCHITECTURE
34 -------------------------------------------------------------------------------
35
36 architecture behav of vga_driver is
37
38   attribute syn_preserve          : boolean;
39   attribute syn_preserve of behav : architecture is true;
40
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";
45
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";
50
51   signal h_sync      : std_logic;
52   signal h_sync_next : std_logic;
53
54   signal hsync_state      : hsync_state_type;
55   signal hsync_state_next : hsync_state_type;
56
57   signal h_enable_sig  : std_logic;
58   signal h_enable_next : std_logic;
59
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";
64
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;
68
69   signal v_sync      : std_logic;
70   signal v_sync_next : std_logic;
71
72   signal vsync_state      : vsync_state_type;
73   signal vsync_state_next : vsync_state_type;
74
75   signal v_enable_sig  : std_logic;
76   signal v_enable_next : std_logic;
77
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";
82
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;
86
87
88
89 begin
90
91 ----------------------------------------------------------------------------
92 -- Column_Counter [0..639]: calculates column number for next pixel to be displayed
93 ----------------------------------------------------------------------------
94
95   COLUMN_COUNT_syn: process(clk, reset, column_counter_next)
96   begin
97     if clk'event and clk = '1' then
98       if reset = RES_ACT then                              -- synchronous reset
99         column_counter_sig <= (others => '0');
100       else
101         column_counter_sig <= column_counter_next;         -- synchronous capture
102       end if;
103     end if;
104   end process;
105
106   COLUMN_COUNT_next: process(set_column_counter, column_counter_sig)
107   begin
108     if set_column_counter = ENABLE then                     -- reset counter
109       column_counter_next <= (others => '0');   
110     else
111       if column_counter_sig < RIGHT_BORDER then 
112         column_counter_next <= column_counter_sig + '1';    -- increment column
113       else
114         column_counter_next <= RIGHT_BORDER;                -- ... but do not count beyond right border
115       end if;
116     end if;
117   end process;
118
119 ----------------------------------------------------------------------------
120 -- Line_counter [0..479]: calculates line number for next pixel to be displayed
121 ----------------------------------------------------------------------------
122
123   LINE_COUNT_syn: process(clk, reset, line_counter_next)
124   begin
125     if clk'event and clk = '1' then
126       if reset = RES_ACT then                              -- synchronous reset
127         line_counter_sig <= (others => '0');
128       else
129         line_counter_sig <= line_counter_next;             -- synchronous capture
130       end if;
131     end if;
132   end process;
133
134   LINE_COUNT_next: process(set_line_counter, line_counter_sig, set_hsync_counter)
135   begin
136     if set_line_counter = ENABLE then                     -- reset counter
137       line_counter_next <= (others => '0');   
138     else
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
142         else
143           line_counter_next <= line_counter_sig;
144           end if;
145       else
146         line_counter_next <= BOTTOM_BORDER;               -- ... but do not count below bottom
147       end if;
148     end if;
149   end process;
150
151
152 ----------------------------------------------------------------------------
153 -- Hsync_Counter: generates time base for HSYNC State Machine
154 ----------------------------------------------------------------------------
155
156   HSYNC_COUNT_syn: process(clk, reset, hsync_counter_next)
157   begin
158     if clk'event and clk = '1' then
159       if reset = RES_ACT then                        -- synchronous reset
160         hsync_counter <= (others => '0');
161       else
162         hsync_counter <= hsync_counter_next;         -- synchronous capture
163       end if;
164     end if;
165   end process;
166
167   HSYNC_COUNT_next: process(set_hsync_counter, hsync_counter)
168   begin
169     if set_hsync_counter = ENABLE then               -- reset counter
170       hsync_counter_next <= (others => '0');   
171     else
172       if hsync_counter < HSYN_CNT_MAX then 
173         hsync_counter_next <= hsync_counter + '1';   -- increment time
174       else
175         hsync_counter_next <= HSYN_CNT_MAX;          -- ... but do not count beyond max period
176       end if;
177     end if;
178   end process;
179
180
181 ----------------------------------------------------------------------------
182 -- HSYNC STATE MACHINE: generates hsync signal and controls hsync counter & column counter
183 ----------------------------------------------------------------------------
184
185   HSYNC_FSM_syn: process (clk, reset)       -- synchronous capture
186   begin
187     if clk'event and clk = '1' then
188       if reset = RES_ACT then
189         hsync_state  <= RESET_STATE;
190         h_sync       <= '1';
191         v_enable_sig <= not(ENABLE);
192       else
193         hsync_state  <= hsync_state_next;
194         h_sync       <= h_sync_next;
195         v_enable_sig <= v_enable_next;
196       end if;
197     end if;
198   end process;
199
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;
205
206     case hsync_state is
207       when RESET_STATE =>
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 
211       when B_STATE =>
212         h_sync_next      <= '0';
213         if hsync_counter = TIME_B then
214           hsync_state_next <= C_STATE;
215         end if;
216       when C_STATE =>
217         h_sync_next      <= '1';
218         if hsync_counter = TIME_BC then
219           hsync_state_next <= pre_D_STATE;
220         end if;
221       when pre_D_STATE =>
222         v_enable_next    <= ENABLE;
223         hsync_state_next <= D_STATE;        
224       when D_STATE =>
225         v_enable_next    <= ENABLE;
226         if hsync_counter = TIME_BCD then
227           hsync_state_next <= E_STATE;
228         end if;
229       when E_STATE =>
230         v_enable_next    <= not(ENABLE);
231         if hsync_counter = TIME_A then
232           hsync_state_next <= pre_B_STATE;
233         end if;
234       when pre_B_STATE =>
235         h_sync_next      <= '0';
236         v_enable_next    <= not(ENABLE);        
237         hsync_state_next <= B_STATE;
238       when others =>
239         null;
240     end case;
241   end process;
242
243   HSYNC_FSM_out : process(hsync_state)  -- output logic
244   begin
245     set_hsync_counter  <= not(ENABLE);      -- default assignments
246     set_column_counter <= not(ENABLE);
247
248     case hsync_state is
249       when RESET_STATE =>                   -- outputs for each state are defined here
250         set_hsync_counter  <= ENABLE;
251       when pre_D_STATE =>
252         set_column_counter <= ENABLE;
253       when pre_B_STATE =>
254         set_hsync_counter  <= ENABLE;
255       when others =>
256         null;
257     end case;
258   end process;
259
260
261 ----------------------------------------------------------------------------
262 -- Vsync_Counter: generates time base for VSYNC State Machine
263 ----------------------------------------------------------------------------
264
265   VSYNC_COUNT_syn: process(clk, reset, vsync_counter_next)
266   begin
267     if clk'event and clk = '1' then
268       if reset = RES_ACT then                        -- synchronous reset
269         vsync_counter <= (others => '0');
270       else
271         vsync_counter <= vsync_counter_next;         -- synchronous capture
272       end if;
273     end if;
274   end process;
275
276   VSYNC_COUNT_next: process(set_vsync_counter, vsync_counter, set_hsync_counter)
277   begin
278     if set_vsync_counter = ENABLE then               -- reset counter
279       vsync_counter_next <= (others => '0');   
280     else
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
284         else
285           vsync_counter_next <= vsync_counter;
286         end if;
287       else
288         vsync_counter_next <= VSYN_CNT_MAX;          -- ... but do not count beyond max period
289       end if;
290     end if;
291   end process;
292
293
294 ----------------------------------------------------------------------------
295 -- VSYNC STATE MACHINE: generates vsync signal and controls vsync counter & line counter 
296 ----------------------------------------------------------------------------
297
298   VSYNC_FSM_syn : process (clk, reset)      -- synchronous capture
299   begin
300     if clk'event and clk = '1' then
301       if reset = RES_ACT then
302         vsync_state  <= RESET_STATE;
303         v_sync       <= '1';
304         h_enable_sig <= not(ENABLE);
305       else
306         vsync_state  <= vsync_state_next;
307         v_sync       <= v_sync_next;
308         h_enable_sig <= h_enable_next;
309       end if;
310     end if;
311   end process;
312
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;
318
319     case vsync_state is                     -- state transitions and next signals are defined here
320       when RESET_STATE =>
321         v_sync_next      <= '0';
322         h_enable_next    <= not(ENABLE);
323         vsync_state_next <= P_STATE;
324       when P_STATE =>
325         v_sync_next      <= '0';
326         if vsync_counter = time_p then
327           vsync_state_next <= Q_STATE;
328         end if;
329       when Q_STATE =>
330         v_sync_next      <= '1';
331         if vsync_counter = time_pq then
332           vsync_state_next <= pre_R_STATE;
333         end if;
334       when pre_R_STATE =>
335         h_enable_next    <= ENABLE;
336         vsync_state_next <= R_STATE;
337       when R_STATE =>
338         h_enable_next    <= ENABLE;
339         if vsync_counter = time_pqr then
340           vsync_state_next <= S_STATE;
341         end if;
342       when S_STATE =>
343         h_enable_next    <= not(ENABLE);
344         if vsync_counter = time_o then
345           vsync_state_next <= pre_P_STATE;
346         end if;
347       when pre_P_STATE =>
348         v_sync_next      <= '0';
349         h_enable_next    <= not(ENABLE);
350         vsync_state_next <= P_STATE;
351       when others =>
352         null;
353     end case;
354   end process;
355
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);
360
361     case vsync_state is
362       when RESET_STATE =>
363         set_vsync_counter <= ENABLE;
364       when pre_R_STATE =>
365         set_line_counter  <= ENABLE;
366       when pre_P_STATE =>
367         set_vsync_counter <= ENABLE;
368       when others => 
369         null;
370     end case;
371   end process;
372
373
374
375 -- signal wiring for entity (introduced _sig to allow readback of output signals)
376
377   column_counter <= column_counter_sig;
378   v_enable       <= v_enable_sig;
379   line_counter   <= line_counter_sig;
380   h_enable       <= h_enable_sig;
381
382
383   hsync <= h_sync;
384   vsync <= v_sync;
385
386   -----------------------------------------------------------------------------
387   -- debug signals
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;
397   
398 end behav;
399
400 -------------------------------------------------------------------------------
401 -- END ARCHITECTURE
402 -------------------------------------------------------------------------------