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