parser: whitespaces ignorieren
[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_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1, SCALC_14,
39         SCALC_15, SCALC_2, SWRITE_CHAR1, SWRITE_CHAR2, SDONE, SERROR1, SERROR2);
40         signal state_int, state_next : PARSER_STATE;
41         signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
42         signal punkt_int, punkt_next : csigned;
43         signal rbyte_int, rbyte_next : hbyte;
44         signal p_write_int, p_write_next : hbyte;
45         signal p_rget_int, p_rget_next : std_logic;
46         signal p_wtake_int, p_wtake_next : std_logic;
47         signal p_finished_int, p_finished_next : std_logic;
48         signal aktop_int, aktop_next : alu_ops;
49         signal opp_int, opp_next : alu_ops;
50         signal opcode_int, opcode_next : alu_ops;
51         signal op1_int, op1_next : csigned;
52         signal op2_int, op2_next : csigned;
53         signal do_calc_int, do_calc_next : std_logic;
54         signal goto_calcn1, goto_op1, goto_space3 : std_logic;
55 begin
56         p_write <= p_write_int;
57         p_rget <= p_rget_int;
58         p_wtake <= p_wtake_int;
59         p_finished <= p_finished_int;
60
61         opcode <= opcode_int;
62         op1 <= op1_int;
63         op2 <= op2_int;
64         do_calc <= do_calc_int;
65
66         process(sys_clk, sys_res_n)
67         begin
68                 if sys_res_n = '0' then
69                         state_int <= SIDLE;
70                         z_int <= (others => '0');
71                         strich_int <= (others => '0');
72                         punkt_int <= (others => '0');
73                         wtmp_int <= (others => '0');
74                         rbyte_int <= (others => '0');
75                         aktop_int <= ALU_NOP;
76                         opp_int <= ALU_NOP;
77                         -- out ports
78                         p_rw <= '0';
79                         p_spalte <= (others => '0');
80                         p_rget_int <= '0';
81                         p_write_int <= (others => '0');
82                         p_wtake_int <= '0';
83                         p_finished_int <= '0';
84                         opcode_int <= ALU_NOP;
85                         op1_int <= (others => '0');
86                         op2_int <= (others => '0');
87                         do_calc_int <= '0';
88                         finished <= '0';
89                 elsif rising_edge(sys_clk) then
90                         -- internal
91                         state_int <= state_next;
92                         z_int <= z_next;
93                         strich_int <= strich_next;
94                         punkt_int <= punkt_next;
95                         wtmp_int <= wtmp_next;
96                         rbyte_int <= rbyte_next;
97                         aktop_int <= aktop_next;
98                         opp_int <= opp_next;
99                         -- out ports
100                         p_rget_int <= p_rget_next;
101                         p_write_int <= p_write_next;
102                         p_wtake_int <= p_wtake_next;
103                         p_finished_int <= p_finished_next;
104                         opcode_int <= opcode_next;
105                         op1_int <= op1_next;
106                         op2_int <= op2_next;
107                         do_calc_int <= do_calc_next;
108                 end if;
109         end process;
110
111         -- next state
112         process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
113                 punkt_int, calc_done, wtmp_int, opp_int, goto_calcn1, goto_op1,
114                 goto_space3)
115         begin
116                 state_next <= state_int;
117
118                 case state_int is
119                         when SIDLE =>
120                                 if do_it = '1' then
121                                         state_next <= SREAD_NEWNUMBER;
122                                 end if;
123                         when SREAD_NEWNUMBER =>
124                                 state_next <= SREAD_SPACE1_2;
125                         when SREAD_SPACE1_2 =>
126                                 if p_rdone = '1' then
127                                         state_next <= SREAD_SPACE2;
128                                 end if;
129                         when SREAD_SPACE1_3 =>
130                                 if p_rdone = '1' then
131                                         state_next <= SREAD_SPACE3;
132                                 end if;
133                         when SREAD_SPACE2 | SREAD_SPACE3 =>
134                                 if p_rdone = '0' then
135                                         if goto_calcn1 = '0' then
136                                                 case state_int is
137                                                         when SREAD_SPACE2 => state_next <= SREAD_SPACE1_2;
138                                                         when SREAD_SPACE3 => state_next <= SREAD_SPACE1_3;
139                                                         when others => assert(false) report "wtf @ state2";
140                                                 end case;
141                                         end if;
142                                 end if;
143                                 if goto_calcn1 = '1' then
144                                         case state_int is
145                                                 when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE;
146                                                 when SREAD_SPACE3 => state_next <= SREAD_OP1;
147                                                 when others => assert(false) report "wtf @ state1";
148                                         end case;
149                                 end if;
150                         when SREAD_NEXTBYTE =>
151                                 if p_rdone = '1' then
152                                         state_next <= SREAD_CALCNUMBER1;
153                                 end if;
154                         when SREAD_CALCNUMBER1 =>
155                                 if goto_op1 = '1' then
156                                         state_next <= SREAD_OP1;
157                                 elsif goto_space3 = '1' then
158                                         state_next <= SREAD_SPACE3;
159                                 else
160                                         state_next <= SREAD_CALCNUMBER2;
161                                 end if;
162                         when SREAD_OP1 =>
163                                 state_next <= SREAD_OP2;
164                         when SREAD_OP2 =>
165                                 if p_rdone = '0' then
166                                         if aktop_int /= ALU_NOP then
167                                                 state_next <= SCALC_1;
168                                         end if;
169                                 end if;
170                         when SREAD_CALCNUMBER2 =>
171                                 if p_rdone = '0' then
172                                         state_next <= SREAD_NEXTBYTE;
173                                 end if;
174                         when SCALC_1 =>
175                                 if calc_done = '1' then
176                                         case opp_int is
177                                                 -- spezialfall: eine zwischenberechnung wird fuer diese
178                                                 -- kombination benoetigt
179                                                 when ALU_MUL | ALU_DIV =>
180                                                         case aktop_int is
181                                                                 when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
182                                                                 when others => state_next <= SCALC_2;
183                                                         end case;
184                                                 when others => state_next <= SCALC_2;
185                                         end case;
186                                 end if;
187                         when SCALC_14 =>
188                                 if calc_done = '0' then
189                                         state_next <= SCALC_15;
190                                 end if;
191                         when SCALC_15 =>
192                                 if calc_done = '1' then
193                                         state_next <= SCALC_2;
194                                 end if;
195                         when SCALC_2 =>
196                                 if aktop_int = ALU_DONE then
197                                         state_next <= SWRITE_CHAR1;
198                                 else
199                                         state_next <= SREAD_NEWNUMBER;
200                                 end if;
201                         when SWRITE_CHAR1 =>
202                                 if p_wdone = '1' then
203                                         if strich_int < 10 then
204                                                 state_next <= SDONE;
205                                         else
206                                                 state_next <= SWRITE_CHAR2;
207                                         end if;
208                                 end if;
209                         when SERROR1 =>
210                                 if p_wdone = '1' then
211                                         -- TODO 
212                                         if strich_int < 10 then
213                                                 state_next <= SDONE;
214                                         else
215                                                 state_next <= SWRITE_CHAR2;
216                                         end if;
217                                 end if;
218                         when SWRITE_CHAR2 | SERROR2 =>
219                                 if p_wdone = '0' then
220                                         state_next <= SWRITE_CHAR1;
221                                 end if;
222                         when SDONE =>
223                                 if p_wdone = '0' and do_it = '0' then
224                                         state_next <= SIDLE;
225                                 end if;
226                 end case;
227         end process;
228
229         -- out
230         process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
231                 strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3,
232                 do_calc_int, wtmp_int, punkt_int)
233                 function hbyte2csigned (x : hbyte) return csigned is
234                         variable y : csigned;
235                 begin
236                         case x is
237                                 when x"30" => y := to_signed(0, CBITS);
238                                 when x"31" => y := to_signed(1, CBITS);
239                                 when x"32" => y := to_signed(2, CBITS);
240                                 when x"33" => y := to_signed(3, CBITS);
241                                 when x"34" => y := to_signed(4, CBITS);
242                                 when x"35" => y := to_signed(5, CBITS);
243                                 when x"36" => y := to_signed(6, CBITS);
244                                 when x"37" => y := to_signed(7, CBITS);
245                                 when x"38" => y := to_signed(8, CBITS);
246                                 when x"39" => y := to_signed(9, CBITS);
247                                 when others => assert(false) report "hbyte2csigned: shouldn't happen";
248                         end case;
249                         return y;
250                 end function hbyte2csigned;
251
252                 function csigned2hbyte (x : csigned) return hbyte is
253                         variable y : hbyte;
254                 begin
255                         case x is
256                                 when x"00000000" => y := x"30";
257                                 when x"00000001" => y := x"31";
258                                 when x"00000002" => y := x"32";
259                                 when x"00000003" => y := x"33";
260                                 when x"00000004" => y := x"34";
261                                 when x"00000005" => y := x"35";
262                                 when x"00000006" => y := x"36";
263                                 when x"00000007" => y := x"37";
264                                 when x"00000008" => y := x"38";
265                                 when x"00000009" => y := x"39";
266                                 when others => assert(false) report "csigned2hbyte: shouldn't happen";
267                         end case;
268                         return y;
269                 end function csigned2hbyte;
270
271                 variable multmp : signed(((2*CBITS)-1) downto 0);
272                 variable tmp : csigned;
273         begin
274                 -- internal
275                 z_next <= z_int;
276                 strich_next <= strich_int;
277                 punkt_next <= punkt_int;
278                 wtmp_next <= wtmp_int;
279                 rbyte_next <= rbyte_int;
280                 aktop_next <= aktop_int;
281                 opp_next <= opp_int;
282                 -- signals
283                 p_rget_next <= '0';
284                 p_write_next <= p_write_int;
285                 p_wtake_next <= '0';
286                 p_finished_next <= '0';
287                 opcode_next <= opcode_int;
288                 op1_next <= op1_int;
289                 op2_next <= op2_int;
290                 do_calc_next <= '0';
291                 goto_calcn1 <= '0';
292                 goto_op1 <= '0';
293                 goto_space3 <= '0';
294
295                 case state_int is
296                         when SIDLE =>
297                                 strich_next <= (others => '0');
298                                 punkt_next <= (0 => '1', others => '0');
299                                 opp_next <= ALU_NOP;
300                         when SREAD_NEWNUMBER =>
301                                 z_next <= (others => '0');
302                                 rbyte_next <= (others => '0');
303                                 p_write_next <= (others => '0');
304                                 aktop_next <= ALU_NOP;
305                         when SREAD_NEXTBYTE | SREAD_SPACE1_2 | SREAD_SPACE1_3 =>
306                                 p_rget_next <= '1';
307                         when SREAD_SPACE2 | SREAD_SPACE3 =>
308                                 case p_read is
309                                         when x"20" =>
310                                                 null;
311                                         when others =>
312                                                 goto_calcn1 <= '1';
313                                                 p_rget_next <= '1';
314                                 end case;
315
316                         when SREAD_CALCNUMBER1 =>
317                                 case p_read is
318                                         -- '+', '-', '*', '/'
319                                         when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
320                                                 goto_op1 <= '1';
321                                                 p_rget_next <= '1';
322
323                                         -- ' '
324                                         when x"20" =>
325                                                 goto_space3 <= '1';
326                                                 p_rget_next <= '1';
327
328                                         when others =>
329                                                 -- TODO: check auf overflow
330                                                 multmp := (z_int * 10) + hbyte2csigned(p_read);
331                                                 z_next <= multmp((CBITS-1) downto 0);
332                                 end case;
333                         when SREAD_CALCNUMBER2 | SREAD_OP2 =>
334                                 null;
335                         when SREAD_OP1 =>
336                                 case p_read is
337                                         -- '+'
338                                         when x"2B" =>
339                                                 aktop_next <= ALU_ADD;
340                                         -- '-'
341                                         when x"2D" =>
342                                                 -- TODO: sign check beim ersten byte lesen!
343                                                 aktop_next <= ALU_SUB;
344                                         -- '*'
345                                         when x"2A" =>
346                                                 aktop_next <= ALU_MUL;
347                                         -- '/'
348                                         when x"2F" =>
349                                                 aktop_next <= ALU_DIV;
350
351                                         -- '\0'
352                                         when x"00" =>
353                                                 aktop_next <= ALU_DONE;
354
355                                         -- TODO: err!
356                                         when others => assert(false) report "TODO: ...";
357                                 end case;
358
359
360                         when SCALC_1 =>
361                                 case opp_int is
362                                         when ALU_NOP | ALU_ADD | ALU_SUB =>
363                                                 case opp_int  is
364                                                         when ALU_SUB => op1_next <= (not z_int) + 1;
365                                                         when others => op1_next <= z_int;
366                                                 end case;
367                                                 case aktop_int is
368                                                         when ALU_ADD | ALU_SUB | ALU_DONE =>
369                                                                 opcode_next <= ALU_ADD;
370                                                                 op2_next <= strich_int;
371                                                         when ALU_MUL | ALU_DIV =>
372                                                                 opcode_next <= ALU_MUL;
373                                                                 op2_next <= punkt_int;
374                                                         when others => assert(false) report "SCALC_1/1: shouldn't happen!";
375                                                 end case;
376
377                                         when ALU_MUL | ALU_DIV =>
378                                                 case aktop_int is
379                                                         when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
380                                                                 op1_next <= punkt_int;
381                                                                 opcode_next <= opp_int;
382                                                                 op2_next <= z_int;
383                                                         when others => assert(false) report "SCALC_1/2: shouldn't happen!";
384                                                 end case;
385                                         when others => assert(false) report "SCALC_1/3: shouldn't happen!";
386                                 end case;
387                                 do_calc_next <= '1';
388
389                         when SCALC_14 =>
390                                 -- ueberpruefung kann man sich sparen, da diese ohnehin in
391                                 -- nextstate gemacht wird.
392                                 op1_next <= op3;
393                                 do_calc_next <= '0';
394
395                         when SCALC_15 =>
396                                 -- ueberpruefung kann man sich sparen, da diese ohnehin in
397                                 -- nextstate gemacht wird.
398                                 opcode_next <= ALU_ADD;
399                                 op2_next <= strich_int;
400                                 punkt_next <= (0 => '1', others => '0');
401                                 do_calc_next <= '1';
402
403                         when SCALC_2 =>
404                                 case opp_int is
405                                         when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
406                                                 case aktop_int is
407                                                         when ALU_ADD | ALU_SUB | ALU_DONE =>
408                                                                 strich_next <= op3;
409                                                         when ALU_MUL | ALU_DIV =>
410                                                                 punkt_next <= op3;
411                                                         when others => assert (false) report "SCALC_2/1: shouldn't happen!";
412                                                 end case;
413                                         when others => assert (false) report "SCALC_2/2: shouldn't happen!";
414                                 end case;
415                                 -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
416                                 opp_next <= aktop_int;
417
418                         when SWRITE_CHAR1 =>
419                                 p_wtake_next <= '1';
420                                 tmp := strich_int mod 10;
421                                 p_write_next <= csigned2hbyte(tmp);
422                                 wtmp_next <= strich_int / 10;
423                         when SWRITE_CHAR2 =>
424                                 strich_next <= wtmp_int;
425
426                         when SERROR1 =>
427                                 -- TODO
428                                 null;
429                         when SERROR2 =>
430                                 -- TODO
431                                 null;
432
433                         when SDONE =>
434                                 p_finished_next <= '1';
435                 end case;
436         end process;
437 end architecture beh;