after slot5
[dide_16.git] / bsp4 / 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: 2007-09-13
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         -- C_STATE instead of D_STATE
217       when C_STATE =>
218         h_sync_next      <= '1';
219         if hsync_counter = TIME_BC then
220           hsync_state_next <= pre_D_STATE;
221         end if;
222       when pre_D_STATE =>
223         v_enable_next    <= ENABLE;
224         hsync_state_next <= D_STATE;        
225         -- D_STATE instead of C_STATE
226       when D_STATE =>
227         v_enable_next    <= ENABLE;
228         if hsync_counter = TIME_BCD then
229           hsync_state_next <= E_STATE;
230         end if;
231       when E_STATE =>
232         v_enable_next    <= not(ENABLE);
233         if hsync_counter = TIME_A then
234           hsync_state_next <= pre_B_STATE;
235         end if;
236       when pre_B_STATE =>
237         h_sync_next      <= '0';
238         v_enable_next    <= not(ENABLE);        
239         hsync_state_next <= B_STATE;
240       when others =>
241         null;
242     end case;
243   end process;
244
245   HSYNC_FSM_out : process(hsync_state)  -- output logic
246   begin
247     set_hsync_counter  <= not(ENABLE);      -- default assignments
248     set_column_counter <= not(ENABLE);
249
250     case hsync_state is
251       when RESET_STATE =>                   -- outputs for each state are defined here
252         set_hsync_counter  <= ENABLE;
253       when pre_D_STATE =>
254         set_column_counter <= ENABLE;
255       when pre_B_STATE =>
256         set_hsync_counter  <= ENABLE;
257       when others =>
258         null;
259     end case;
260   end process;
261
262
263 ----------------------------------------------------------------------------
264 -- Vsync_Counter: generates time base for VSYNC State Machine
265 ----------------------------------------------------------------------------
266
267   VSYNC_COUNT_syn: process(clk, reset, vsync_counter_next)
268   begin
269     if clk'event and clk = '1' then
270       if reset = RES_ACT then                        -- synchronous reset
271         vsync_counter <= (others => '0');
272       else
273         vsync_counter <= vsync_counter_next;         -- synchronous capture
274       end if;
275     end if;
276   end process;
277
278   VSYNC_COUNT_next: process(set_vsync_counter, vsync_counter, set_hsync_counter)
279   begin
280     if set_vsync_counter = ENABLE then               -- reset counter
281       vsync_counter_next <= (others => '0');   
282     else
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
286         else
287           vsync_counter_next <= vsync_counter;
288         end if;
289       else
290         vsync_counter_next <= VSYN_CNT_MAX;          -- ... but do not count beyond max period
291       end if;
292     end if;
293   end process;
294
295
296 ----------------------------------------------------------------------------
297 -- VSYNC STATE MACHINE: generates vsync signal and controls vsync counter & line counter 
298 ----------------------------------------------------------------------------
299
300   VSYNC_FSM_syn : process (clk, reset)      -- synchronous capture
301   begin
302     if clk'event and clk = '1' then
303       if reset = RES_ACT then
304         vsync_state  <= RESET_STATE;
305         v_sync       <= '1';
306         h_enable_sig <= not(ENABLE);
307       else
308         vsync_state  <= vsync_state_next;
309         v_sync       <= v_sync_next;
310         h_enable_sig <= h_enable_next;
311       end if;
312     end if;
313   end process;
314
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;
320
321     case vsync_state is                     -- state transitions and next signals are defined here
322       when RESET_STATE =>
323         v_sync_next      <= '0';
324         h_enable_next    <= not(ENABLE);
325         vsync_state_next <= P_STATE;
326       when P_STATE =>
327         v_sync_next      <= '0';
328         if vsync_counter = time_p then
329           vsync_state_next <= Q_STATE;
330         end if;
331       when Q_STATE =>
332         v_sync_next      <= '1';
333         if vsync_counter = time_pq then
334           vsync_state_next <= pre_R_STATE;
335         end if;
336       when pre_R_STATE =>
337         h_enable_next    <= ENABLE;
338         vsync_state_next <= R_STATE;
339       when R_STATE =>
340         h_enable_next    <= ENABLE;
341         if vsync_counter = time_pqr then
342           vsync_state_next <= S_STATE;
343         end if;
344       when S_STATE =>
345         h_enable_next    <= not(ENABLE);
346         if vsync_counter = time_o then
347           vsync_state_next <= pre_P_STATE;
348         end if;
349       when pre_P_STATE =>
350         v_sync_next      <= '0';
351         h_enable_next    <= not(ENABLE);
352         vsync_state_next <= P_STATE;
353       when others =>
354         null;
355     end case;
356   end process;
357
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);
362
363     case vsync_state is
364       when RESET_STATE =>
365         set_vsync_counter <= ENABLE;
366       when pre_R_STATE =>
367         set_line_counter  <= ENABLE;
368       when pre_P_STATE =>
369         set_vsync_counter <= ENABLE;
370       when others => 
371         null;
372     end case;
373   end process;
374
375
376
377 -- signal wiring for entity (introduced _sig to allow readback of output signals)
378
379   column_counter <= column_counter_sig;
380   v_enable       <= v_enable_sig;
381   line_counter   <= line_counter_sig;
382   h_enable       <= h_enable_sig;
383
384
385   hsync <= h_sync;
386   vsync <= v_sync;
387
388   -----------------------------------------------------------------------------
389   -- debug signals
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;
399   
400 end behav;
401
402 -------------------------------------------------------------------------------
403 -- END ARCHITECTURE
404 -------------------------------------------------------------------------------