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