--- /dev/null
+-------------------------------------------------------------------------\r
+--\r
+-- Filename: textmode_vga_h_sm_beh.vhd\r
+-- =========\r
+--\r
+-- Short Description:\r
+-- ==================\r
+-- Behavioural implementation of the horizontal VGA timing finite state machine\r
+--\r
+-------------------------------------------------------------------------\r
+\r
+library ieee;\r
+use ieee.std_logic_1164.all;\r
+use ieee.numeric_std.all;\r
+use work.math_pkg.all;\r
+use work.textmode_vga_pkg.all;\r
+use work.font_pkg.all;\r
+\r
+architecture beh of textmode_vga_h_sm is\r
+ type TEXTMODE_VGA_H_SM_STATE_TYPE is\r
+ (\r
+ HSYNC_FIRST, HSYNC, HBACK_FIRST, HBACK, BLACK_CHAR_NEW,\r
+ BLACK_PIXEL, CHAR_NEW_FG, PIXEL_FG, CHAR_NEW_BG, PIXEL_BG,\r
+ HFRONT_FIRST, HFRONT, HFRONT_LAST, CHAR_NEW_CURSOR, PIXEL_CURSOR\r
+ );\r
+ signal textmode_vga_h_sm_state, textmode_vga_h_sm_state_next : TEXTMODE_VGA_H_SM_STATE_TYPE;\r
+ signal hcnt, hcnt_next : integer range 0 to max(HSYNC_CYCLES, HBACK_CYCLES, HFRONT_CYCLES);\r
+ signal current_char, current_char_next : std_logic_vector(0 to CHAR_WIDTH - 1);\r
+ signal current_color, current_color_next : std_logic_vector(RED_BITS + GREEN_BITS + BLUE_BITS - 1 downto 0);\r
+ signal char_width_pixel, char_width_pixel_next : integer range 0 to CHAR_WIDTH;\r
+ signal char_cnt_int, char_cnt_next : integer range 0 to COLUMN_COUNT;\r
+begin\r
+ char_cnt <= std_logic_vector(to_unsigned(char_cnt_int, log2c(COLUMN_COUNT)));\r
+ \r
+ 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
+ begin\r
+ textmode_vga_h_sm_state_next <= textmode_vga_h_sm_state;\r
+ case textmode_vga_h_sm_state is\r
+ when HSYNC_FIRST =>\r
+ textmode_vga_h_sm_state_next <= HSYNC;\r
+ when HSYNC =>\r
+ if hcnt = HSYNC_CYCLES - 1 then\r
+ textmode_vga_h_sm_state_next <= HBACK_FIRST;\r
+ end if;\r
+ when HBACK_FIRST =>\r
+ textmode_vga_h_sm_state_next <= HBACK;\r
+ when HBACK =>\r
+ if hcnt = HBACK_CYCLES - 1 then\r
+ if is_data_line = '0' then\r
+ textmode_vga_h_sm_state_next <= BLACK_CHAR_NEW;\r
+ else\r
+ if (cursor_state = CURSOR_ON or\r
+ (cursor_state = CURSOR_BLINK and blink = '0')) and\r
+ char_line_cnt = cursor_line and\r
+ std_logic_vector(to_unsigned(char_cnt_int, log2c(COLUMN_COUNT))) = cursor_column then\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_CURSOR;\r
+ elsif decoded_char(0) = '1' then\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_FG;\r
+ else\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_BG;\r
+ end if;\r
+ end if;\r
+ end if;\r
+ when BLACK_CHAR_NEW =>\r
+ textmode_vga_h_sm_state_next <= BLACK_PIXEL;\r
+ when BLACK_PIXEL =>\r
+ if char_width_pixel = CHAR_WIDTH - 1 then\r
+ if char_cnt_int = COLUMN_COUNT then\r
+ textmode_vga_h_sm_state_next <= HFRONT_FIRST;\r
+ else\r
+ textmode_vga_h_sm_state_next <= BLACK_CHAR_NEW;\r
+ end if;\r
+ end if;\r
+ when CHAR_NEW_FG =>\r
+ if decoded_char(1) = '1' then\r
+ textmode_vga_h_sm_state_next <= PIXEL_FG;\r
+ else\r
+ textmode_vga_h_sm_state_next <= PIXEL_BG;\r
+ end if;\r
+ when CHAR_NEW_CURSOR =>\r
+ textmode_vga_h_sm_state_next <= PIXEL_CURSOR;\r
+ when PIXEL_FG =>\r
+ if char_width_pixel = CHAR_WIDTH - 1 then\r
+ if char_cnt_int = COLUMN_COUNT then\r
+ textmode_vga_h_sm_state_next <= HFRONT_FIRST; \r
+ else\r
+ if (cursor_state = CURSOR_ON or\r
+ (cursor_state = CURSOR_BLINK and blink = '0')) and\r
+ char_line_cnt = cursor_line and\r
+ std_logic_vector(to_unsigned(char_cnt_int, log2c(COLUMN_COUNT))) = cursor_column then\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_CURSOR;\r
+ elsif decoded_char(0) = '1' then\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_FG; \r
+ else\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_BG; \r
+ end if;\r
+ end if;\r
+ else\r
+ if current_char(char_width_pixel + 1) = '1' then\r
+ textmode_vga_h_sm_state_next <= PIXEL_FG;\r
+ else\r
+ textmode_vga_h_sm_state_next <= PIXEL_BG;\r
+ end if;\r
+ end if;\r
+ when PIXEL_CURSOR =>\r
+ if char_width_pixel = CHAR_WIDTH - 1 then\r
+ if char_cnt_int = COLUMN_COUNT then\r
+ textmode_vga_h_sm_state_next <= HFRONT_FIRST; \r
+ else\r
+ if decoded_char(0) = '1' then\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_FG; \r
+ else\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_BG; \r
+ end if;\r
+ end if;\r
+ end if;\r
+ when CHAR_NEW_BG =>\r
+ if decoded_char(1) = '1' then\r
+ textmode_vga_h_sm_state_next <= PIXEL_FG;\r
+ else\r
+ textmode_vga_h_sm_state_next <= PIXEL_BG;\r
+ end if;\r
+ when PIXEL_BG =>\r
+ if char_width_pixel = CHAR_WIDTH - 1 then\r
+ if char_cnt_int = COLUMN_COUNT then\r
+ textmode_vga_h_sm_state_next <= HFRONT_FIRST; \r
+ else\r
+ if (cursor_state = CURSOR_ON or\r
+ (cursor_state = CURSOR_BLINK and blink = '0')) and\r
+ char_line_cnt = cursor_line and\r
+ std_logic_vector(to_unsigned(char_cnt_int, log2c(COLUMN_COUNT))) = cursor_column then\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_CURSOR;\r
+ elsif decoded_char(0) = '1' then\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_FG; \r
+ else\r
+ textmode_vga_h_sm_state_next <= CHAR_NEW_BG; \r
+ end if;\r
+ end if;\r
+ else\r
+ if current_char(char_width_pixel + 1) = '1' then\r
+ textmode_vga_h_sm_state_next <= PIXEL_FG;\r
+ else\r
+ textmode_vga_h_sm_state_next <= PIXEL_BG;\r
+ end if;\r
+ end if;\r
+ when HFRONT_FIRST =>\r
+ textmode_vga_h_sm_state_next <= HFRONT;\r
+ when HFRONT =>\r
+ if hcnt = HFRONT_CYCLES - 2 then\r
+ textmode_vga_h_sm_state_next <= HFRONT_LAST;\r
+ end if;\r
+ when HFRONT_LAST =>\r
+ textmode_vga_h_sm_state_next <= HSYNC_FIRST;\r
+ end case;\r
+ end process h_sm_next_state;\r
+ \r
+ 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
+ begin\r
+ hsync_n <= '1';\r
+ rgb <= COLOR_BLACK(3 * COLOR_SIZE - 1 downto 3 * COLOR_SIZE - RED_BITS) &\r
+ COLOR_BLACK(2 * COLOR_SIZE - 1 downto 2 * COLOR_SIZE - GREEN_BITS) &\r
+ COLOR_BLACK(COLOR_SIZE - 1 downto COLOR_SIZE - BLUE_BITS);\r
+ is_eol <= '0';\r
+ hcnt_next <= hcnt;\r
+ char_cnt_next <= char_cnt_int;\r
+ char_width_pixel_next <= char_width_pixel;\r
+ current_char_next <= current_char;\r
+ current_color_next <= current_color;\r
+\r
+ case textmode_vga_h_sm_state is\r
+ when HSYNC_FIRST =>\r
+ hsync_n <= '0';\r
+ hcnt_next <= 0;\r
+ char_cnt_next <= 0;\r
+ when HSYNC =>\r
+ hsync_n <= '0';\r
+ hcnt_next <= hcnt + 1;\r
+ when HBACK_FIRST =>\r
+ hcnt_next <= 0;\r
+ when HBACK =>\r
+ hcnt_next <= hcnt + 1;\r
+ when BLACK_CHAR_NEW =>\r
+ char_cnt_next <= char_cnt_int + 1;\r
+ char_width_pixel_next <= 1;\r
+ when BLACK_PIXEL =>\r
+ char_width_pixel_next <= char_width_pixel + 1;\r
+ when CHAR_NEW_FG =>\r
+ rgb <= color;\r
+ char_cnt_next <= char_cnt_int + 1;\r
+ char_width_pixel_next <= 1;\r
+ current_char_next <= decoded_char;\r
+ current_color_next <= color;\r
+ when PIXEL_FG =>\r
+ rgb <= current_color;\r
+ char_width_pixel_next <= char_width_pixel + 1;\r
+ when CHAR_NEW_CURSOR =>\r
+ rgb <= cursor_color;\r
+ char_cnt_next <= char_cnt_int + 1;\r
+ char_width_pixel_next <= 1;\r
+ current_char_next <= decoded_char;\r
+ current_color_next <= color;\r
+ when PIXEL_CURSOR =>\r
+ rgb <= cursor_color;\r
+ char_width_pixel_next <= char_width_pixel + 1;\r
+ when CHAR_NEW_BG =>\r
+ rgb <= background_color;\r
+ char_cnt_next <= char_cnt_int + 1;\r
+ char_width_pixel_next <= 1;\r
+ current_char_next <= decoded_char;\r
+ current_color_next <= color;\r
+ when PIXEL_BG =>\r
+ rgb <= background_color;\r
+ char_width_pixel_next <= char_width_pixel + 1;\r
+ when HFRONT_FIRST =>\r
+ hcnt_next <= 0;\r
+ when HFRONT =>\r
+ hcnt_next <= hcnt + 1;\r
+ when HFRONT_LAST =>\r
+ is_eol <= '1';\r
+ end case;\r
+ end process h_sm_output;\r
+\r
+ sync : process(sys_clk, sys_res_n)\r
+ begin\r
+ if sys_res_n = '0' then\r
+ textmode_vga_h_sm_state <= HSYNC_FIRST;\r
+ hcnt <= 0;\r
+ char_cnt_int <= 0;\r
+ char_width_pixel <= 0;\r
+ current_char <= (others => '0');\r
+ current_color <= COLOR_WHITE(3 * COLOR_SIZE - 1 downto 3 * COLOR_SIZE - RED_BITS) &\r
+ COLOR_WHITE(2 * COLOR_SIZE - 1 downto 2 * COLOR_SIZE - GREEN_BITS) &\r
+ COLOR_WHITE(COLOR_SIZE - 1 downto COLOR_SIZE - BLUE_BITS);\r
+ elsif rising_edge(sys_clk) then\r
+ textmode_vga_h_sm_state <= textmode_vga_h_sm_state_next;\r
+ hcnt <= hcnt_next;\r
+ char_cnt_int <= char_cnt_next;\r
+ char_width_pixel <= char_width_pixel_next;\r
+ current_char <= current_char_next;\r
+ current_color <= current_color_next;\r
+ end if;\r
+ end process sync;\r
+end architecture beh;\r