1 -------------------------------------------------------------------------
\r
3 -- Filename: textmode_vga_h_sm_beh.vhd
\r
6 -- Short Description:
\r
7 -- ==================
\r
8 -- Behavioural implementation of the horizontal VGA timing finite state machine
\r
10 -------------------------------------------------------------------------
\r
13 use ieee.std_logic_1164.all;
\r
14 use ieee.numeric_std.all;
\r
15 use work.math_pkg.all;
\r
16 use work.textmode_vga_pkg.all;
\r
17 use work.font_pkg.all;
\r
19 architecture beh of textmode_vga_h_sm is
\r
20 type TEXTMODE_VGA_H_SM_STATE_TYPE is
\r
22 HSYNC_FIRST, HSYNC, HBACK_FIRST, HBACK, BLACK_CHAR_NEW,
\r
23 BLACK_PIXEL, CHAR_NEW_FG, PIXEL_FG, CHAR_NEW_BG, PIXEL_BG,
\r
24 HFRONT_FIRST, HFRONT, HFRONT_LAST, CHAR_NEW_CURSOR, PIXEL_CURSOR
\r
26 signal textmode_vga_h_sm_state, textmode_vga_h_sm_state_next : TEXTMODE_VGA_H_SM_STATE_TYPE;
\r
27 signal hcnt, hcnt_next : integer range 0 to max(HSYNC_CYCLES, HBACK_CYCLES, HFRONT_CYCLES);
\r
28 signal current_char, current_char_next : std_logic_vector(0 to CHAR_WIDTH - 1);
\r
29 signal current_color, current_color_next : std_logic_vector(RED_BITS + GREEN_BITS + BLUE_BITS - 1 downto 0);
\r
30 signal char_width_pixel, char_width_pixel_next : integer range 0 to CHAR_WIDTH;
\r
31 signal char_cnt_int, char_cnt_next : integer range 0 to COLUMN_COUNT;
\r
33 char_cnt <= std_logic_vector(to_unsigned(char_cnt_int, log2c(COLUMN_COUNT)));
\r
35 h_sm_next_state : process(textmode_vga_h_sm_state, hcnt, is_data_line, decoded_char, char_width_pixel, current_char, char_cnt_int, char_line_cnt, blink, cursor_line, cursor_column, cursor_state)
\r
37 textmode_vga_h_sm_state_next <= textmode_vga_h_sm_state;
\r
38 case textmode_vga_h_sm_state is
\r
40 textmode_vga_h_sm_state_next <= HSYNC;
\r
42 if hcnt = HSYNC_CYCLES - 1 then
\r
43 textmode_vga_h_sm_state_next <= HBACK_FIRST;
\r
46 textmode_vga_h_sm_state_next <= HBACK;
\r
48 if hcnt = HBACK_CYCLES - 1 then
\r
49 if is_data_line = '0' then
\r
50 textmode_vga_h_sm_state_next <= BLACK_CHAR_NEW;
\r
52 if (cursor_state = CURSOR_ON or
\r
53 (cursor_state = CURSOR_BLINK and blink = '0')) and
\r
54 char_line_cnt = cursor_line and
\r
55 std_logic_vector(to_unsigned(char_cnt_int, log2c(COLUMN_COUNT))) = cursor_column then
\r
56 textmode_vga_h_sm_state_next <= CHAR_NEW_CURSOR;
\r
57 elsif decoded_char(0) = '1' then
\r
58 textmode_vga_h_sm_state_next <= CHAR_NEW_FG;
\r
60 textmode_vga_h_sm_state_next <= CHAR_NEW_BG;
\r
64 when BLACK_CHAR_NEW =>
\r
65 textmode_vga_h_sm_state_next <= BLACK_PIXEL;
\r
67 if char_width_pixel = CHAR_WIDTH - 1 then
\r
68 if char_cnt_int = COLUMN_COUNT then
\r
69 textmode_vga_h_sm_state_next <= HFRONT_FIRST;
\r
71 textmode_vga_h_sm_state_next <= BLACK_CHAR_NEW;
\r
75 if decoded_char(1) = '1' then
\r
76 textmode_vga_h_sm_state_next <= PIXEL_FG;
\r
78 textmode_vga_h_sm_state_next <= PIXEL_BG;
\r
80 when CHAR_NEW_CURSOR =>
\r
81 textmode_vga_h_sm_state_next <= PIXEL_CURSOR;
\r
83 if char_width_pixel = CHAR_WIDTH - 1 then
\r
84 if char_cnt_int = COLUMN_COUNT then
\r
85 textmode_vga_h_sm_state_next <= HFRONT_FIRST;
\r
87 if (cursor_state = CURSOR_ON or
\r
88 (cursor_state = CURSOR_BLINK and blink = '0')) and
\r
89 char_line_cnt = cursor_line and
\r
90 std_logic_vector(to_unsigned(char_cnt_int, log2c(COLUMN_COUNT))) = cursor_column then
\r
91 textmode_vga_h_sm_state_next <= CHAR_NEW_CURSOR;
\r
92 elsif decoded_char(0) = '1' then
\r
93 textmode_vga_h_sm_state_next <= CHAR_NEW_FG;
\r
95 textmode_vga_h_sm_state_next <= CHAR_NEW_BG;
\r
99 if current_char(char_width_pixel + 1) = '1' then
\r
100 textmode_vga_h_sm_state_next <= PIXEL_FG;
\r
102 textmode_vga_h_sm_state_next <= PIXEL_BG;
\r
105 when PIXEL_CURSOR =>
\r
106 if char_width_pixel = CHAR_WIDTH - 1 then
\r
107 if char_cnt_int = COLUMN_COUNT then
\r
108 textmode_vga_h_sm_state_next <= HFRONT_FIRST;
\r
110 if decoded_char(0) = '1' then
\r
111 textmode_vga_h_sm_state_next <= CHAR_NEW_FG;
\r
113 textmode_vga_h_sm_state_next <= CHAR_NEW_BG;
\r
117 when CHAR_NEW_BG =>
\r
118 if decoded_char(1) = '1' then
\r
119 textmode_vga_h_sm_state_next <= PIXEL_FG;
\r
121 textmode_vga_h_sm_state_next <= PIXEL_BG;
\r
124 if char_width_pixel = CHAR_WIDTH - 1 then
\r
125 if char_cnt_int = COLUMN_COUNT then
\r
126 textmode_vga_h_sm_state_next <= HFRONT_FIRST;
\r
128 if (cursor_state = CURSOR_ON or
\r
129 (cursor_state = CURSOR_BLINK and blink = '0')) and
\r
130 char_line_cnt = cursor_line and
\r
131 std_logic_vector(to_unsigned(char_cnt_int, log2c(COLUMN_COUNT))) = cursor_column then
\r
132 textmode_vga_h_sm_state_next <= CHAR_NEW_CURSOR;
\r
133 elsif decoded_char(0) = '1' then
\r
134 textmode_vga_h_sm_state_next <= CHAR_NEW_FG;
\r
136 textmode_vga_h_sm_state_next <= CHAR_NEW_BG;
\r
140 if current_char(char_width_pixel + 1) = '1' then
\r
141 textmode_vga_h_sm_state_next <= PIXEL_FG;
\r
143 textmode_vga_h_sm_state_next <= PIXEL_BG;
\r
146 when HFRONT_FIRST =>
\r
147 textmode_vga_h_sm_state_next <= HFRONT;
\r
149 if hcnt = HFRONT_CYCLES - 2 then
\r
150 textmode_vga_h_sm_state_next <= HFRONT_LAST;
\r
152 when HFRONT_LAST =>
\r
153 textmode_vga_h_sm_state_next <= HSYNC_FIRST;
\r
155 end process h_sm_next_state;
\r
157 h_sm_output : process(textmode_vga_h_sm_state, decoded_char, current_char, background_color, hcnt, char_cnt_int, char_width_pixel, current_color, color, cursor_color)
\r
160 rgb <= COLOR_BLACK(3 * COLOR_SIZE - 1 downto 3 * COLOR_SIZE - RED_BITS) &
\r
161 COLOR_BLACK(2 * COLOR_SIZE - 1 downto 2 * COLOR_SIZE - GREEN_BITS) &
\r
162 COLOR_BLACK(COLOR_SIZE - 1 downto COLOR_SIZE - BLUE_BITS);
\r
165 char_cnt_next <= char_cnt_int;
\r
166 char_width_pixel_next <= char_width_pixel;
\r
167 current_char_next <= current_char;
\r
168 current_color_next <= current_color;
\r
170 case textmode_vga_h_sm_state is
\r
171 when HSYNC_FIRST =>
\r
174 char_cnt_next <= 0;
\r
177 hcnt_next <= hcnt + 1;
\r
178 when HBACK_FIRST =>
\r
181 hcnt_next <= hcnt + 1;
\r
182 when BLACK_CHAR_NEW =>
\r
183 char_cnt_next <= char_cnt_int + 1;
\r
184 char_width_pixel_next <= 1;
\r
185 when BLACK_PIXEL =>
\r
186 char_width_pixel_next <= char_width_pixel + 1;
\r
187 when CHAR_NEW_FG =>
\r
189 char_cnt_next <= char_cnt_int + 1;
\r
190 char_width_pixel_next <= 1;
\r
191 current_char_next <= decoded_char;
\r
192 current_color_next <= color;
\r
194 rgb <= current_color;
\r
195 char_width_pixel_next <= char_width_pixel + 1;
\r
196 when CHAR_NEW_CURSOR =>
\r
197 rgb <= cursor_color;
\r
198 char_cnt_next <= char_cnt_int + 1;
\r
199 char_width_pixel_next <= 1;
\r
200 current_char_next <= decoded_char;
\r
201 current_color_next <= color;
\r
202 when PIXEL_CURSOR =>
\r
203 rgb <= cursor_color;
\r
204 char_width_pixel_next <= char_width_pixel + 1;
\r
205 when CHAR_NEW_BG =>
\r
206 rgb <= background_color;
\r
207 char_cnt_next <= char_cnt_int + 1;
\r
208 char_width_pixel_next <= 1;
\r
209 current_char_next <= decoded_char;
\r
210 current_color_next <= color;
\r
212 rgb <= background_color;
\r
213 char_width_pixel_next <= char_width_pixel + 1;
\r
214 when HFRONT_FIRST =>
\r
217 hcnt_next <= hcnt + 1;
\r
218 when HFRONT_LAST =>
\r
221 end process h_sm_output;
\r
223 sync : process(sys_clk, sys_res_n)
\r
225 if sys_res_n = '0' then
\r
226 textmode_vga_h_sm_state <= HSYNC_FIRST;
\r
229 char_width_pixel <= 0;
\r
230 current_char <= (others => '0');
\r
231 current_color <= COLOR_WHITE(3 * COLOR_SIZE - 1 downto 3 * COLOR_SIZE - RED_BITS) &
\r
232 COLOR_WHITE(2 * COLOR_SIZE - 1 downto 2 * COLOR_SIZE - GREEN_BITS) &
\r
233 COLOR_WHITE(COLOR_SIZE - 1 downto COLOR_SIZE - BLUE_BITS);
\r
234 elsif rising_edge(sys_clk) then
\r
235 textmode_vga_h_sm_state <= textmode_vga_h_sm_state_next;
\r
237 char_cnt_int <= char_cnt_next;
\r
238 char_width_pixel <= char_width_pixel_next;
\r
239 current_char <= current_char_next;
\r
240 current_color <= current_color_next;
\r
243 end architecture beh;
\r