shit not working
[calu.git] / cpu / src / extension_lcd_b_8.vhd
index db591a831aac51c1a92b9deef292efc7e09f3e5e..7016a1953fbd2502014000f0f37374cfa5f05fd9 100644 (file)
@@ -15,10 +15,17 @@ use work.extension_lcd_pkg_8.all;
 architecture behav of extension_lcd_8 is
 
 constant CLK_Divide : integer := 16;
+constant LCD_Delay : std_logic_vector(19 downto 0) := x"3fffe";
+--constant LCD_Delay : std_logic_vector(19 downto 0) := x"0000e"; -- for simulation
 
-signal w1_st_co, w1_st_co_nxt, w2_im_val, w2_im_val_nxt : gp_register_t;
+--w1_st_co(0) == 1 => ready for data
+--w1_st_co(1) == 1 => setup finished
+
+signal w1_st_co, w2_data_val, w2_data_val_nxt : gp_register_t;
 signal w3_im_notused, w3_im_notused_nxt, w4_im_notused, w4_im_notused_nxt : gp_register_t;
 
+signal new_data, new_data_nxt, new_data_p, new_data_p_nxt, new_data_send, new_data_send_nxt : std_logic;
+
 signal lcd_count, lcd_count_nxt : integer := 0;
 signal lcd_st, lcd_st_nxt : std_logic_vector(1 downto 0);
 signal lcd_preStart, lcd_preStart_nxt, lcd_mStart, lcd_mStart_nxt, lcd_done, lcd_done_nxt : std_logic;
@@ -28,6 +35,7 @@ signal lcd_en_int, lcd_en_nxt, lcd_start, lcd_start_nxt : std_logic;
 signal lcd_rom_addr, lcd_rom_addr_nxt : std_logic_vector(2 downto 0);
 signal lcd_rom_data : std_logic_vector(11 downto 0); -- eigentlich 8 downto 0, aber vhdl < 2008 kann 
 --keine laenge von bits bei hex angeben und binaer suckt
+signal lcd_data_int : std_logic_vector(8 downto 0);
 
 type LCD_SETUP_STATE_TYPE is (SEND_DATA, WAIT_DONE, DO_WAIT, FETCH_NEW);
 signal lcd_set_st, lcd_set_st_nxt : LCD_SETUP_STATE_TYPE;
@@ -42,17 +50,21 @@ LCD_RW <= '0';
 
 LCD_EN <= lcd_en_int;
 
-LCD_DATA <= lcd_rom_data(7 downto 0);
-LCD_RS <= lcd_rom_data(8);
+LCD_DATA <= lcd_data_int(7 downto 0);
+LCD_RS <= lcd_data_int(8);
 
 syn : process (clk, reset)
 begin
    if (reset = RESET_VALUE) then
                w1_st_co <= (others => '0');
-               w2_im_val <= (others => '0');
+               w2_data_val <= (others => '0');
                w3_im_notused <= (others => '0');
                w4_im_notused <= (others => '0');
                
+               new_data <= '0';
+               new_data_p <= '0';
+               new_data_send <= '0';
+               
                --lcd ctrl
                lcd_en_int <= '0';
                lcd_st <= "00";
@@ -68,11 +80,22 @@ begin
                lcd_set_delay <= (others => '0');
                
        elsif rising_edge(clk) then
-               w1_st_co <= w1_st_co_nxt;
-               w2_im_val <= w2_im_val_nxt;
+               w1_st_co <= (others => '0');
+               w1_st_co(0) <= lcd_done_nxt;
+               if lcd_rom_addr_nxt < "111" then
+                       w1_st_co(1) <= '0';
+               else
+                       w1_st_co(1) <= '1';
+               end if;
+               
+               w2_data_val <= w2_data_val_nxt;
                w3_im_notused <= w3_im_notused_nxt;
                w4_im_notused <= w4_im_notused_nxt;
                
+               new_data <= new_data_nxt;
+               new_data_p <= new_data_p_nxt;
+               new_data_send <= new_data_send_nxt;
+               
                --lcd ctrl
                lcd_en_int <= lcd_en_nxt;
                lcd_st <= lcd_st_nxt;
@@ -93,22 +116,14 @@ end process syn;
 
 -------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------
 
-gwriten : process (ext_reg, w1_st_co, w2_im_val, w3_im_notused, w4_im_notused)
+gwriten : process (ext_reg, w2_data_val, w3_im_notused, w4_im_notused)
 variable tmp_data : gp_register_t;
 begin
-       w1_st_co_nxt <= w1_st_co;
-       w2_im_val_nxt <= w2_im_val;
+       w2_data_val_nxt <= w2_data_val;
        w3_im_notused_nxt <= w3_im_notused;
        w4_im_notused_nxt <= w4_im_notused;
 
-       -- timer logic
-       if (w1_st_co(0) = '1') then -- timer enabled?
-               w2_im_val_nxt <= std_logic_vector(IEEE.numeric_std.unsigned(w2_im_val) + 1);
-               -- n00b overflow (logic elements sparen...)
-               if(w2_im_val(31) = '1') then 
-                       w1_st_co_nxt(16) <= '1';
-               end if;
-       end if;
+       new_data_nxt <= '0';
 
        if ext_reg.sel = '1' and ext_reg.wr_en = '1' then
                tmp_data := (others =>'0');                     
