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