parser: fehlermeldungen
[hwmod.git] / src / parser.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 parser is
7         port
8         (
9                 sys_clk : in std_logic;
10                 sys_res_n : in std_logic;
11                 -- History
12                 p_rw : out std_logic;
13                 p_spalte : out hspalte;
14                 p_rget : out std_logic;
15                 p_rdone : in std_logic;
16                 p_read : in hbyte;
17                 p_wtake : out std_logic;
18                 p_wdone : in std_logic;
19                 p_write : out hbyte;
20                 p_finished : out std_logic;
21                 -- ALU
22                 opcode : out alu_ops;
23                 op1 : out csigned;
24                 op2 : out csigned;
25                 op3 : in csigned;
26                 do_calc : out std_logic;
27                 calc_done : in std_logic;
28                 calc_error : in std_logic;
29                 -- Scanner
30                 do_it : in std_logic;
31                 finished : out std_logic
32         );
33 end entity parser;
34
35 architecture beh of parser is
36         type PARSER_STATE is (SIDLE, SREAD_NEWNUMBER, SREAD_SPACE1_2,
37         SREAD_SPACE1_3, SREAD_SPACE2, SREAD_SPACE3, SREAD_OP1, SREAD_OP2,
38         SREAD_SIGN1, SREAD_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1,
39         SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR1, SWRITE_CHAR2, SWRITE_SIGN1,
40         SWRITE_SIGN2, SDONE, SERROR1, SERROR2);
41         signal state_int, state_next : PARSER_STATE;
42         signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
43         signal punkt_int, punkt_next : csigned;
44         signal rbyte_int, rbyte_next : hbyte;
45         signal p_write_int, p_write_next : hbyte;
46         signal p_rget_int, p_rget_next : std_logic;
47         signal p_wtake_int, p_wtake_next : std_logic;
48         signal p_finished_int, p_finished_next : std_logic;
49         signal aktop_int, aktop_next : alu_ops;
50         signal opp_int, opp_next : alu_ops;
51         signal opcode_int, opcode_next : alu_ops;
52         signal op1_int, op1_next : csigned;
53         signal op2_int, op2_next : csigned;
54         signal do_calc_int, do_calc_next : std_logic;
55         signal goto_calcn1, goto_op1, goto_space3, goto_sign : std_logic;
56         signal z_sign_next, z_sign_int : std_logic;
57         signal err_next, err_int : natural;
58         signal errc_next, errc_int : natural;
59         signal errc_tmp_next, errc_tmp_int : natural;
60         signal firstz_next, firstz_int : boolean;
61 begin
62         p_write <= p_write_int;
63         p_rget <= p_rget_int;
64         p_wtake <= p_wtake_int;
65         p_finished <= p_finished_int;
66
67         opcode <= opcode_int;
68         op1 <= op1_int;
69         op2 <= op2_int;
70         do_calc <= do_calc_int;
71
72         process(sys_clk, sys_res_n)
73         begin
74                 if sys_res_n = '0' then
75                         state_int <= SIDLE;
76                         z_int <= (others => '0');
77                         z_sign_int <= '0';
78                         strich_int <= (others => '0');
79                         punkt_int <= (others => '0');
80                         wtmp_int <= (others => '0');
81                         rbyte_int <= (others => '0');
82                         aktop_int <= ALU_NOP;
83                         opp_int <= ALU_NOP;
84                         err_int <= 0;
85                         errc_int <= 70;
86                         errc_tmp_int <= 0;
87                         firstz_int <= true;
88                         -- out ports
89                         p_rw <= '0';
90                         p_spalte <= (others => '0');
91                         p_rget_int <= '0';
92                         p_write_int <= (others => '0');
93                         p_wtake_int <= '0';
94                         p_finished_int <= '0';
95                         opcode_int <= ALU_NOP;
96                         op1_int <= (others => '0');
97                         op2_int <= (others => '0');
98                         do_calc_int <= '0';
99                         finished <= '0';
100                 elsif rising_edge(sys_clk) then
101                         -- internal
102                         state_int <= state_next;
103                         z_int <= z_next;
104                         z_sign_int <= z_sign_next;
105                         strich_int <= strich_next;
106                         punkt_int <= punkt_next;
107                         wtmp_int <= wtmp_next;
108                         rbyte_int <= rbyte_next;
109                         aktop_int <= aktop_next;
110                         opp_int <= opp_next;
111                         err_int <= err_next;
112                         errc_int <= errc_next;
113                         errc_tmp_int <= errc_tmp_next;
114                         firstz_int <= firstz_next;
115                         -- out ports
116                         p_rget_int <= p_rget_next;
117                         p_write_int <= p_write_next;
118                         p_wtake_int <= p_wtake_next;
119                         p_finished_int <= p_finished_next;
120                         opcode_int <= opcode_next;
121                         op1_int <= op1_next;
122                         op2_int <= op2_next;
123                         do_calc_int <= do_calc_next;
124                 end if;
125         end process;
126
127         -- next state
128         process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
129                 punkt_int, calc_done, wtmp_int, opp_int, goto_calcn1, goto_op1,
130                 goto_space3, goto_sign, z_sign_int, err_int, errc_int, calc_error,
131                 op2_int)
132         begin
133                 state_next <= state_int;
134
135                 case state_int is
136                         when SIDLE =>
137                                 if do_it = '1' then
138                                         state_next <= SREAD_NEWNUMBER;
139                                 end if;
140                         when SREAD_NEWNUMBER =>
141                                 state_next <= SREAD_SPACE1_2;
142                         when SREAD_SPACE1_2 =>
143                                 if p_rdone = '1' then
144                                         state_next <= SREAD_SPACE2;
145                                 end if;
146                         when SREAD_SPACE1_3 =>
147                                 if p_rdone = '1' then
148                                         state_next <= SREAD_SPACE3;
149                                 end if;
150                         when SREAD_SPACE2 | SREAD_SPACE3 =>
151                                 if goto_calcn1 = '1' then
152                                         case state_int is
153                                                 when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE;
154                                                 when SREAD_SPACE3 => state_next <= SREAD_OP1;
155                                                 when others => assert(false) report "wtf @ state2";
156                                         end case;
157                                 end if;
158                                 if goto_sign = '1' then
159                                         case state_int is
160                                                 when SREAD_SPACE2 => state_next <= SREAD_SIGN1;
161                                                 when others => assert(false) report "wtf @ state3";
162                                         end case;
163                                 end if;
164                                 if p_rdone = '0' then
165                                         if goto_calcn1 = '0' then
166                                                 case state_int is
167                                                         when SREAD_SPACE2 => state_next <= SREAD_SPACE1_2;
168                                                         when SREAD_SPACE3 => state_next <= SREAD_SPACE1_3;
169                                                         when others => assert(false) report "wtf @ state1";
170                                                 end case;
171                                         end if;
172                                 end if;
173                         when SREAD_SIGN1 =>
174                                 if p_rdone = '0' then
175                                         state_next <= SREAD_NEXTBYTE;
176                                 end if;
177                         when SREAD_NEXTBYTE =>
178                                 if p_rdone = '1' then
179                                         state_next <= SREAD_CALCNUMBER1;
180                                 end if;
181                         when SREAD_CALCNUMBER1 =>
182                                 if goto_op1 = '1' then
183                                         state_next <= SREAD_OP1;
184                                 elsif goto_space3 = '1' then
185                                         state_next <= SREAD_SPACE3;
186                                 else
187                                         state_next <= SREAD_CALCNUMBER2;
188                                 end if;
189                         when SREAD_OP1 =>
190                                 state_next <= SREAD_OP2;
191                         when SREAD_OP2 =>
192                                 if p_rdone = '0' then
193                                         if aktop_int /= ALU_NOP then
194                                                 state_next <= SCALC_1;
195                                         end if;
196                                 end if;
197                         when SREAD_CALCNUMBER2 =>
198                                 if p_rdone = '0' then
199                                         state_next <= SREAD_NEXTBYTE;
200                                 end if;
201                         when SCALC_1 =>
202                                 if calc_done = '1' then
203                                         case opp_int is
204                                                 -- spezialfall: eine zwischenberechnung wird fuer diese
205                                                 -- kombination benoetigt
206                                                 when ALU_MUL | ALU_DIV =>
207                                                         case aktop_int is
208                                                                 when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
209                                                                 when others => state_next <= SCALC_2;
210                                                         end case;
211                                                 when others => state_next <= SCALC_2;
212                                         end case;
213                                 end if;
214                         when SCALC_14 =>
215                                 if calc_done = '0' then
216                                         state_next <= SCALC_15;
217                                 end if;
218                         when SCALC_15 =>
219                                 if calc_done = '1' then
220                                         state_next <= SCALC_2;
221                                 end if;
222                         when SCALC_2 =>
223                                 if aktop_int = ALU_DONE then
224                                         state_next <= SWRITE_CHAR1;
225                                 else
226                                         state_next <= SREAD_NEWNUMBER;
227                                 end if;
228                         when SWRITE_CHAR1 =>
229                                 if p_wdone = '1' then
230                                         if strich_int < 10 then
231                                                 if z_sign_int = '1' then
232                                                         state_next <= SWRITE_SIGN1;
233                                                 else
234                                                         state_next <= SDONE;
235                                                 end if;
236                                         else
237                                                 state_next <= SWRITE_CHAR2;
238                                         end if;
239                                 end if;
240                         when SERROR1 =>
241                                 if p_wdone = '1' then
242                                         if errc_int <= 2 then
243                                                 state_next <= SDONE;
244                                         else
245                                                 state_next <= SERROR2;
246                                         end if;
247                                 end if;
248                         when SERROR2 =>
249                                 if p_wdone = '0' then
250                                         state_next <= SERROR1;
251                                 end if;
252                         when SWRITE_CHAR2 =>
253                                 if p_wdone = '0' then
254                                         state_next <= SWRITE_CHAR1;
255                                 end if;
256                         when SWRITE_SIGN1 =>
257                                 if p_wdone = '0' then
258                                         state_next <= SWRITE_SIGN2;
259                                 end if;
260                         when SWRITE_SIGN2 =>
261                                 if p_wdone = '1' then
262                                         state_next <= SDONE;
263                                 end if;
264
265                         when SDONE =>
266                                 if p_wdone = '0' and do_it = '0' then
267                                         state_next <= SIDLE;
268                                 end if;
269                 end case;
270
271                 -- fehlerbehandlung
272                 case state_int is
273                         when SERROR1 | SERROR2 | SDONE => null;
274                         when others =>
275                                 if err_int > 0 then
276                                         state_next <= SERROR1;
277                                 end if;
278                 end case;
279         end process;
280
281         -- out
282         process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
283                 strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3,
284                 do_calc_int, wtmp_int, punkt_int, z_sign_int, err_int, errc_int,
285                 errc_tmp_int, firstz_int, calc_done, calc_error)
286                 function hbyte2csigned (x : hbyte) return csigned is
287                         variable y : csigned;
288                 begin
289                         case x is
290                                 when x"30" => y := to_signed(0, CBITS);
291                                 when x"31" => y := to_signed(1, CBITS);
292                                 when x"32" => y := to_signed(2, CBITS);
293                                 when x"33" => y := to_signed(3, CBITS);
294                                 when x"34" => y := to_signed(4, CBITS);
295                                 when x"35" => y := to_signed(5, CBITS);
296                                 when x"36" => y := to_signed(6, CBITS);
297                                 when x"37" => y := to_signed(7, CBITS);
298                                 when x"38" => y := to_signed(8, CBITS);
299                                 when x"39" => y := to_signed(9, CBITS);
300                                 when others => assert(false) report "hbyte2csigned: shouldn't happen";
301                         end case;
302                         return y;
303                 end function hbyte2csigned;
304
305                 function csigned2hbyte (x : csigned) return hbyte is
306                         variable y : hbyte;
307                 begin
308                         case x is
309                                 when x"00000000" => y := x"30";
310                                 when x"00000001" => y := x"31";
311                                 when x"00000002" => y := x"32";
312                                 when x"00000003" => y := x"33";
313                                 when x"00000004" => y := x"34";
314                                 when x"00000005" => y := x"35";
315                                 when x"00000006" => y := x"36";
316                                 when x"00000007" => y := x"37";
317                                 when x"00000008" => y := x"38";
318                                 when x"00000009" => y := x"39";
319                                 when others => assert(false) report "csigned2hbyte: shouldn't happen";
320                         end case;
321                         return y;
322                 end function csigned2hbyte;
323
324
325                 variable multmp : signed(((2*CBITS)-1) downto 0);
326                 variable tmp : csigned;
327
328                 type errstrings is array (natural range 1 to 3) of hstring;
329                 variable error_str : errstrings := (
330                         --1 => (71 => character'val(0), 50 to 70 => "    Division durch 0", others => character'val(20)),
331                         1 => "                                                   Division durch Null ",
332                         2 => "                                                                Syntax ",
333                         3 => "                                                  Over- bzw. Underflow "
334                 );
335         begin
336                 -- internal
337                 z_next <= z_int;
338                 z_sign_next <= z_sign_int;
339                 strich_next <= strich_int;
340                 punkt_next <= punkt_int;
341                 wtmp_next <= wtmp_int;
342                 rbyte_next <= rbyte_int;
343                 aktop_next <= aktop_int;
344                 opp_next <= opp_int;
345                 err_next <= err_int;
346                 errc_next <= errc_int;
347                 errc_tmp_next <= errc_tmp_int;
348                 firstz_next <= firstz_int;
349                 -- signals
350                 p_rget_next <= '0';
351                 p_write_next <= p_write_int;
352                 p_wtake_next <= '0';
353                 p_finished_next <= '0';
354                 opcode_next <= opcode_int;
355                 op1_next <= op1_int;
356                 op2_next <= op2_int;
357                 do_calc_next <= '0';
358                 goto_calcn1 <= '0';
359                 goto_op1 <= '0';
360                 goto_space3 <= '0';
361                 goto_sign <= '0';
362
363                 case state_int is
364                         when SIDLE =>
365                                 strich_next <= (others => '0');
366                                 punkt_next <= (0 => '1', others => '0');
367                                 opp_next <= ALU_NOP;
368                         when SREAD_NEWNUMBER =>
369                                 z_next <= (others => '0');
370                                 z_sign_next <= '0';
371                                 firstz_next <= true;
372                                 rbyte_next <= (others => '0');
373                                 p_write_next <= (others => '0');
374                                 aktop_next <= ALU_NOP;
375                         when SREAD_NEXTBYTE | SREAD_SPACE1_2 | SREAD_SPACE1_3 =>
376                                 p_rget_next <= '1';
377                         when SREAD_SPACE2 | SREAD_SPACE3 =>
378                                 case p_read is
379                                         when x"20" =>
380                                                 null;
381                                         when x"2D" =>
382                                                 case state_int is
383                                                         when SREAD_SPACE2 => goto_sign <= '1';
384                                                         when SREAD_SPACE3 => goto_calcn1 <= '1'; p_rget_next <= '1';
385                                                         when others => assert(false) report "SREAD_SPACE2/3: shouldn't happen";
386                                                 end case;
387                                         when others =>
388                                                 goto_calcn1 <= '1';
389                                                 p_rget_next <= '1';
390                                 end case;
391
392                         when SREAD_CALCNUMBER1 =>
393                                 case p_read is
394                                         -- '+', '-', '*', '/'
395                                         when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
396                                                 if firstz_int then
397                                                         err_next <= 2;
398                                                 else
399                                                         goto_op1 <= '1';
400                                                         p_rget_next <= '1';
401                                                 end if;
402
403                                         -- ' '
404                                         when x"20" =>
405                                                 goto_space3 <= '1';
406                                                 p_rget_next <= '1';
407
408                                         when others =>
409                                                 -- TODO: check auf overflow
410                                                 multmp := (z_int * 10) + hbyte2csigned(p_read);
411                                                 z_next <= multmp((CBITS-1) downto 0);
412                                                 firstz_next <= false;
413                                 end case;
414                         when SREAD_SIGN1 =>
415                                 z_sign_next <= '1';
416                         when SREAD_CALCNUMBER2 | SREAD_OP2 =>
417                                 null;
418                         when SREAD_OP1 =>
419                                 case p_read is
420                                         -- '+'
421                                         when x"2B" => aktop_next <= ALU_ADD;
422                                         -- '-'
423                                         when x"2D" => aktop_next <= ALU_SUB;
424                                         -- '*'
425                                         when x"2A" => aktop_next <= ALU_MUL;
426                                         -- '/'
427                                         when x"2F" => aktop_next <= ALU_DIV;
428                                         -- '\0'
429                                         when x"00" => aktop_next <= ALU_DONE;
430
431                                         when others => err_next <= 2;
432                                 end case;
433
434
435                         when SCALC_1 =>
436                                 if z_sign_int = '1' then
437                                         tmp := (not z_int) + 1;
438                                         z_next <= tmp;
439                                         z_sign_next <= '0';
440                                 else
441                                         tmp := z_int;
442                                 end if;
443
444                                 case opp_int is
445                                         when ALU_NOP | ALU_ADD | ALU_SUB =>
446                                                 case opp_int  is
447                                                         when ALU_SUB => op1_next <= (not tmp) + 1;
448                                                         when others => op1_next <= tmp;
449                                                 end case;
450                                                 case aktop_int is
451                                                         when ALU_ADD | ALU_SUB | ALU_DONE =>
452                                                                 opcode_next <= ALU_ADD;
453                                                                 op2_next <= strich_int;
454                                                         when ALU_MUL | ALU_DIV =>
455                                                                 opcode_next <= ALU_MUL;
456                                                                 op2_next <= punkt_int;
457                                                         when others => assert(false) report "SCALC_1/1: shouldn't happen!";
458                                                 end case;
459
460                                         when ALU_MUL | ALU_DIV =>
461                                                 case aktop_int is
462                                                         when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
463                                                                 op1_next <= punkt_int;
464                                                                 opcode_next <= opp_int;
465                                                                 op2_next <= tmp;
466                                                         when others => assert(false) report "SCALC_1/2: shouldn't happen!";
467                                                 end case;
468                                         when others => assert(false) report "SCALC_1/3: shouldn't happen!";
469                                 end case;
470                                 do_calc_next <= '1';
471
472                         when SCALC_14 =>
473                                 -- ueberpruefung kann man sich sparen, da diese ohnehin in
474                                 -- nextstate gemacht wird.
475                                 op1_next <= op3;
476                                 do_calc_next <= '0';
477
478                         when SCALC_15 =>
479                                 -- ueberpruefung kann man sich sparen, da diese ohnehin in
480                                 -- nextstate gemacht wird.
481                                 opcode_next <= ALU_ADD;
482                                 op2_next <= strich_int;
483                                 punkt_next <= (0 => '1', others => '0');
484                                 do_calc_next <= '1';
485
486                         when SCALC_2 =>
487                                 case opp_int is
488                                         when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
489                                                 case aktop_int is
490                                                         when ALU_ADD | ALU_SUB | ALU_DONE =>
491                                                                 if aktop_int = ALU_DONE and op3 < 0 then
492                                                                         strich_next <= (not op3) + 1;
493                                                                         z_sign_next <= '1';
494                                                                 else
495                                                                         strich_next <= op3;
496                                                                 end if;
497                                                         when ALU_MUL | ALU_DIV =>
498                                                                 punkt_next <= op3;
499                                                         when others => assert (false) report "SCALC_2/1: shouldn't happen!";
500                                                 end case;
501                                         when others => assert (false) report "SCALC_2/2: shouldn't happen!";
502                                 end case;
503                                 -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
504                                 opp_next <= aktop_int;
505
506                         when SWRITE_CHAR1 =>
507                                 p_wtake_next <= '1';
508                                 tmp := strich_int mod 10;
509                                 p_write_next <= csigned2hbyte(tmp);
510                                 wtmp_next <= strich_int / 10;
511                         when SWRITE_CHAR2 =>
512                                 strich_next <= wtmp_int;
513
514                         when SWRITE_SIGN1 =>
515                                 null;
516                         when SWRITE_SIGN2 =>
517                                 if z_sign_int = '1' then
518                                         p_wtake_next <= '1';
519                                         p_write_next <= x"2D";
520                                 else
521                                         assert(false) report "SWRITE_SIGN: shouldn't happen!";
522                                 end if;
523
524                         when SERROR1 =>
525                                 p_wtake_next <= '1';
526                                 -- workaround
527                                 error_str(err_int)(71) := character'val(0);
528                                 p_write_next <= hbyte(to_unsigned (character'pos(error_str(err_int)(errc_int)),8));
529                                 errc_tmp_next <= errc_int - 1;
530                         when SERROR2 =>
531                                 errc_next <= errc_tmp_int;
532
533                         when SDONE =>
534                                 err_next <= 0;
535                                 errc_next <= 70;
536                                 p_finished_next <= '1';
537                 end case;
538
539                 -- fehlerbehandlung
540                 case state_int is
541                         when SERROR1 | SERROR2 | SDONE => null;
542                         when others =>
543                                 if calc_error = '1' then
544                                         if op2_int = 0 then
545                                                 err_next <= 1;
546                                         else
547                                                 err_next <= 3;
548                                         end if;
549                                 end if;
550                 end case;
551         end process;
552 end architecture beh;