library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; use work.common_pkg.all; use work.core_pkg.all; use work.mem_pkg.all; use work.extension_pkg.all; use work.extension_lcd_pkg_8.all; architecture behav of extension_lcd_8 is constant CLK_Divide : integer := 16; --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; 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; signal lcd_set_delay, lcd_set_delay_nxt : std_logic_vector(17 downto 0); begin LCD_ON <= '1'; LCD_BLON <= '1'; LCD_RW <= '0'; LCD_EN <= lcd_en_int; 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_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"; lcd_done <= '0'; lcd_preStart <= '0'; lcd_start <= '0'; lcd_mStart <= '0'; lcd_count <= 0; --lcd_setup lcd_rom_addr <= (others => '0'); lcd_set_st <= SEND_DATA; lcd_set_delay <= (others => '0'); elsif rising_edge(clk) then 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; lcd_done <= lcd_done_nxt; lcd_preStart <= lcd_preStart_nxt; lcd_start <= lcd_start_nxt; lcd_mStart <= lcd_mStart_nxt; lcd_count <= lcd_count_nxt; --lcd setup lcd_rom_addr <= lcd_rom_addr_nxt; lcd_set_st <= lcd_set_st_nxt; lcd_set_delay <= lcd_set_delay_nxt; end if; end process syn; -------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------ gwriten : process (ext_reg, w2_data_val, w3_im_notused, w4_im_notused) variable tmp_data : gp_register_t; begin w2_data_val_nxt <= w2_data_val; w3_im_notused_nxt <= w3_im_notused; w4_im_notused_nxt <= w4_im_notused; new_data_nxt <= '0'; if ext_reg.sel = '1' and ext_reg.wr_en = '1' then tmp_data := (others =>'0'); for i in 0 to 3 loop if ext_reg.byte_en(i) = '1' then tmp_data(((i+1)*byte_t'length-1) downto i*byte_t'length) := ext_reg.data(((i+1)*byte_t'length-1) downto i*byte_t'length); end if; end loop; case ext_reg.addr(1 downto 0) is 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; end case; end if; end process gwriten; 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 others => null; end case; end if; data_out <= tmp_data; end process gread; 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; 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'; lcd_set_st_nxt <= WAIT_DONE; 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_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; lcd_ctrl : process(clk, lcd_en_int, lcd_count, lcd_mStart, lcd_start, lcd_done, lcd_preStart, lcd_st) begin lcd_en_nxt <= lcd_en_int; lcd_count_nxt <= lcd_count; lcd_mStart_nxt <= lcd_mStart; lcd_preStart_nxt <= lcd_start; lcd_done_nxt <= lcd_done; --start detection if lcd_preStart = '0' and lcd_start = '1' then lcd_mStart_nxt <= '1'; lcd_done_nxt <= '0'; end if; lcd_st_nxt <= lcd_st; case lcd_st is when "00" => if lcd_mStart = '1' then lcd_st_nxt <= "01"; -- wait setup else lcd_st_nxt <= "00"; end if; when "01" => lcd_en_nxt <= '1'; lcd_st_nxt <= "10"; when "10" => if(lcd_count < CLK_Divide) then lcd_count_nxt <= lcd_count+1; else lcd_st_nxt <= "11"; end if; when "11" => lcd_en_nxt <= '0'; lcd_mStart_nxt <= '0'; lcd_done_nxt <= '1'; lcd_count_nxt <= 0; lcd_st_nxt <= "00"; end case; end process lcd_ctrl; lcd_data_rom : process(lcd_rom_addr) begin case lcd_rom_addr is --init of display when "000" => lcd_rom_data <= x"038"; when "001" => lcd_rom_data <= x"00c"; when "010" => lcd_rom_data <= x"038"; when "011" => lcd_rom_data <= x"00c"; when "100" => lcd_rom_data <= x"001"; when "101" => lcd_rom_data <= x"006"; when "110" => lcd_rom_data <= x"080"; when others => lcd_rom_data <= x"0b0"; --goto 0,0 -- Line 1 --when "000111" => lcd_rom_data <= x"120"; -- Welcome to the --when "001000" => lcd_rom_data <= x"13C"; --when "001001" => lcd_rom_data <= x"133"; --when "010110" => lcd_rom_data <= x"120"; -- Change Line --when "010111" => lcd_rom_data <= x"0c0"; -- Line 2 --when "011000" => lcd_rom_data <= x"120"; -- Altera DE2-70 --when "011001" => lcd_rom_data <= x"141"; --when "011010" => lcd_rom_data <= x"085"; --back to upper line + forward --when "011011" => lcd_rom_data <= x"174"; -- when "011100" => lcd_rom_data <= x"165"; -- when "011101" => lcd_rom_data <= x"172"; -- when "011110" => lcd_rom_data <= x"161"; -- when "011111" => lcd_rom_data <= x"120"; -- when "100000" => lcd_rom_data <= x"144"; -- when "100010" => lcd_rom_data <= x"145"; -- when "100011" => lcd_rom_data <= x"132"; -- when "100100" => lcd_rom_data <= x"1b0"; -- when "100101" => lcd_rom_data <= x"131"; -- when "100110" => lcd_rom_data <= x"131"; -- when "100111" => lcd_rom_data <= x"135"; -- when "101000" => lcd_rom_data <= x"120"; -- when others => lcd_rom_data <= x"120"; end case; end process lcd_data_rom; -------------------------- LESEN UND SCHREIBEN ENDE --------------------------------------------------------------- -------------------------- INTERNE VERARBEITUNG ANFANG ------------------------------------------------------------ -------------------------- INTERNE VERARBEITUNG ENDE -------------------------------------------------------------- end behav;