library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.gen_pkg.all; entity history is port ( sys_clk : in std_logic; sys_res_n : in std_logic; -- PC-komm pc_get : in std_logic; pc_spalte : in hspalte; pc_zeile : in hzeile; pc_char : out hbyte; pc_done : out std_logic; -- Scanner s_char : in hbyte; s_take : in std_logic; s_done : out std_logic; s_backspace : in std_logic; -- Display d_new_eingabe : out std_logic; d_new_result : out std_logic; d_new_bs : out std_logic; d_zeile : in hzeile; d_spalte : in hspalte; d_get : in std_logic; d_done : out std_logic; d_char : out hbyte; -- Parser p_rget : in std_logic; p_rdone : out std_logic; p_read : out hbyte; p_wtake : in std_logic; p_wdone : out std_logic; p_write : in hbyte; p_finished : in std_logic ); end entity history; architecture beh of history is type HISTORY_STATE is (SIDLE, S_S_INIT, S_S_WRITE, S_S_BS, S_S_DONE, S_S_FIN, S_D_INIT, S_D_READ, S_S_FIN_POSUP, S_P_READ, S_P_READ_DONE, S_P_WRITE, S_P_WRITE_DONE, S_P_DONE, S_INIT, S_S_CLEAR_NEXT0, S_S_CLEAR_NEXT1, S_PC_INIT, S_PC_READ); signal state_int, state_next : HISTORY_STATE; signal was_bs_int, was_bs_next : std_logic; signal pos_int, pos_next : std_logic_vector(H_RAM_WIDTH - 1 downto 0); signal s_done_int, s_done_next : std_logic; signal s_cnt_int, s_cnt_next : hspalte; signal d_new_eingabe_int, d_new_eingabe_next : std_logic; signal d_new_result_int, d_new_result_next : std_logic; signal d_new_bs_int, d_new_bs_next: std_logic; signal d_done_int, d_done_next : std_logic; signal d_char_int, d_char_next : hbyte; signal p_rdone_int, p_rdone_next : std_logic; signal p_wdone_int, p_wdone_next : std_logic; signal p_read_int, p_read_next : hbyte; signal p_sp_read_int, p_sp_read_next : hspalte; signal p_sp_write_int, p_sp_write_next : hspalte; signal pc_char_next ,pc_char_int : hbyte; signal pc_done_next, pc_done_int : std_logic; -- ram signal address_next, address_int : std_logic_vector(H_RAM_WIDTH - 1 downto 0); signal data_out, data_in_next, data_in_int : hbyte; signal wr_next, wr_int : std_logic; begin s_done <= s_done_int; d_new_eingabe <= d_new_eingabe_int; d_new_result <= d_new_result_int; d_new_bs <= d_new_bs_int; d_done <= d_done_int; d_char <= d_char_int; p_rdone <= p_rdone_int; p_wdone <= p_wdone_int; p_read <= p_read_int; pc_done <= pc_done_int; pc_char <= pc_char_int; process(sys_clk, sys_res_n) begin if sys_res_n = '0' then -- internal state_int <= S_INIT; was_bs_int <= '0'; pos_int <= (others => '0'); -- out s_done_int <= '0'; s_cnt_int <= (0 => '1', others => '0'); d_new_result_int <= '0'; d_new_eingabe_int <= '0'; d_new_bs_int <= '0'; d_done_int <= '0'; d_char_int <= (others => '0'); p_rdone_int <= '0'; p_wdone_int <= '0'; p_read_int <= (others => '0'); p_sp_read_int <= (others => '0'); p_sp_write_int <= std_logic_vector(to_unsigned(HSPALTE_MAX,p_sp_write_int'length)); pc_char_int <= (others => '0'); pc_done_int <= '0'; address_int <= (0 => '1', others => '0'); data_in_int <= x"00"; wr_int <= '0'; elsif rising_edge(sys_clk) then -- internal state_int <= state_next; was_bs_int <= was_bs_next; pos_int <= pos_next; -- out s_done_int <= s_done_next; s_cnt_int <= s_cnt_next; d_new_result_int <= d_new_result_next; d_new_eingabe_int <= d_new_eingabe_next; d_new_bs_int <= d_new_bs_next; d_done_int <= d_done_next; d_char_int <= d_char_next; p_rdone_int <= p_rdone_next; p_wdone_int <= p_wdone_next; p_read_int <= p_read_next; p_sp_read_int <= p_sp_read_next; p_sp_write_int <= p_sp_write_next; pc_char_int <= pc_char_next; pc_done_int <= pc_done_next; address_int <= address_next; data_in_int <= data_in_next; wr_int <= wr_next; end if; end process; -- next state process(state_int, d_get, pc_get, p_finished, s_take, s_backspace, was_bs_int, p_rget, p_wtake, pos_int, s_cnt_int) begin state_next <= state_int; case state_int is when S_INIT => -- ganzen speicher clearen: fuer ausgabe am vga nicht umbedingt -- noetig, aber spaetestens fuers dumpen per rs232 if pos_int = std_logic_vector(to_unsigned(H_RAM_SIZE,H_RAM_WIDTH)) then state_next <= SIDLE; end if; when SIDLE => -- S_S_FIN: tmp.. if s_take = '1' then state_next <= S_S_INIT; elsif p_rget = '1' then state_next <= S_P_READ; elsif p_wtake = '1' then state_next <= S_P_WRITE; elsif p_finished = '1' then state_next <= S_S_FIN; elsif d_get = '1' then state_next <= S_D_INIT; elsif pc_get = '1' then state_next <= S_PC_INIT; end if; when S_S_INIT => if s_backspace = '1' then state_next <= S_S_BS; else state_next <= S_S_WRITE; end if; when S_S_WRITE => state_next <= S_S_DONE; when S_S_BS => state_next <= S_S_DONE; when S_S_FIN => if p_finished = '0' then state_next <= S_S_FIN_POSUP; end if; when S_S_FIN_POSUP => state_next <= S_S_CLEAR_NEXT0; when S_S_CLEAR_NEXT0 => if s_cnt_int = hspalte(to_unsigned(HSPALTE_MAX,hspalte'length)) then state_next <= S_S_CLEAR_NEXT1; end if; when S_S_CLEAR_NEXT1 => if s_cnt_int = hspalte(to_unsigned(HSPALTE_MAX,hspalte'length)) then state_next <= SIDLE; end if; when S_S_DONE => if s_take = '0' then state_next <= SIDLE; end if; when S_D_INIT => state_next <= S_D_READ; when S_D_READ => if d_get = '0' then state_next <= SIDLE; end if; when S_PC_INIT => state_next <= S_PC_READ; when S_PC_READ => if pc_get = '0' then state_next <= SIDLE; end if; when S_P_READ => state_next <= S_P_READ_DONE; when S_P_READ_DONE => if p_rget = '0' then state_next <= S_P_DONE; end if; when S_P_WRITE => state_next <= S_P_WRITE_DONE; when S_P_WRITE_DONE => if p_wtake = '0' then state_next <= S_P_DONE; end if; when S_P_DONE => state_next <= SIDLE; end case; end process; -- out process(state_int, s_cnt_int, d_spalte, d_zeile, data_out, s_char, address_int, data_in_int, d_new_result_int, d_new_eingabe_int, d_new_bs_int, was_bs_int, s_take, pos_int, p_rdone_int, p_wdone_int, p_read_int, p_write, p_sp_read_int, p_sp_write_int, pc_char_int, pc_zeile, pc_spalte) variable addr_tmp : std_logic_vector(H_RAM_WIDTH - 1 downto 0); variable spalte_tmp : hspalte; variable mul_tmp : std_logic_vector((H_RAM_WIDTH*2) -1 downto 0); begin s_done_next <= '0'; s_cnt_next <= s_cnt_int; was_bs_next <= was_bs_int; pos_next <= pos_int; d_new_result_next <= d_new_result_int; d_new_eingabe_next <= d_new_eingabe_int; d_new_bs_next <= '0'; d_done_next <= '0'; d_char_next <= (others => '0'); wr_next <= '0'; address_next <= address_int; data_in_next <= data_in_int; pc_done_next <= '0'; pc_char_next <= pc_char_int; p_rdone_next <= p_rdone_int; p_wdone_next <= p_wdone_int; p_read_next <= p_read_int; p_sp_read_next <= p_sp_read_int; p_sp_write_next <= p_sp_write_int; case state_int is when S_INIT => wr_next <= '1'; address_next <= pos_int; data_in_next <= (others => '0'); if pos_int = std_logic_vector(to_unsigned(H_RAM_SIZE,H_RAM_WIDTH)) then pos_next <= (others => '0'); else pos_next <= std_logic_vector(unsigned(pos_int) + to_unsigned(1,H_RAM_WIDTH)); end if; when SIDLE => d_new_result_next <= '0'; when S_S_INIT => null; when S_S_WRITE => -- nur bei < HSPALTE_MAX weiter machen -- Hint: '/=' billiger als '<' if unsigned(s_cnt_int) /= HSPALTE_MAX then wr_next <= '1'; address_next <= std_logic_vector(unsigned(pos_int) + unsigned(s_cnt_int)); data_in_next <= s_char; s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) + 1); else -- was_bs hier missbrauchen, um ein d_new_eingabe zu verhindern was_bs_next <= '1'; end if; when S_S_BS => -- ab 1 darf nicht mehr dekrementiert werden addr_tmp := (others => '0'); if unsigned(s_cnt_int) /= 1 then addr_tmp(hspalte'length - 1 downto 0) := std_logic_vector(unsigned(s_cnt_int) - 1); d_new_bs_next <= '1'; else addr_tmp(hspalte'length - 1 downto 0) := s_cnt_int; end if; s_cnt_next <= addr_tmp(hspalte'length - 1 downto 0); wr_next <= '1'; address_next <= std_logic_vector(unsigned(pos_int) + unsigned(addr_tmp)); data_in_next <= (others => '0'); was_bs_next <= '1'; when S_S_FIN => s_cnt_next <= (0 => '1', others => '0'); d_new_result_next <= '1'; -- resetten der parser counter p_sp_read_next <= (others => '0'); p_sp_write_next <= std_logic_vector(to_unsigned(HSPALTE_MAX,p_sp_write_next'length)); when S_S_FIN_POSUP => -- overflowcheck nach 50 berechnungen => wieder von vorne anfangen if pos_int = std_logic_vector(to_unsigned(H_RAM_SIZE-142,H_RAM_WIDTH)) then pos_next <= (others => '0'); else pos_next <= std_logic_vector(unsigned(pos_int) + to_unsigned(142,H_RAM_WIDTH)); end if; when S_S_CLEAR_NEXT0 => -- die naechsten 142 bytes im speicher resetten wr_next <= '1'; address_next <= std_logic_vector(unsigned(pos_int) + unsigned(s_cnt_int)); data_in_next <= (others => '0'); if s_cnt_int = hspalte(to_unsigned(HSPALTE_MAX,hspalte'length)) then s_cnt_next <= (0 => '1', others => '0'); else s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) + 1); end if; when S_S_CLEAR_NEXT1 => -- die naechsten 142 bytes im speicher resetten wr_next <= '1'; address_next <= std_logic_vector(unsigned(pos_int) + to_unsigned(HSPALTE_MAX,H_RAM_WIDTH) + unsigned(s_cnt_int)); data_in_next <= (others => '0'); if s_cnt_int = hspalte(to_unsigned(HSPALTE_MAX,hspalte'length)) then s_cnt_next <= (0 => '1', others => '0'); else s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) + 1); end if; when S_S_DONE => s_done_next <= '1'; if was_bs_int = '0' then d_new_eingabe_next <= '1'; end if; if s_take = '0' then was_bs_next <= '0'; end if; when S_D_INIT => addr_tmp := (others => '0'); addr_tmp(hzeile'length - 1 downto 0) := d_zeile; mul_tmp := std_logic_vector(unsigned(addr_tmp) * to_unsigned(HSPALTE_MAX,H_RAM_WIDTH)); addr_tmp := mul_tmp((addr_tmp'length - 1) downto 0); addr_tmp := std_logic_vector(unsigned(addr_tmp) + unsigned(d_spalte)); address_next <= addr_tmp; d_new_eingabe_next <= '0'; d_new_result_next <= '0'; when S_D_READ => d_char_next <= data_out; d_done_next <= '1'; when S_PC_INIT => addr_tmp := (others => '0'); addr_tmp(hzeile'length - 1 downto 0) := pc_zeile; mul_tmp := std_logic_vector(unsigned(addr_tmp) * to_unsigned(HSPALTE_MAX,H_RAM_WIDTH)); addr_tmp := mul_tmp((addr_tmp'length - 1) downto 0); addr_tmp := std_logic_vector(unsigned(addr_tmp) + unsigned(pc_spalte)); address_next <= addr_tmp; when S_PC_READ => pc_done_next <= '1'; pc_char_next <= data_out; when S_P_READ => wr_next <= '0'; spalte_tmp := std_logic_vector(unsigned(p_sp_read_int) + 1); p_sp_read_next <= spalte_tmp; address_next <= std_logic_vector(unsigned(pos_int) + unsigned(spalte_tmp)); when S_P_READ_DONE => p_rdone_next <= '1'; p_read_next <= data_out; when S_P_WRITE => wr_next <= '1'; data_in_next <= p_write; spalte_tmp := std_logic_vector(unsigned(p_sp_write_int) - 1); p_sp_write_next <= spalte_tmp; address_next <= std_logic_vector(unsigned(pos_int) + to_unsigned(HSPALTE_MAX,H_RAM_WIDTH) + unsigned(spalte_tmp)); when S_P_WRITE_DONE => p_wdone_next <= '1'; when S_P_DONE => p_rdone_next <= '0'; p_wdone_next <= '0'; end case; end process; sp_ram_inst : sp_ram generic map ( ADDR_WIDTH => H_RAM_WIDTH ) port map ( sys_clk => sys_clk, address => address_int, data_out => data_out, wr => wr_int, data_in => data_in_int ); end architecture beh;