@@ -119,10 +134,10 @@ begin
                end loop;
 
                case ext_reg.addr(1 downto 0) is
-               when "00" => -- status/config
-                       w1_st_co_nxt <= tmp_data;
-               when "01" => -- timer value
-                       w2_im_val_nxt <= tmp_data;
+               when "00" => null; -- status
+               when "01" => -- data value
+                       w2_data_val_nxt <= tmp_data;
+                       new_data_nxt <= '1';
                when "10" => null;
                when "11" => null;
                when others => null;
@@ -130,16 +145,13 @@ begin
        end if;
 end process gwriten;
 
-gread : process (clk, ext_reg, w1_st_co, w2_im_val, w3_im_notused, w4_im_notused)
+gread : process (clk, ext_reg, w1_st_co, w2_data_val, w3_im_notused, w4_im_notused)
 variable tmp_data : gp_register_t;
 begin
        tmp_data := (others => '0');
        if ext_reg.sel = '1' and ext_reg.wr_en = '0' then
                case ext_reg.addr(1 downto 0) is
                when "00" => put_word_be(tmp_data, w1_st_co, ext_reg.byte_en);
-               when "01" => put_word_be(tmp_data, w2_im_val, ext_reg.byte_en);
-               when "10" => put_word_be(tmp_data, w3_im_notused, ext_reg.byte_en);
-               when "11" => put_word_be(tmp_data, w4_im_notused, ext_reg.byte_en);
                when others => null;
                end case;
        end if;
@@ -148,14 +160,20 @@ end process gread;
 
 
 
-lcd_setup : process(clk, lcd_set_st, lcd_start, lcd_set_delay, lcd_rom_addr, lcd_done)
+lcd_setup : process(clk, lcd_set_st, lcd_start, lcd_set_delay, lcd_rom_addr, new_data, lcd_rom_data, lcd_done, w2_data_val, new_data_p, new_data_send)
 begin
        lcd_set_st_nxt <= lcd_set_st;
        lcd_start_nxt <= lcd_start;
        lcd_set_delay_nxt <= lcd_set_delay;
        lcd_rom_addr_nxt <= lcd_rom_addr;
        
-       if lcd_rom_addr < "101000" then
+       
+       new_data_p_nxt <= new_data;
+       new_data_send_nxt <= '0';
+       
+       if lcd_rom_addr < "111" then
+               lcd_data_int <= lcd_rom_data(8 downto 0);
+               
                case lcd_set_st is
                        when SEND_DATA =>
                                lcd_start_nxt <= '1';
@@ -168,7 +186,7 @@ begin
                                end if;
 
                        when DO_WAIT =>
-                               if lcd_set_delay < x"3fffe" then
+                               if lcd_set_delay < LCD_Delay then
                                        lcd_set_delay_nxt <= lcd_set_delay + 1;
                                else
                                        lcd_set_delay_nxt <= (others => '0');
@@ -179,6 +197,37 @@ begin
                                lcd_rom_addr_nxt <= lcd_rom_addr + 1;
                                lcd_set_st_nxt <= SEND_DATA;
                end case;
+       else
+               lcd_data_int <= w2_data_val(8 downto 0);
+               
+               if new_data_p = '0' and new_data = '1' then
+                       new_data_send_nxt <= '1';
+               end if;
+               
+               case lcd_set_st is
+                       when SEND_DATA =>
+                               if new_data_send = '1' then
+                                       lcd_start_nxt <= '1';
+                                       lcd_set_st_nxt <= WAIT_DONE;
+                               end if;
+
+                       when WAIT_DONE =>
+                               if lcd_done = '1' then
+                                       lcd_set_st_nxt <= DO_WAIT;
+                                       lcd_start_nxt <= '0';
+                               end if;
+
+                       when DO_WAIT =>
+                               if lcd_set_delay < LCD_Delay then
+                                       lcd_set_delay_nxt <= lcd_set_delay + 1;
+                               else
+                                       lcd_set_delay_nxt <= (others => '0');
+                                       lcd_set_st_nxt <= FETCH_NEW;
+                               end if;
+
+                       when FETCH_NEW =>
+                               lcd_set_st_nxt <= SEND_DATA;
+               end case;
        end if;
                
 end process lcd_setup;
@@ -220,6 +269,7 @@ begin
                        lcd_done_nxt  <= '1';
                        lcd_count_nxt <= 0;
                        lcd_st_nxt <= "00";
+               when others => null;
        end case;
 
 
@@ -236,6 +286,7 @@ begin
                when "100" => lcd_rom_data <= x"001";
                when "101" => lcd_rom_data <= x"006";
                when "110" => lcd_rom_data <= x"080";
+               when "111" => lcd_rom_data <= x"13C";
                when others => lcd_rom_data <= x"0b0"; --goto 0,0
                --      Line 1
                --when "000111" => lcd_rom_data <= x"120";      --      Welcome to the