vga/ps/2: ip-core hinzugefuegt
[hwmod.git] / src / textmode_vga / textmode_vga_h_sm_beh.vhd
diff --git a/src/textmode_vga/textmode_vga_h_sm_beh.vhd b/src/textmode_vga/textmode_vga_h_sm_beh.vhd
new file mode 100644 (file)
index 0000000..5314bdd
--- /dev/null
@@ -0,0 +1,243 @@
+-------------------------------------------------------------------------\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