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;
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;
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";
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;
-------------------------- 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');
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;
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;
-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';
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;