history: maximal 70 zeichen eingabe
[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
110                 case state_int is
111                         when SIDLE =>
112                                 -- S_S_FIN: tmp..
113                                 if s_take = '1' then
114                                         state_next <= S_S_INIT;
115                                 elsif do_it = '1' then
116                                         state_next <= S_S_FIN;
117                                 elsif d_get = '1' then
118                                         state_next <= S_D_INIT;
119                                 end if;
120                         when S_S_INIT =>
121                                 if s_backspace = '1' then
122                                         state_next <= S_S_BS;
123                                 else
124                                         state_next <= S_S_WRITE;
125                                 end if;
126                         when S_S_WRITE =>
127                                 state_next <= S_S_DONE;
128                         when S_S_BS =>
129                                 state_next <= S_S_DONE;
130                         when S_S_FIN =>
131                                 if do_it = '0' then
132                                         state_next <= SIDLE;
133                                 end if;
134                         when S_S_DONE =>
135                                 if s_take = '0' then
136                                         state_next <= SIDLE;
137                                 end if;
138
139                         when S_D_INIT =>
140                                 state_next <= S_D_WRITE;
141                         when S_D_WRITE =>
142                                 if d_get = '0' then
143                                         state_next <= SIDLE;
144                                 end if;
145                 end case;
146         end process;
147
148         -- out
149         process(state_int, s_cnt_int, d_spalte, data_out, s_char, address_int,
150                 data_in_int, d_new_result_int, d_new_eingabe_int, d_new_bs_int,
151                 was_bs_int, s_take)
152                 variable addr_tmp : std_logic_vector(H_RAM_WIDTH - 1 downto 0);
153         begin
154                 s_done_next <= '0';
155                 s_cnt_next <= s_cnt_int;
156                 was_bs_next <= was_bs_int;
157                 d_new_result_next <= d_new_result_int;
158                 d_new_eingabe_next <= d_new_eingabe_int;
159                 d_new_bs_next <= '0';
160                 d_done_next <= '0';
161                 d_char_next <= (others => '0');
162                 finished_next <= '0';
163                 wr_next <= '0';
164                 address_next <= address_int;
165                 data_in_next <= data_in_int;
166
167                 case state_int is
168                         when SIDLE =>
169                                 -- TODO: tmp fix
170                                 d_new_result_next <= '0';
171                         when S_S_INIT =>
172                                 null;
173                         when S_S_WRITE =>
174                                 -- nur bei < 71 weiter machen
175                                 -- TODO: '/=' billiger als '<' ?
176                                 if unsigned(s_cnt_int) /= 71 then
177                                         wr_next <= '1';
178                                         address_next <= s_cnt_int;
179                                         data_in_next <= s_char;
180                                         s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) + 1);
181                                 else
182                                         -- was_bs hier missbrauchen, um ein d_new_eingabe zu verhindern
183                                         was_bs_next <= '1';
184                                 end if;
185                         when S_S_BS =>
186                                 -- ab 1 darf nicht mehr dekrementiert werden
187                                 if unsigned(s_cnt_int) /= 1 then
188                                         addr_tmp := std_logic_vector(unsigned(s_cnt_int) - 1);
189                                         d_new_bs_next <= '1';
190                                 else
191                                         addr_tmp := s_cnt_int;
192                                 end if;
193                                 s_cnt_next <= addr_tmp;
194                 
195                                 wr_next <= '1';
196                                 address_next <= addr_tmp;
197                                 data_in_next <= (others => '0');
198                                 was_bs_next <= '1';
199                         when S_S_FIN =>
200                                 finished_next <= '1';
201                                 s_cnt_next <= (0 => '1', others => '0');
202                                 d_new_result_next <= '1';
203                         when S_S_DONE =>
204                                 s_done_next <= '1';
205                                 if was_bs_int = '0' then
206                                         d_new_eingabe_next <= '1';
207                                 end if;
208                                 if s_take = '0' then
209                                         was_bs_next <= '0';
210                                 end if;
211
212                         when S_D_INIT =>
213                                 address_next <= d_spalte;
214                                 d_new_eingabe_next <= '0';
215                                 d_new_result_next <= '0';
216                         when S_D_WRITE =>
217                                 d_char_next <= data_out;
218                                 d_done_next <= '1';
219                 end case;
220         end process;
221
222         sp_ram_inst : entity work.sp_ram(beh)
223         generic map (
224                 ADDR_WIDTH => H_RAM_WIDTH
225         )
226         port map (
227                 sys_clk => sys_clk,
228                 address => address_int,
229                 data_out => data_out,
230                 wr => wr_int,
231                 data_in => data_in_int
232         );
233 end architecture beh;