2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
8 sys_clk : in std_logic;
9 sys_res_n : in std_logic;
11 p_rget : out std_logic;
12 p_rdone : in std_logic;
14 p_wtake : out std_logic;
15 p_wdone : in std_logic;
17 p_finished : out std_logic;
20 finished : out std_logic
24 architecture beh of parser is
25 type PARSER_STATE is (SIDLE, SREAD_NEWNUMBER, SREAD_SPACE_GET,
26 SREAD_SPACE_GET_SIGN, SREAD_SPACE_PROC, SREAD_SPACE_PROC_SIGN, SREAD_OP1, SREAD_OP2,
27 SREAD_SIGN, SREAD_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1,
28 SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR0, SWRITE_CHAR1, SWRITE_CHAR2,
29 SWRITE_SIGN1, SWRITE_SIGN2, SDONE, SERROR1, SERROR2, SBLANK1, SBLANK2);
30 signal state_int, state_next : PARSER_STATE;
31 signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
32 signal punkt_int, punkt_next : csigned;
33 signal rbyte_int, rbyte_next : hbyte;
34 signal p_write_int, p_write_next : hbyte;
35 signal p_rget_int, p_rget_next : std_logic;
36 signal p_wtake_int, p_wtake_next : std_logic;
37 signal p_finished_int, p_finished_next : std_logic;
38 signal finished_int, finished_next : std_logic;
39 signal aktop_int, aktop_next : alu_ops;
40 signal opp_int, opp_next : alu_ops;
41 signal opcode_int, opcode_next : alu_ops;
42 signal op1_int, op1_next : csigned;
43 signal op2_int, op2_next : csigned;
44 signal do_calc_int, do_calc_next : std_logic;
45 signal z_sign_next, z_sign_int : std_logic;
46 signal firstz_next, firstz_int : boolean;
47 signal err_next, err_int : hstr_int;
48 signal errc_next, errc_int : hstr_int;
49 signal errc_tmp_next, errc_tmp_int : hstr_int;
51 signal opcode : alu_ops;
56 signal do_calc : std_logic;
57 signal calc_done : std_logic;
58 signal calc_error : std_logic;
63 sys_res_n => sys_res_n,
65 calc_done => calc_done,
66 calc_error => calc_error,
74 p_write <= p_write_int;
76 p_wtake <= p_wtake_int;
77 p_finished <= p_finished_int;
78 finished <= finished_int;
83 do_calc <= do_calc_int;
85 process(sys_clk, sys_res_n)
87 if sys_res_n = '0' then
89 z_int <= (others => '0');
91 strich_int <= (others => '0');
92 punkt_int <= (others => '0');
93 wtmp_int <= (others => '0');
94 rbyte_int <= (others => '0');
98 errc_int <= HSPALTE_MAX;
103 p_write_int <= (others => '0');
105 p_finished_int <= '0';
107 opcode_int <= ALU_NOP;
108 op1_int <= (others => '0');
109 op2_int <= (others => '0');
111 elsif rising_edge(sys_clk) then
113 state_int <= state_next;
115 z_sign_int <= z_sign_next;
116 strich_int <= strich_next;
117 punkt_int <= punkt_next;
118 wtmp_int <= wtmp_next;
119 rbyte_int <= rbyte_next;
120 aktop_int <= aktop_next;
123 errc_int <= errc_next;
124 errc_tmp_int <= errc_tmp_next;
125 firstz_int <= firstz_next;
127 p_rget_int <= p_rget_next;
128 p_write_int <= p_write_next;
129 p_wtake_int <= p_wtake_next;
130 p_finished_int <= p_finished_next;
131 finished_int <= finished_next;
132 opcode_int <= opcode_next;
135 do_calc_int <= do_calc_next;
140 process(do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int, punkt_int,
141 calc_done, wtmp_int, opp_int, z_sign_int, err_int, errc_int,
142 calc_error, op2_int, state_int, p_write_int, z_int, rbyte_int,
143 p_rget_int, opcode_int, op1_int, op3, opM, do_calc_int,
144 errc_tmp_int, firstz_int)
145 function hbyte2csigned (x : hbyte) return csigned is
146 variable y : csigned;
149 when x"30" => y := x"00000000";
150 when x"31" => y := x"00000001";
151 when x"32" => y := x"00000002";
152 when x"33" => y := x"00000003";
153 when x"34" => y := x"00000004";
154 when x"35" => y := x"00000005";
155 when x"36" => y := x"00000006";
156 when x"37" => y := x"00000007";
157 when x"38" => y := x"00000008";
158 when x"39" => y := x"00000009";
159 when others => assert(false) report "hbyte2csigned: shouldn't happen";
162 end function hbyte2csigned;
164 function csigned2hbyte (x : csigned) return hbyte is
168 when x"00000000" => y := x"30";
169 when x"00000001" => y := x"31";
170 when x"00000002" => y := x"32";
171 when x"00000003" => y := x"33";
172 when x"00000004" => y := x"34";
173 when x"00000005" => y := x"35";
174 when x"00000006" => y := x"36";
175 when x"00000007" => y := x"37";
176 when x"00000008" => y := x"38";
177 when x"00000009" => y := x"39";
178 when others => assert(false) report "csigned2hbyte: shouldn't happen";
181 end function csigned2hbyte;
183 variable multmp : signed(((2*CBITS)-1) downto 0);
184 variable tmp : csigned;
186 type errstrings is array (natural range 1 to 3) of hstring;
187 constant error_str : errstrings := (
188 1 => " Fehler: Division durch Null " & nul,
189 2 => " Fehler: Syntax " & nul,
190 3 => " Fehler: Over- bzw. Underflow " & nul
193 state_next <= state_int;
196 z_sign_next <= z_sign_int;
197 strich_next <= strich_int;
198 punkt_next <= punkt_int;
199 wtmp_next <= wtmp_int;
200 rbyte_next <= rbyte_int;
201 aktop_next <= aktop_int;
204 errc_next <= errc_int;
205 errc_tmp_next <= errc_tmp_int;
206 firstz_next <= firstz_int;
209 p_write_next <= p_write_int;
211 p_finished_next <= '0';
212 finished_next <= '0';
213 opcode_next <= opcode_int;
220 strich_next <= (others => '0');
221 punkt_next <= (0 => '1', others => '0');
224 state_next <= SREAD_NEWNUMBER;
227 when SREAD_NEWNUMBER =>
228 z_next <= (others => '0');
231 rbyte_next <= (others => '0');
232 p_write_next <= (others => '0');
233 aktop_next <= ALU_NOP;
234 state_next <= SREAD_SPACE_GET;
236 when SREAD_SPACE_GET =>
238 if p_rdone = '1' then
239 state_next <= SREAD_SPACE_PROC;
241 when SREAD_SPACE_GET_SIGN =>
243 if p_rdone = '1' then
244 state_next <= SREAD_SPACE_PROC_SIGN;
246 when SREAD_SPACE_PROC | SREAD_SPACE_PROC_SIGN =>
247 if p_rdone = '0' then
249 when SREAD_SPACE_PROC => state_next <= SREAD_SPACE_GET;
250 when SREAD_SPACE_PROC_SIGN => state_next <= SREAD_SPACE_GET_SIGN;
251 when others => assert(false) report "wtf @ state1";
254 if p_read = x"2d" and state_int = SREAD_SPACE_PROC then
256 state_next <= SREAD_SIGN;
257 elsif p_read /= x"20" then
258 -- leerzeichen sollen ignoriert werden
261 when SREAD_SPACE_PROC => state_next <= SREAD_NEXTBYTE;
262 when SREAD_SPACE_PROC_SIGN => state_next <= SREAD_OP1;
263 when others => assert(false) report "SREAD_SPACE_PROC{,_SIGN}: shouldn't happen";
270 if p_rdone = '0' then
271 state_next <= SREAD_NEXTBYTE;
273 when SREAD_NEXTBYTE =>
275 if p_rdone = '1' then
276 state_next <= SREAD_CALCNUMBER1;
278 when SREAD_CALCNUMBER1 =>
280 -- '+', '-', '*', '/'
281 when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
285 state_next <= SREAD_OP1;
291 state_next <= SREAD_SPACE_PROC_SIGN;
296 opcode_next <= ALU_MUL;
297 op2_next <= to_signed(10,CBITS);
298 firstz_next <= false;
301 if calc_done = '1' then
302 state_next <= SREAD_CALCNUMBER2;
304 when SREAD_CALCNUMBER2 =>
305 z_next <= op3 + hbyte2csigned(p_read);
306 if p_rdone = '0' and calc_done = '0' then
307 state_next <= SREAD_NEXTBYTE;
312 when x"2B" => aktop_next <= ALU_ADD; -- '+'
313 when x"2D" => aktop_next <= ALU_SUB; -- '-'
314 when x"2A" => aktop_next <= ALU_MUL; -- '*'
315 when x"2F" => aktop_next <= ALU_DIV; -- '/'
316 when x"00" => aktop_next <= ALU_DONE; -- '\0'
318 when others => err_next <= 2;
320 state_next <= SREAD_OP2;
322 if p_rdone = '0' then
323 state_next <= SCALC_1;
327 if z_sign_int = '1' then
328 tmp := (not z_int) + 1;
336 when ALU_NOP | ALU_ADD | ALU_SUB =>
339 -- xst (xilinx) workaround
340 if x"80000000" = tmp then
341 -- vgl. testfall 37 und 38
345 op1_next <= (not tmp) + 1;
347 when others => op1_next <= tmp;
350 when ALU_ADD | ALU_SUB | ALU_DONE =>
351 opcode_next <= ALU_ADD;
352 op2_next <= strich_int;
353 when ALU_MUL | ALU_DIV =>
354 opcode_next <= ALU_MUL;
355 op2_next <= punkt_int;
356 when others => assert(false) report "SCALC_1/1: shouldn't happen!";
359 when ALU_MUL | ALU_DIV =>
361 when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
362 op1_next <= punkt_int;
363 opcode_next <= opp_int;
365 when others => assert(false) report "SCALC_1/2: shouldn't happen!";
367 when others => assert(false) report "SCALC_1/3: shouldn't happen!";
371 if calc_done = '1' then
373 -- spezialfall: eine zwischenberechnung wird fuer diese
374 -- kombination benoetigt
375 when ALU_MUL | ALU_DIV =>
377 when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
378 when others => state_next <= SCALC_2;
380 when others => state_next <= SCALC_2;
384 -- ueberpruefung kann man sich sparen, da diese ohnehin in
385 -- nextstate gemacht wird.
389 if calc_done = '0' then
390 state_next <= SCALC_15;
393 -- ueberpruefung kann man sich sparen, da diese ohnehin in
394 -- nextstate gemacht wird.
395 opcode_next <= ALU_ADD;
396 op2_next <= strich_int;
397 punkt_next <= (0 => '1', others => '0');
400 if calc_done = '1' then
401 state_next <= SCALC_2;
405 when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
407 when ALU_ADD | ALU_SUB | ALU_DONE =>
408 if aktop_int = ALU_DONE and op3 < 0 then
409 strich_next <= (not op3) + 1;
410 wtmp_next <= (not op3) + 1;
416 when ALU_MUL | ALU_DIV =>
418 when others => assert (false) report "SCALC_2/1: shouldn't happen!";
420 when ALU_DONE => null;
421 when others => assert (false) report "SCALC_2/2: shouldn't happen!";
423 -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
424 opp_next <= aktop_int;
426 if calc_done = '0' then
427 if aktop_int = ALU_DONE then
428 state_next <= SWRITE_CHAR2;
430 state_next <= SREAD_NEWNUMBER;
435 -- fuer testfall 39 und 40
436 if strich_int = to_signed(-214748364,CBITS) then
437 op1_next <= to_signed(214748364,CBITS);
438 strich_next <= to_signed(214748364,CBITS);
440 op1_next <= strich_int;
442 opcode_next <= ALU_DIV;
443 op2_next <= to_signed(10,CBITS);
446 if calc_done = '1' then
447 state_next <= SWRITE_CHAR1;
453 p_write_next <= csigned2hbyte(tmp);
456 if p_wdone = '1' then
457 errc_next <= errc_int - 1;
458 -- ueberpruefung auf -2147483648 fuer testfall 39 und 40
459 -- x"80000000": xst (xilinx) workaround
460 if strich_int < 10 and strich_int /= x"80000000" then
461 if z_sign_int = '1' then
462 state_next <= SWRITE_SIGN1;
464 state_next <= SBLANK1;
467 state_next <= SWRITE_CHAR2;
471 strich_next <= wtmp_int;
472 if p_wdone = '0' and calc_done = '0' then
473 state_next <= SWRITE_CHAR0;
477 if p_wdone = '0' then
478 state_next <= SWRITE_SIGN2;
481 if z_sign_int = '1' then
483 p_write_next <= x"2D";
485 assert(false) report "SWRITE_SIGN: shouldn't happen!";
488 if p_wdone = '1' then
489 errc_next <= errc_int - 1;
495 p_write_next <= x"20";
496 errc_tmp_next <= errc_int - 1;
497 if p_wdone = '1' then
498 if errc_int <= 2 then
501 state_next <= SBLANK2;
505 errc_next <= errc_tmp_int;
506 if p_wdone = '0' then
507 state_next <= SBLANK1;
512 p_write_next <= hbyte(to_unsigned (character'pos(error_str(err_int)(errc_int)),8));
513 errc_tmp_next <= errc_int - 1;
514 if p_wdone = '1' then
515 if errc_int <= 2 then
518 state_next <= SERROR2;
522 errc_next <= errc_tmp_int;
523 if p_wdone = '0' then
524 state_next <= SERROR1;
529 errc_next <= HSPALTE_MAX;
530 p_finished_next <= '1';
531 finished_next <= '1';
533 if p_wdone = '0' and do_it = '0' then
540 -- diese states sind ausgenommen vom "pokemon-exception-handling"
541 when SERROR1 | SERROR2 | SDONE => null;
543 if calc_error = '1' then
552 state_next <= SERROR1;
556 end architecture beh;