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; signal w1_st_co, w1_st_co_nxt, w2_im_val, w2_im_val_nxt : gp_register_t; signal w3_im_notused, w3_im_notused_nxt, w4_im_notused, w4_im_notused_nxt : gp_register_t; 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 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_rom_data(7 downto 0); LCD_RS <= lcd_rom_data(8); syn : process (clk, reset) begin if (reset = RESET_VALUE) then w1_st_co <= (others => '0'); w2_im_val <= (others => '0'); w3_im_notused <= (others => '0'); w4_im_notused <= (others => '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 <= w1_st_co_nxt; w2_im_val <= w2_im_val_nxt; w3_im_notused <= w3_im_notused_nxt; w4_im_notused <= w4_im_notused_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, w1_st_co, w2_im_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; 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; 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" => -- status/config w1_st_co_nxt <= tmp_data; when "01" => -- timer value w2_im_val_nxt <= tmp_data; 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_im_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; data_out <= tmp_data; end process gread; lcd_setup : process(clk, lcd_set_st, lcd_start, lcd_set_delay, lcd_rom_addr, lcd_done) 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 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; 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;