history: testbench mit scanner und display instanz erweitert
[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 : 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_zeile => d_zeile,
51                 d_spalte => d_spalte,
52                 d_get => d_get,
53                 d_done => d_done,
54                 d_char => d_char,
55                 -- TODO: tmp only!
56                 do_it => do_it,
57                 finished => finished
58         );
59
60         -- display
61         inst_disp : entity work.display(beh)
62         port map (
63                 sys_clk => sys_clk,
64                 sys_res_n => sys_res_n,
65                 -- history
66                 d_new_eingabe => d_new_eingabe,
67                 d_new_result => d_new_result,
68                 d_zeile => d_zeile,
69                 d_spalte => d_spalte,
70                 d_get => d_get,
71                 d_done => d_done,
72                 d_char => d_char,
73                 -- vga
74                 command => command,
75                 command_data => command_data,
76                 free => free
77         );
78
79         -- scanner
80         inst_scan : entity work.scanner(beh)
81         port map (
82                 sys_clk => sys_clk,
83                 sys_res_n => sys_res_n,
84                 -- ps/2
85                 new_data => new_data,
86                 data => data,
87                 -- history
88                 s_char => s_char,
89                 s_take => s_take,
90                 s_done => s_done,
91                 s_backspace => s_backspace,
92                 -- Parser
93                 do_it => do_it,
94                 finished => finished
95         );
96
97
98         process
99         begin
100                 sys_clk <= '0';
101                 wait for 15 ns;
102                 sys_clk <= '1';
103                 wait for 15 ns;
104                 if stop = true then
105                         wait;
106                 end if;
107         end process;
108
109         process
110         begin
111                 free <= '0';
112                 icwait(sys_clk, 2);
113                 free <= '1';
114                 icwait(sys_clk, 2);
115                 if stop = true then
116                         wait;
117                 end if;
118         end process;
119
120         process
121                 function ascii2sc (x : hbyte) return hbyte is
122                         variable y : hbyte;
123                 begin
124                         case x is
125                                 when x"30" => y := SC_KP_0;
126                                 when x"31" => y := SC_KP_1;
127                                 when x"32" => y := SC_KP_2;
128                                 when x"33" => y := SC_KP_3;
129                                 when x"34" => y := SC_KP_4;
130                                 when x"35" => y := SC_KP_5;
131                                 when x"36" => y := SC_KP_6;
132                                 when x"37" => y := SC_KP_7;
133                                 when x"38" => y := SC_KP_8;
134                                 when x"39" => y := SC_KP_9;
135                                 when x"2b" => y := SC_KP_PLUS;
136                                 when x"2d" => y := SC_KP_MINUS;
137                                 when x"2a" => y := SC_KP_MUL;
138                                 when x"2f" => y := SC_KP_DIV;
139                                 when x"20" => y := SC_SPACE;
140                                 when x"1c" => y := SC_ENTER;
141                                 when x"0e" => y := SC_BKSP;
142                                 when others => y := x"41";
143                         end case;
144                         return y;
145                 end function;
146
147                 function valid_char (x : std_logic_vector(7 downto 0); last : std_logic_vector(7 downto 0)) return boolean is
148                                 variable y : boolean;
149                 begin
150                         case x is
151                                 when SC_KP_0 | SC_KP_1 | SC_KP_2 | SC_KP_3 |
152                                         SC_KP_4 | SC_KP_5 | SC_KP_6 | SC_KP_7 |
153                                         SC_KP_8 | SC_KP_9 | SC_KP_PLUS |
154                                         SC_KP_MINUS | SC_KP_MUL |
155                                         SC_KP_DIV | SC_SPACE |
156                                         SC_BKSP | SC_ENTER =>
157                                                 y := true;
158                                 when others => y := false;
159                         end case;
160                         return y;
161                 end function;
162
163                 -- textio stuff
164                 use std.textio.all;
165                 file f : text open read_mode is "../../src/history.test";
166                 variable l : line;
167
168                 variable input : hstring;
169
170                 variable run_tc, run_inner : boolean := true;
171                 variable i, j, y : natural;
172                 variable last : std_logic_vector(7 downto 0);
173         begin
174                 -- init & reset
175                 sys_res_n <= '0';
176                 new_data <= '0';
177                 data <= (others => '0');
178                 s_done <= '0';
179                 finished <= '0';
180
181                 icwait(sys_clk, 5);
182                 sys_res_n <= '1';
183
184                 i := 1;
185                 f_loop : while not endfile(f) loop
186                         data <= (others => '0');
187
188                         f1_loop : while not endfile(f) loop
189                                 readline (f, l);
190                                 input := (others => nul);
191                                 if (l'length <= 72) then
192                                         input(1 to l'length) := l.all;
193                                         if (input(1) = '#') then
194                                                 next f1_loop;
195                                         else
196                                                 exit f1_loop;
197                                         end if;
198                                 else
199                                         report "fehler in history.test: eingabe zu lange in testfall " & natural'image(i);
200                                         next f_loop;
201                                 end if;
202                         end loop f1_loop;
203
204                         report "testcase(" & natural'image(i) & ").input: " & input;
205                         i := i + 1;
206
207                         icwait(sys_clk, 5);
208                         run_tc := true;
209                         j := 0;
210
211                         mainl : while run_tc loop
212                                 last := data;
213                                 icwait(sys_clk, 1);
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, last)) 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;