history/display: backspace logic
[hwmod.git] / src / beh_history_tb.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use work.gen_pkg.all;
5 use work.textmode_vga_component_pkg.all;
6 use work.textmode_vga_pkg.all;
7 use work.textmode_vga_platform_dependent_pkg.all;
8
9 entity beh_history_tb is
10 end entity beh_history_tb;
11
12 architecture sim of beh_history_tb is
13         -- system
14         signal sys_clk, sys_res_n : std_logic;
15         -- history/display
16         signal d_new_eingabe, d_new_result, d_new_bs : std_logic;
17         signal d_zeile : hzeile;
18         signal d_spalte : hspalte;
19         signal d_get, d_done : std_logic;
20         signal d_char : hbyte;
21         -- history/scanner
22         signal s_char : hbyte;
23         signal s_take, s_done, s_backspace : std_logic;
24         -- ps/2
25         signal new_data : std_logic;
26         signal data : std_logic_vector(7 downto 0);
27         -- vga/display
28         signal free : std_logic;
29         signal command : std_logic_vector(COMMAND_SIZE - 1 downto 0);
30         signal command_data : std_logic_vector(3 * COLOR_SIZE + CHAR_SIZE -1 downto 0);
31
32         -- tmp: history<>scanner
33         signal do_it, finished : std_logic;
34
35         signal stop : boolean := false;
36 begin
37         -- history
38         inst : entity work.history(beh)
39         port map (
40                 sys_clk => sys_clk,
41                 sys_res_n => sys_res_n,
42                 -- scanner
43                 s_char => s_char,
44                 s_take => s_take,
45                 s_done => s_done,
46                 s_backspace => s_backspace,
47                 -- display
48                 d_new_eingabe => d_new_eingabe,
49                 d_new_result => d_new_result,
50                 d_new_bs => d_new_bs,
51                 d_zeile => d_zeile,
52                 d_spalte => d_spalte,
53                 d_get => d_get,
54                 d_done => d_done,
55                 d_char => d_char,
56                 -- TODO: tmp only!
57                 do_it => do_it,
58                 finished => finished
59         );
60
61         -- display
62         inst_disp : entity work.display(beh)
63         port map (
64                 sys_clk => sys_clk,
65                 sys_res_n => sys_res_n,
66                 -- history
67                 d_new_eingabe => d_new_eingabe,
68                 d_new_result => d_new_result,
69                 d_new_bs => d_new_bs,
70                 d_zeile => d_zeile,
71                 d_spalte => d_spalte,
72                 d_get => d_get,
73                 d_done => d_done,
74                 d_char => d_char,
75                 -- vga
76                 command => command,
77                 command_data => command_data,
78                 free => free
79         );
80
81         -- scanner
82         inst_scan : entity work.scanner(beh)
83         port map (
84                 sys_clk => sys_clk,
85                 sys_res_n => sys_res_n,
86                 -- ps/2
87                 new_data => new_data,
88                 data => data,
89                 -- history
90                 s_char => s_char,
91                 s_take => s_take,
92                 s_done => s_done,
93                 s_backspace => s_backspace,
94                 -- Parser
95                 do_it => do_it,
96                 finished => finished
97         );
98
99
100         process
101         begin
102                 sys_clk <= '0';
103                 wait for 15 ns;
104                 sys_clk <= '1';
105                 wait for 15 ns;
106                 if stop = true then
107                         wait;
108                 end if;
109         end process;
110
111         process
112         begin
113                 free <= '0';
114                 wait for 15 ns;
115                 free <= '1';
116                 wait for 30 ns;
117                 if stop = true then
118                         wait;
119                 end if;
120         end process;
121
122         process
123                 function ascii2sc (x : hbyte) return hbyte is
124                         variable y : hbyte;
125                 begin
126                         case x is
127                                 when x"30" => y := SC_KP_0;
128                                 when x"31" => y := SC_KP_1;
129                                 when x"32" => y := SC_KP_2;
130                                 when x"33" => y := SC_KP_3;
131                                 when x"34" => y := SC_KP_4;
132                                 when x"35" => y := SC_KP_5;
133                                 when x"36" => y := SC_KP_6;
134                                 when x"37" => y := SC_KP_7;
135                                 when x"38" => y := SC_KP_8;
136                                 when x"39" => y := SC_KP_9;
137                                 when x"2b" => y := SC_KP_PLUS;
138                                 when x"2d" => y := SC_KP_MINUS;
139                                 when x"2a" => y := SC_KP_MUL;
140                                 when x"2f" => y := SC_KP_DIV;
141                                 when x"20" => y := SC_SPACE;
142                                 when x"1c" => y := SC_ENTER;
143                                 when x"0e" => y := SC_BKSP;
144                                 when others => y := x"41";
145                         end case;
146                         return y;
147                 end function;
148
149                 function valid_char (x : std_logic_vector(7 downto 0)) return boolean is
150                                 variable y : boolean;
151                 begin
152                         case x is
153                                 when SC_KP_0 | SC_KP_1 | SC_KP_2 | SC_KP_3 |
154                                         SC_KP_4 | SC_KP_5 | SC_KP_6 | SC_KP_7 |
155                                         SC_KP_8 | SC_KP_9 | SC_KP_PLUS |
156                                         SC_KP_MINUS | SC_KP_MUL |
157                                         SC_KP_DIV | SC_SPACE |
158                                         SC_BKSP | SC_ENTER =>
159                                                 y := true;
160                                 when others => y := false;
161                         end case;
162                         return y;
163                 end function;
164
165                 -- textio stuff
166                 use std.textio.all;
167                 file f : text open read_mode is "../../src/history.test";
168                 variable l : line;
169
170                 variable input : hstring;
171
172                 variable run_tc, run_inner : boolean := true;
173                 variable i, j, y : natural;
174         begin
175                 -- init & reset
176                 sys_res_n <= '0';
177                 new_data <= '0';
178                 data <= (others => '0');
179                 s_done <= '0';
180                 finished <= '0';
181
182                 icwait(sys_clk, 20);
183                 sys_res_n <= '1';
184
185                 i := 1;
186                 f_loop : while not endfile(f) loop
187                         data <= (others => '0');
188
189                         f1_loop : while not endfile(f) loop
190                                 readline (f, l);
191                                 input := (others => nul);
192                                 if (l'length <= 72) then
193                                         input(1 to l'length) := l.all;
194                                         if (input(1) = '#') then
195                                                 next f1_loop;
196                                         else
197                                                 exit f1_loop;
198                                         end if;
199                                 else
200                                         report "fehler in history.test: eingabe zu lange in testfall " & natural'image(i);
201                                         next f_loop;
202                                 end if;
203                         end loop f1_loop;
204
205                         report "testcase(" & natural'image(i) & ").input: " & input;
206                         i := i + 1;
207
208                         icwait(sys_clk, 5);
209                         run_tc := true;
210                         j := 0;
211
212                         mainl : while run_tc loop
213                                 icwait(sys_clk, 10);
214                                 j := j + 1;
215
216                                 if j = 73 then
217                                         run_tc := false;
218                                         assert(false) report "wtf @ schleife";
219                                         next mainl;
220                                 end if;
221
222                                 -- jedes mal release
223                                 new_data <= '1';
224                                 data <= x"f0";
225                                 icwait(sys_clk, 1);
226                                 new_data <= '0';
227                                 icwait(sys_clk, 1);
228                                 new_data <= '1';
229
230                                 case input(j) is
231                                         when nul => data <= ascii2sc(x"1c"); -- $ (enter)
232                                         when '!' => data <= ascii2sc(x"0e"); -- ! (backspace)
233                                         when others => data <= ascii2sc(std_logic_vector(to_unsigned(character'pos(input(j)),8)));
234                                 end case;
235                                 icwait(sys_clk, 1);
236                                 new_data <= '0';
237
238                                 -- ack'en skippen, falls es ein "spezielles" zeichen ist (steht
239                                 -- in abhaengigkeit zum vorherigen zeichen)
240                                 if(not valid_char(data)) then
241                                         next mainl;
242                                 end if;
243
244                                 -- wuenschswert waere das hier:
245                                 -- > wait on s_backspace, s_take, do_it;
246                                 -- geht aber leider nicht, weil sich die signale vllt schon
247                                 -- geaendert haben
248                                 run_inner := true;
249                                 main_inner : while run_inner loop
250                                         icwait(sys_clk, 1);
251
252                                         run_inner := false;
253                                         if s_backspace = '1' or s_take = '1' then
254                                                 icwait(sys_clk, 1);
255                                                 s_done <= '1';
256                                                 wait on s_take; -- = '0'
257                                                 icwait(sys_clk, 1);
258                                                 s_done <= '0';
259                                         elsif do_it = '1' then
260                                                 -- dauert normalweiser noch laenger (parser braucht
261                                                 -- relativ lange)
262                                                 icwait(sys_clk, 7);
263                                                 finished <= '1';
264                                                 wait on do_it; -- = '0'
265                                                 icwait(sys_clk, 1);
266                                                 finished <= '0';
267
268                                                 run_tc := false;
269                                         else
270                                                 -- assert(false) report "history_tb: kann passieren. wenn tb haengt, dann hier auskommentieren";
271                                                 run_inner := true;
272                                         end if;
273                                 end loop;
274                         end loop;
275                         report "==================";
276                 end loop f_loop;
277
278                 icwait(sys_clk, 20);
279                 stop <= true;
280                 wait;
281         end process;
282 end architecture sim;