history/display: backspace logic
[hwmod.git] / src / history.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use work.gen_pkg.all;
5
6 entity history is
7         port (
8                 sys_clk : in std_logic;
9                 sys_res_n : in std_logic;
10                 -- PC-komm
11                 -- TODO: pins
12                 -- Scanner
13                 s_char : in hbyte;
14                 s_take : in std_logic;
15                 s_done : out std_logic;
16                 s_backspace : in std_logic;
17                 -- Display
18                 d_new_eingabe : out std_logic;
19                 d_new_result : out std_logic;
20                 d_new_bs : out std_logic;
21                 d_zeile : in hzeile;
22                 d_spalte : in hspalte;
23                 d_get : in std_logic;
24                 d_done : out std_logic;
25                 d_char : out hbyte;
26                 -- Parser
27                 -- TODO: pins
28
29                 -- TODO: tmp only!
30                 do_it : in std_logic;
31                 finished : out std_logic
32         );
33 end entity history;
34
35 architecture beh of history is
36         type HISTORY_STATE is (SIDLE, S_S_INIT, S_S_WRITE, S_S_BS, S_S_DONE, S_S_FIN,
37                 S_D_INIT, S_D_WRITE);
38         signal state_int, state_next : HISTORY_STATE;
39         signal was_bs_int, was_bs_next : std_logic;
40         signal s_done_int, s_done_next : std_logic;
41         signal s_cnt_int, s_cnt_next : hspalte;
42         signal d_new_eingabe_int, d_new_eingabe_next : std_logic;
43         signal d_new_result_int, d_new_result_next : std_logic;
44         signal d_new_bs_int, d_new_bs_next: std_logic;
45         signal d_done_int, d_done_next : std_logic;
46         signal d_char_int, d_char_next : hbyte;
47
48         signal finished_int, finished_next : std_logic;
49
50         -- ram
51         signal address_next, address_int : std_logic_vector(H_RAM_WIDTH - 1 downto 0);
52         signal data_out, data_in_next, data_in_int : hbyte;
53         signal wr_next, wr_int : std_logic;
54 begin
55         s_done <= s_done_int;
56         d_new_eingabe <= d_new_eingabe_int;
57         d_new_result <= d_new_result_int;
58         d_new_bs <= d_new_bs_int;
59         d_done <= d_done_int;
60         d_char <= d_char_int;
61
62         finished <= finished_int;
63
64         process(sys_clk, sys_res_n)
65         begin
66                 if sys_res_n = '0' then
67                         -- internal
68                         state_int <= SIDLE;
69                         was_bs_int <= '0';
70                         -- out
71                         s_done_int <= '0';
72                         s_cnt_int <= (0 => '1', others => '0');
73                         d_new_result_int <= '0';
74                         d_new_eingabe_int <= '0';
75                         d_new_bs_int <= '0';
76                         d_done_int <= '0';
77                         d_char_int <= (others => '0');
78
79                         finished_int <= '0';
80
81                         address_int <= (0 => '1', others => '0');
82                         data_in_int <= x"00";
83                         wr_int <= '0';
84                 elsif rising_edge(sys_clk) then
85                         -- internal
86                         state_int <= state_next;
87                         was_bs_int <= was_bs_next;
88                         -- out
89                         s_done_int <= s_done_next;
90                         s_cnt_int <= s_cnt_next;
91                         d_new_result_int <= d_new_result_next;
92                         d_new_eingabe_int <= d_new_eingabe_next;
93                         d_new_bs_int <= d_new_bs_next;
94                         d_done_int <= d_done_next;
95                         d_char_int <= d_char_next;
96
97                         finished_int <= finished_next;
98
99                         address_int <= address_next;
100                         data_in_int <= data_in_next;
101                         wr_int <= wr_next;
102                 end if;
103         end process;
104
105         -- next state
106         process(state_int, d_get, do_it, s_take, s_backspace, was_bs_int)
107         begin
108                 state_next <= state_int;
109                 was_bs_next <= was_bs_int;
110
111                 case state_int is
112                         when SIDLE =>
113                                 -- S_S_FIN: tmp..
114                                 if s_take = '1' then
115                                         state_next <= S_S_INIT;
116                                 elsif do_it = '1' then
117                                         state_next <= S_S_FIN;
118                                 elsif d_get = '1' then
119                                         state_next <= S_D_INIT;
120                                 end if;
121                         when S_S_INIT =>
122                                 if s_backspace = '1' then
123                                         state_next <= S_S_BS;
124                                 else
125                                         state_next <= S_S_WRITE;
126                                 end if;
127                         when S_S_WRITE =>
128                                 state_next <= S_S_DONE;
129                         when S_S_BS =>
130                                 state_next <= S_S_DONE;
131                                 was_bs_next <= '1';
132                         when S_S_FIN =>
133                                 if do_it = '0' then
134                                         state_next <= SIDLE;
135                                 end if;
136                         when S_S_DONE =>
137                                 if s_take = '0' then
138                                         state_next <= SIDLE;
139                                         was_bs_next <= '0';
140                                 end if;
141
142                         when S_D_INIT =>
143                                 state_next <= S_D_WRITE;
144                         when S_D_WRITE =>
145                                 if d_get = '0' then
146                                         state_next <= SIDLE;
147                                 end if;
148                 end case;
149         end process;
150
151         -- out
152         process(state_int, s_cnt_int, d_spalte, data_out, s_char, address_int,
153                 data_in_int, d_new_result_int, d_new_eingabe_int, d_new_bs_int,
154                 was_bs_int)
155                 variable addr_tmp : std_logic_vector(H_RAM_WIDTH - 1 downto 0);
156         begin
157                 s_done_next <= '0';
158                 s_cnt_next <= s_cnt_int;
159                 d_new_result_next <= d_new_result_int;
160                 d_new_eingabe_next <= d_new_eingabe_int;
161                 d_new_bs_next <= '0';
162                 d_done_next <= '0';
163                 d_char_next <= (others => '0');
164                 finished_next <= '0';
165                 wr_next <= '0';
166                 address_next <= address_int;
167                 data_in_next <= data_in_int;
168
169                 case state_int is
170                         when SIDLE =>
171                                 -- TODO: tmp fix
172                                 d_new_result_next <= '0';
173                         when S_S_INIT =>
174                                 null;
175                         when S_S_WRITE =>
176                                 wr_next <= '1';
177                                 address_next <= s_cnt_int;
178                                 data_in_next <= s_char;
179                                 s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) + 1);
180                         when S_S_BS =>
181                                 -- ab 1 darf nicht mehr dekrementiert werden
182                                 if unsigned(s_cnt_int) /= 1 then
183                                         addr_tmp := std_logic_vector(unsigned(s_cnt_int) - 1);
184                                         d_new_bs_next <= '1';
185                                 else
186                                         addr_tmp := s_cnt_int;
187                                 end if;
188                                 s_cnt_next <= addr_tmp;
189                 
190                                 wr_next <= '1';
191                                 address_next <= addr_tmp;
192                                 data_in_next <= (others => '0');
193                         when S_S_FIN =>
194                                 finished_next <= '1';
195                                 s_cnt_next <= (0 => '1', others => '0');
196                                 d_new_result_next <= '1';
197                         when S_S_DONE =>
198                                 s_done_next <= '1';
199                                 if was_bs_int = '0' then
200                                         d_new_eingabe_next <= '1';
201                                 end if;
202
203                         when S_D_INIT =>
204                                 address_next <= d_spalte;
205                                 d_new_eingabe_next <= '0';
206                                 d_new_result_next <= '0';
207                         when S_D_WRITE =>
208                                 d_char_next <= data_out;
209                                 d_done_next <= '1';
210                 end case;
211         end process;
212
213         sp_ram_inst : entity work.sp_ram(beh)
214         generic map (
215                 ADDR_WIDTH => H_RAM_WIDTH
216         )
217         port map (
218                 sys_clk => sys_clk,
219                 address => address_int,
220                 data_out => data_out,
221                 wr => wr_int,
222                 data_in => data_in_int
223         );
224 end architecture beh;