2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
9 sys_clk : in std_logic;
10 sys_res_n : in std_logic;
12 p_rget : out std_logic;
13 p_rdone : in std_logic;
15 p_wtake : out std_logic;
16 p_wdone : in std_logic;
18 p_finished : out std_logic;
21 finished : out std_logic
25 architecture beh of parser is
26 type PARSER_STATE is (SIDLE, SREAD_NEWNUMBER, SREAD_SPACE1_2,
27 SREAD_SPACE1_3, SREAD_SPACE2, SREAD_SPACE3, SREAD_OP1, SREAD_OP2,
28 SREAD_SIGN1, SREAD_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1,
29 SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR0, SWRITE_CHAR1, SWRITE_CHAR2,
30 SWRITE_SIGN1, SWRITE_SIGN2, SDONE, SERROR1, SERROR2);
31 signal state_int, state_next : PARSER_STATE;
32 signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
33 signal punkt_int, punkt_next : csigned;
34 signal rbyte_int, rbyte_next : hbyte;
35 signal p_write_int, p_write_next : hbyte;
36 signal p_rget_int, p_rget_next : std_logic;
37 signal p_wtake_int, p_wtake_next : std_logic;
38 signal p_finished_int, p_finished_next : std_logic;
39 signal finished_int, finished_next : std_logic;
40 signal aktop_int, aktop_next : alu_ops;
41 signal opp_int, opp_next : alu_ops;
42 signal opcode_int, opcode_next : alu_ops;
43 signal op1_int, op1_next : csigned;
44 signal op2_int, op2_next : csigned;
45 signal do_calc_int, do_calc_next : std_logic;
46 signal goto_calcn1, goto_op1, goto_space3, goto_sign : std_logic;
47 signal z_sign_next, z_sign_int : std_logic;
48 signal firstz_next, firstz_int : boolean;
49 signal err_next, err_int : hstr_int;
50 signal errc_next, errc_int : hstr_int;
51 signal errc_tmp_next, errc_tmp_int : hstr_int;
53 signal opcode : alu_ops;
58 signal do_calc : std_logic;
59 signal calc_done : std_logic;
60 signal calc_error : std_logic;
62 instalu : entity work.alu(beh)
66 sys_res_n => sys_res_n,
68 calc_done => calc_done,
69 calc_error => calc_error,
77 p_write <= p_write_int;
79 p_wtake <= p_wtake_int;
80 p_finished <= p_finished_int;
81 finished <= finished_int;
86 do_calc <= do_calc_int;
88 process(sys_clk, sys_res_n)
90 if sys_res_n = '0' then
92 z_int <= (others => '0');
94 strich_int <= (others => '0');
95 punkt_int <= (others => '0');
96 wtmp_int <= (others => '0');
97 rbyte_int <= (others => '0');
106 p_write_int <= (others => '0');
108 p_finished_int <= '0';
110 opcode_int <= ALU_NOP;
111 op1_int <= (others => '0');
112 op2_int <= (others => '0');
114 elsif rising_edge(sys_clk) then
116 state_int <= state_next;
118 z_sign_int <= z_sign_next;
119 strich_int <= strich_next;
120 punkt_int <= punkt_next;
121 wtmp_int <= wtmp_next;
122 rbyte_int <= rbyte_next;
123 aktop_int <= aktop_next;
126 errc_int <= errc_next;
127 errc_tmp_int <= errc_tmp_next;
128 firstz_int <= firstz_next;
130 p_rget_int <= p_rget_next;
131 p_write_int <= p_write_next;
132 p_wtake_int <= p_wtake_next;
133 p_finished_int <= p_finished_next;
134 finished_int <= finished_next;
135 opcode_int <= opcode_next;
138 do_calc_int <= do_calc_next;
143 process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
144 punkt_int, calc_done, wtmp_int, opp_int, goto_calcn1, goto_op1,
145 goto_space3, goto_sign, z_sign_int, err_int, errc_int, calc_error,
148 state_next <= state_int;
153 state_next <= SREAD_NEWNUMBER;
155 when SREAD_NEWNUMBER =>
156 state_next <= SREAD_SPACE1_2;
157 when SREAD_SPACE1_2 =>
158 if p_rdone = '1' then
159 state_next <= SREAD_SPACE2;
161 when SREAD_SPACE1_3 =>
162 if p_rdone = '1' then
163 state_next <= SREAD_SPACE3;
165 when SREAD_SPACE2 | SREAD_SPACE3 =>
166 if goto_calcn1 = '1' then
168 when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE;
169 when SREAD_SPACE3 => state_next <= SREAD_OP1;
170 when others => assert(false) report "wtf @ state2";
173 if goto_sign = '1' then
175 when SREAD_SPACE2 => state_next <= SREAD_SIGN1;
176 when others => assert(false) report "wtf @ state3";
179 if p_rdone = '0' then
180 if goto_calcn1 = '0' then
182 when SREAD_SPACE2 => state_next <= SREAD_SPACE1_2;
183 when SREAD_SPACE3 => state_next <= SREAD_SPACE1_3;
184 when others => assert(false) report "wtf @ state1";
189 if p_rdone = '0' then
190 state_next <= SREAD_NEXTBYTE;
192 when SREAD_NEXTBYTE =>
193 if p_rdone = '1' then
194 state_next <= SREAD_CALCNUMBER1;
196 when SREAD_CALCNUMBER1 =>
197 if goto_op1 = '1' then
198 state_next <= SREAD_OP1;
199 elsif goto_space3 = '1' then
200 state_next <= SREAD_SPACE3;
201 elsif calc_done = '1' then
202 state_next <= SREAD_CALCNUMBER2;
205 state_next <= SREAD_OP2;
207 if p_rdone = '0' then
208 if aktop_int /= ALU_NOP then
209 state_next <= SCALC_1;
212 when SREAD_CALCNUMBER2 =>
213 if p_rdone = '0' and calc_done = '0' then
214 state_next <= SREAD_NEXTBYTE;
217 if calc_done = '1' then
219 -- spezialfall: eine zwischenberechnung wird fuer diese
220 -- kombination benoetigt
221 when ALU_MUL | ALU_DIV =>
223 when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
224 when others => state_next <= SCALC_2;
226 when others => state_next <= SCALC_2;
230 if calc_done = '0' then
231 state_next <= SCALC_15;
234 if calc_done = '1' then
235 state_next <= SCALC_2;
238 if calc_done = '0' then
239 if aktop_int = ALU_DONE then
240 state_next <= SWRITE_CHAR2;
242 state_next <= SREAD_NEWNUMBER;
246 if calc_done = '1' then
247 state_next <= SWRITE_CHAR1;
250 if p_wdone = '1' then
251 -- ueberpruefung auf -2147483648 fuer testfall 39 und 40
252 -- x"80000000": xst (xilinx) workaround
253 if strich_int < 10 and strich_int /= x"80000000" then
254 if z_sign_int = '1' then
255 state_next <= SWRITE_SIGN1;
260 state_next <= SWRITE_CHAR2;
264 if p_wdone = '1' then
265 if errc_int <= 2 then
268 state_next <= SERROR2;
272 if p_wdone = '0' then
273 state_next <= SERROR1;
276 if p_wdone = '0' and calc_done = '0' then
277 state_next <= SWRITE_CHAR0;
280 if p_wdone = '0' then
281 state_next <= SWRITE_SIGN2;
284 if p_wdone = '1' then
289 if p_wdone = '0' and do_it = '0' then
296 when SERROR1 | SERROR2 | SDONE => null;
299 state_next <= SERROR1;
305 process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
306 strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3, opM,
307 do_calc_int, wtmp_int, punkt_int, z_sign_int, err_int, errc_int,
308 errc_tmp_int, firstz_int, calc_done, calc_error)
309 function hbyte2csigned (x : hbyte) return csigned is
310 variable y : csigned;
313 when x"30" => y := x"00000000";
314 when x"31" => y := x"00000001";
315 when x"32" => y := x"00000002";
316 when x"33" => y := x"00000003";
317 when x"34" => y := x"00000004";
318 when x"35" => y := x"00000005";
319 when x"36" => y := x"00000006";
320 when x"37" => y := x"00000007";
321 when x"38" => y := x"00000008";
322 when x"39" => y := x"00000009";
323 when others => assert(false) report "hbyte2csigned: shouldn't happen";
326 end function hbyte2csigned;
328 function csigned2hbyte (x : csigned) return hbyte is
332 when x"00000000" => y := x"30";
333 when x"00000001" => y := x"31";
334 when x"00000002" => y := x"32";
335 when x"00000003" => y := x"33";
336 when x"00000004" => y := x"34";
337 when x"00000005" => y := x"35";
338 when x"00000006" => y := x"36";
339 when x"00000007" => y := x"37";
340 when x"00000008" => y := x"38";
341 when x"00000009" => y := x"39";
342 when others => assert(false) report "csigned2hbyte: shouldn't happen";
345 end function csigned2hbyte;
348 variable multmp : signed(((2*CBITS)-1) downto 0);
349 variable tmp : csigned;
351 type errstrings is array (natural range 1 to 3) of hstring;
352 constant error_str : errstrings := (
353 1 => " Fehler: Division durch Null " & nul,
354 2 => " Fehler: Syntax " & nul,
355 3 => " Fehler: Over- bzw. Underflow " & nul
360 z_sign_next <= z_sign_int;
361 strich_next <= strich_int;
362 punkt_next <= punkt_int;
363 wtmp_next <= wtmp_int;
364 rbyte_next <= rbyte_int;
365 aktop_next <= aktop_int;
368 errc_next <= errc_int;
369 errc_tmp_next <= errc_tmp_int;
370 firstz_next <= firstz_int;
373 p_write_next <= p_write_int;
375 p_finished_next <= '0';
376 finished_next <= '0';
377 opcode_next <= opcode_int;
388 strich_next <= (others => '0');
389 punkt_next <= (0 => '1', others => '0');
391 when SREAD_NEWNUMBER =>
392 z_next <= (others => '0');
395 rbyte_next <= (others => '0');
396 p_write_next <= (others => '0');
397 aktop_next <= ALU_NOP;
398 when SREAD_NEXTBYTE | SREAD_SPACE1_2 | SREAD_SPACE1_3 =>
400 when SREAD_SPACE2 | SREAD_SPACE3 =>
406 when SREAD_SPACE2 => goto_sign <= '1';
407 when SREAD_SPACE3 => goto_calcn1 <= '1'; p_rget_next <= '1';
408 when others => assert(false) report "SREAD_SPACE2/3: shouldn't happen";
415 when SREAD_CALCNUMBER1 =>
417 -- '+', '-', '*', '/'
418 when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
433 opcode_next <= ALU_MUL;
434 op2_next <= to_signed(10,CBITS);
435 firstz_next <= false;
440 when SREAD_CALCNUMBER2 =>
441 z_next <= op3 + hbyte2csigned(p_read);
446 when x"2B" => aktop_next <= ALU_ADD; -- '+'
447 when x"2D" => aktop_next <= ALU_SUB; -- '-'
448 when x"2A" => aktop_next <= ALU_MUL; -- '*'
449 when x"2F" => aktop_next <= ALU_DIV; -- '/'
450 when x"00" => aktop_next <= ALU_DONE; -- '\0'
452 when others => err_next <= 2;
457 if z_sign_int = '1' then
458 tmp := (not z_int) + 1;
466 when ALU_NOP | ALU_ADD | ALU_SUB =>
469 -- xst (xilinx) workaround
470 if x"80000000" = tmp then
471 -- vgl. testfall 37 und 38
475 op1_next <= (not tmp) + 1;
477 when others => op1_next <= tmp;
480 when ALU_ADD | ALU_SUB | ALU_DONE =>
481 opcode_next <= ALU_ADD;
482 op2_next <= strich_int;
483 when ALU_MUL | ALU_DIV =>
484 opcode_next <= ALU_MUL;
485 op2_next <= punkt_int;
486 when others => assert(false) report "SCALC_1/1: shouldn't happen!";
489 when ALU_MUL | ALU_DIV =>
491 when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
492 op1_next <= punkt_int;
493 opcode_next <= opp_int;
495 when others => assert(false) report "SCALC_1/2: shouldn't happen!";
497 when others => assert(false) report "SCALC_1/3: shouldn't happen!";
502 -- ueberpruefung kann man sich sparen, da diese ohnehin in
503 -- nextstate gemacht wird.
508 -- ueberpruefung kann man sich sparen, da diese ohnehin in
509 -- nextstate gemacht wird.
510 opcode_next <= ALU_ADD;
511 op2_next <= strich_int;
512 punkt_next <= (0 => '1', others => '0');
517 when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
519 when ALU_ADD | ALU_SUB | ALU_DONE =>
520 if aktop_int = ALU_DONE and op3 < 0 then
521 strich_next <= (not op3) + 1;
522 wtmp_next <= (not op3) + 1;
528 when ALU_MUL | ALU_DIV =>
530 when others => assert (false) report "SCALC_2/1: shouldn't happen!";
532 when ALU_DONE => null;
533 when others => assert (false) report "SCALC_2/2: shouldn't happen!";
535 -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
536 opp_next <= aktop_int;
539 -- fuer testfall 39 und 40
540 if strich_int = to_signed(-214748364,CBITS) then
541 op1_next <= to_signed(214748364,CBITS);
542 strich_next <= to_signed(214748364,CBITS);
544 op1_next <= strich_int;
546 opcode_next <= ALU_DIV;
547 op2_next <= to_signed(10,CBITS);
553 p_write_next <= csigned2hbyte(tmp);
556 strich_next <= wtmp_int;
561 if z_sign_int = '1' then
563 p_write_next <= x"2D";
565 assert(false) report "SWRITE_SIGN: shouldn't happen!";
570 p_write_next <= hbyte(to_unsigned (character'pos(error_str(err_int)(errc_int)),8));
571 errc_tmp_next <= errc_int - 1;
573 errc_next <= errc_tmp_int;
578 p_finished_next <= '1';
579 finished_next <= '1';
584 when SERROR1 | SERROR2 | SDONE => null;
586 if calc_error = '1' then
595 end architecture beh;