history/display: nach d_new_result = '1' werden die naechsten 70 bytes vom display
[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_READ, S_S_FIN_POSUP);
38         signal state_int, state_next : HISTORY_STATE;
39         signal was_bs_int, was_bs_next : std_logic;
40         signal pos_int, pos_next : std_logic_vector(H_RAM_WIDTH - 1 downto 0);
41         signal s_done_int, s_done_next : std_logic;
42         signal s_cnt_int, s_cnt_next : hspalte;
43         signal d_new_eingabe_int, d_new_eingabe_next : std_logic;
44         signal d_new_result_int, d_new_result_next : std_logic;
45         signal d_new_bs_int, d_new_bs_next: std_logic;
46         signal d_done_int, d_done_next : std_logic;
47         signal d_char_int, d_char_next : hbyte;
48
49         signal finished_int, finished_next : std_logic;
50
51         -- ram
52         signal address_next, address_int : std_logic_vector(H_RAM_WIDTH - 1 downto 0);
53         signal data_out, data_in_next, data_in_int : hbyte;
54         signal wr_next, wr_int : std_logic;
55 begin
56         s_done <= s_done_int;
57         d_new_eingabe <= d_new_eingabe_int;
58         d_new_result <= d_new_result_int;
59         d_new_bs <= d_new_bs_int;
60         d_done <= d_done_int;
61         d_char <= d_char_int;
62
63         finished <= finished_int;
64
65         process(sys_clk, sys_res_n)
66         begin
67                 if sys_res_n = '0' then
68                         -- internal
69                         state_int <= SIDLE;
70                         was_bs_int <= '0';
71                         pos_int <= (others => '0');
72                         -- out
73                         s_done_int <= '0';
74                         s_cnt_int <= (0 => '1', others => '0');
75                         d_new_result_int <= '0';
76                         d_new_eingabe_int <= '0';
77                         d_new_bs_int <= '0';
78                         d_done_int <= '0';
79                         d_char_int <= (others => '0');
80
81                         finished_int <= '0';
82
83                         address_int <= (0 => '1', others => '0');
84                         data_in_int <= x"00";
85                         wr_int <= '0';
86                 elsif rising_edge(sys_clk) then
87                         -- internal
88                         state_int <= state_next;
89                         was_bs_int <= was_bs_next;
90                         pos_int <= pos_next;
91                         -- out
92                         s_done_int <= s_done_next;
93                         s_cnt_int <= s_cnt_next;
94                         d_new_result_int <= d_new_result_next;
95                         d_new_eingabe_int <= d_new_eingabe_next;
96                         d_new_bs_int <= d_new_bs_next;
97                         d_done_int <= d_done_next;
98                         d_char_int <= d_char_next;
99
100                         finished_int <= finished_next;
101
102                         address_int <= address_next;
103                         data_in_int <= data_in_next;
104                         wr_int <= wr_next;
105                 end if;
106         end process;
107
108         -- next state
109         process(state_int, d_get, do_it, s_take, s_backspace, was_bs_int)
110         begin
111                 state_next <= state_int;
112
113                 case state_int is
114                         when SIDLE =>
115                                 -- S_S_FIN: tmp..
116                                 if s_take = '1' then
117                                         state_next <= S_S_INIT;
118                                 elsif do_it = '1' then
119                                         state_next <= S_S_FIN;
120                                 elsif d_get = '1' then
121                                         state_next <= S_D_INIT;
122                                 end if;
123                         when S_S_INIT =>
124                                 if s_backspace = '1' then
125                                         state_next <= S_S_BS;
126                                 else
127                                         state_next <= S_S_WRITE;
128                                 end if;
129                         when S_S_WRITE =>
130                                 state_next <= S_S_DONE;
131                         when S_S_BS =>
132                                 state_next <= S_S_DONE;
133                         when S_S_FIN =>
134                                 if do_it = '0' then
135                                         state_next <= S_S_FIN_POSUP;
136                                 end if;
137                         when S_S_FIN_POSUP =>
138                                 state_next <= SIDLE;
139                         when S_S_DONE =>
140                                 if s_take = '0' then
141                                         state_next <= SIDLE;
142                                 end if;
143
144                         when S_D_INIT =>
145                                 state_next <= S_D_READ;
146                         when S_D_READ =>
147                                 if d_get = '0' then
148                                         state_next <= SIDLE;
149                                 end if;
150                 end case;
151         end process;
152
153         -- out
154         process(state_int, s_cnt_int, d_spalte, d_zeile, data_out, s_char, address_int,
155                 data_in_int, d_new_result_int, d_new_eingabe_int, d_new_bs_int,
156                 was_bs_int, s_take, pos_int)
157                 variable addr_tmp : std_logic_vector(H_RAM_WIDTH - 1 downto 0);
158                 variable mul_tmp : std_logic_vector((H_RAM_WIDTH*2) -1 downto 0);
159         begin
160                 s_done_next <= '0';
161                 s_cnt_next <= s_cnt_int;
162                 was_bs_next <= was_bs_int;
163                 pos_next <= pos_int;
164                 d_new_result_next <= d_new_result_int;
165                 d_new_eingabe_next <= d_new_eingabe_int;
166                 d_new_bs_next <= '0';
167                 d_done_next <= '0';
168                 d_char_next <= (others => '0');
169                 finished_next <= '0';
170                 wr_next <= '0';
171                 address_next <= address_int;
172                 data_in_next <= data_in_int;
173
174                 case state_int is
175                         when SIDLE =>
176                                 -- TODO: tmp fix
177                                 d_new_result_next <= '0';
178                         when S_S_INIT =>
179                                 null;
180                         when S_S_WRITE =>
181                                 -- nur bei < 71 weiter machen
182                                 -- TODO: '/=' billiger als '<' ?
183                                 if unsigned(s_cnt_int) /= 71 then
184                                         wr_next <= '1';
185                                         address_next <= std_logic_vector(unsigned(pos_int) + unsigned(s_cnt_int));
186                                         data_in_next <= s_char;
187                                         s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) + 1);
188                                 else
189                                         -- was_bs hier missbrauchen, um ein d_new_eingabe zu verhindern
190                                         was_bs_next <= '1';
191                                 end if;
192                         when S_S_BS =>
193                                 -- ab 1 darf nicht mehr dekrementiert werden
194                                 addr_tmp := (others => '0');
195                                 if unsigned(s_cnt_int) /= 1 then
196                                         addr_tmp(hspalte'length - 1 downto 0) := std_logic_vector(unsigned(s_cnt_int) - 1);
197                                         d_new_bs_next <= '1';
198                                 else
199                                         addr_tmp(hspalte'length - 1 downto 0) := s_cnt_int;
200                                 end if;
201                                 s_cnt_next <= addr_tmp(hspalte'length - 1 downto 0);
202                 
203                                 wr_next <= '1';
204                                 address_next <= std_logic_vector(unsigned(pos_int) + unsigned(addr_tmp));
205                                 data_in_next <= (others => '0');
206                                 was_bs_next <= '1';
207                         when S_S_FIN =>
208                                 finished_next <= '1';
209                                 s_cnt_next <= (0 => '1', others => '0');
210                                 d_new_result_next <= '1';
211                         when S_S_FIN_POSUP =>
212                                 -- TODO: overflow nach 50 berechnungen... => wieder von vorne anfangen
213                                 pos_next <= std_logic_vector(unsigned(pos_int) + to_unsigned(142,H_RAM_WIDTH));
214                         when S_S_DONE =>
215                                 s_done_next <= '1';
216                                 if was_bs_int = '0' then
217                                         d_new_eingabe_next <= '1';
218                                 end if;
219                                 if s_take = '0' then
220                                         was_bs_next <= '0';
221                                 end if;
222
223                         when S_D_INIT =>
224                                 addr_tmp := (others => '0');
225                                 addr_tmp(hzeile'length - 1 downto 0) := d_zeile;
226                                 mul_tmp := std_logic_vector(unsigned(addr_tmp) * to_unsigned(71,H_RAM_WIDTH));
227                                 addr_tmp := mul_tmp((addr_tmp'length - 1) downto 0);
228                                 addr_tmp := std_logic_vector(unsigned(addr_tmp) + unsigned(d_spalte));
229                                 address_next <= addr_tmp;
230                                 d_new_eingabe_next <= '0';
231                                 d_new_result_next <= '0';
232                         when S_D_READ =>
233                                 d_char_next <= data_out;
234                                 d_done_next <= '1';
235                 end case;
236         end process;
237
238         sp_ram_inst : entity work.sp_ram(beh)
239         generic map (
240                 ADDR_WIDTH => H_RAM_WIDTH
241         )
242         port map (
243                 sys_clk => sys_clk,
244                 address => address_int,
245                 data_out => data_out,
246                 wr => wr_int,
247                 data_in => data_in_int
248         );
249 end architecture beh;