assd
authorMartin Perner <martin@perner.cc>
Sun, 16 Jan 2011 13:37:44 +0000 (14:37 +0100)
committerMartin Perner <martin@perner.cc>
Sun, 16 Jan 2011 13:37:44 +0000 (14:37 +0100)
cpu/src/extension_lcd_b_8.vhd

index db591a831aac51c1a92b9deef292efc7e09f3e5e..119a1bd4a929a1c81cc9e751a5c3792558cd9775 100644 (file)
@@ -16,9 +16,14 @@ architecture behav of extension_lcd_8 is
 
 constant CLK_Divide : integer := 16;
 
-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 +33,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 +48,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 +78,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 +114,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 +132,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 +143,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 +158,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';
@@ -179,6 +195,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 < x"3fffe" 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;