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;
13 p_spalte : out hspalte;
14 p_rget : out std_logic;
15 p_rdone : in std_logic;
17 p_wtake : out std_logic;
18 p_wdone : in std_logic;
20 p_finished : out std_logic;
27 do_calc : out std_logic;
28 calc_done : in std_logic;
29 calc_error : in std_logic;
32 finished : out std_logic
36 architecture beh of parser is
37 type PARSER_STATE is (SIDLE, SREAD_NEWNUMBER, SREAD_SPACE1_2,
38 SREAD_SPACE1_3, SREAD_SPACE2, SREAD_SPACE3, SREAD_OP1, SREAD_OP2,
39 SREAD_SIGN1, SREAD_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1,
40 SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR0, SWRITE_CHAR1, SWRITE_CHAR2,
41 SWRITE_SIGN1, SWRITE_SIGN2, SDONE, SERROR1, SERROR2);
42 signal state_int, state_next : PARSER_STATE;
43 signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
44 signal punkt_int, punkt_next : csigned;
45 signal rbyte_int, rbyte_next : hbyte;
46 signal p_write_int, p_write_next : hbyte;
47 signal p_rget_int, p_rget_next : std_logic;
48 signal p_wtake_int, p_wtake_next : std_logic;
49 signal p_finished_int, p_finished_next : std_logic;
50 signal aktop_int, aktop_next : alu_ops;
51 signal opp_int, opp_next : alu_ops;
52 signal opcode_int, opcode_next : alu_ops;
53 signal op1_int, op1_next : csigned;
54 signal op2_int, op2_next : csigned;
55 signal do_calc_int, do_calc_next : std_logic;
56 signal goto_calcn1, goto_op1, goto_space3, goto_sign : std_logic;
57 signal z_sign_next, z_sign_int : std_logic;
58 signal firstz_next, firstz_int : boolean;
59 signal err_next, err_int : hstr_int;
60 signal errc_next, errc_int : hstr_int;
61 signal errc_tmp_next, errc_tmp_int : hstr_int;
63 p_write <= p_write_int;
65 p_wtake <= p_wtake_int;
66 p_finished <= p_finished_int;
71 do_calc <= do_calc_int;
73 process(sys_clk, sys_res_n)
75 if sys_res_n = '0' then
77 z_int <= (others => '0');
79 strich_int <= (others => '0');
80 punkt_int <= (others => '0');
81 wtmp_int <= (others => '0');
82 rbyte_int <= (others => '0');
91 p_spalte <= (others => '0');
93 p_write_int <= (others => '0');
95 p_finished_int <= '0';
96 opcode_int <= ALU_NOP;
97 op1_int <= (others => '0');
98 op2_int <= (others => '0');
101 elsif rising_edge(sys_clk) then
103 state_int <= state_next;
105 z_sign_int <= z_sign_next;
106 strich_int <= strich_next;
107 punkt_int <= punkt_next;
108 wtmp_int <= wtmp_next;
109 rbyte_int <= rbyte_next;
110 aktop_int <= aktop_next;
113 errc_int <= errc_next;
114 errc_tmp_int <= errc_tmp_next;
115 firstz_int <= firstz_next;
117 p_rget_int <= p_rget_next;
118 p_write_int <= p_write_next;
119 p_wtake_int <= p_wtake_next;
120 p_finished_int <= p_finished_next;
121 opcode_int <= opcode_next;
124 do_calc_int <= do_calc_next;
129 process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
130 punkt_int, calc_done, wtmp_int, opp_int, goto_calcn1, goto_op1,
131 goto_space3, goto_sign, z_sign_int, err_int, errc_int, calc_error,
134 state_next <= state_int;
139 state_next <= SREAD_NEWNUMBER;
141 when SREAD_NEWNUMBER =>
142 state_next <= SREAD_SPACE1_2;
143 when SREAD_SPACE1_2 =>
144 if p_rdone = '1' then
145 state_next <= SREAD_SPACE2;
147 when SREAD_SPACE1_3 =>
148 if p_rdone = '1' then
149 state_next <= SREAD_SPACE3;
151 when SREAD_SPACE2 | SREAD_SPACE3 =>
152 if goto_calcn1 = '1' then
154 when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE;
155 when SREAD_SPACE3 => state_next <= SREAD_OP1;
156 when others => assert(false) report "wtf @ state2";
159 if goto_sign = '1' then
161 when SREAD_SPACE2 => state_next <= SREAD_SIGN1;
162 when others => assert(false) report "wtf @ state3";
165 if p_rdone = '0' then
166 if goto_calcn1 = '0' then
168 when SREAD_SPACE2 => state_next <= SREAD_SPACE1_2;
169 when SREAD_SPACE3 => state_next <= SREAD_SPACE1_3;
170 when others => assert(false) report "wtf @ state1";
175 if p_rdone = '0' then
176 state_next <= SREAD_NEXTBYTE;
178 when SREAD_NEXTBYTE =>
179 if p_rdone = '1' then
180 state_next <= SREAD_CALCNUMBER1;
182 when SREAD_CALCNUMBER1 =>
183 if goto_op1 = '1' then
184 state_next <= SREAD_OP1;
185 elsif goto_space3 = '1' then
186 state_next <= SREAD_SPACE3;
187 elsif calc_done = '1' then
188 state_next <= SREAD_CALCNUMBER2;
191 state_next <= SREAD_OP2;
193 if p_rdone = '0' then
194 if aktop_int /= ALU_NOP then
195 state_next <= SCALC_1;
198 when SREAD_CALCNUMBER2 =>
199 if p_rdone = '0' and calc_done = '0' then
200 state_next <= SREAD_NEXTBYTE;
203 if calc_done = '1' then
205 -- spezialfall: eine zwischenberechnung wird fuer diese
206 -- kombination benoetigt
207 when ALU_MUL | ALU_DIV =>
209 when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
210 when others => state_next <= SCALC_2;
212 when others => state_next <= SCALC_2;
216 if calc_done = '0' then
217 state_next <= SCALC_15;
220 if calc_done = '1' then
221 state_next <= SCALC_2;
224 if calc_done = '0' then
225 if aktop_int = ALU_DONE then
226 state_next <= SWRITE_CHAR2;
228 state_next <= SREAD_NEWNUMBER;
232 if calc_done = '1' then
233 state_next <= SWRITE_CHAR1;
236 if p_wdone = '1' then
237 if strich_int < 10 then
238 if z_sign_int = '1' then
239 state_next <= SWRITE_SIGN1;
244 state_next <= SWRITE_CHAR2;
248 if p_wdone = '1' then
249 if errc_int <= 2 then
252 state_next <= SERROR2;
256 if p_wdone = '0' then
257 state_next <= SERROR1;
260 if p_wdone = '0' and calc_done = '0' then
261 state_next <= SWRITE_CHAR0;
264 if p_wdone = '0' then
265 state_next <= SWRITE_SIGN2;
268 if p_wdone = '1' then
273 if p_wdone = '0' and do_it = '0' then
280 when SERROR1 | SERROR2 | SDONE => null;
283 state_next <= SERROR1;
289 process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
290 strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3, opM,
291 do_calc_int, wtmp_int, punkt_int, z_sign_int, err_int, errc_int,
292 errc_tmp_int, firstz_int, calc_done, calc_error)
293 function hbyte2csigned (x : hbyte) return csigned is
294 variable y : csigned;
297 when x"30" => y := x"00000000";
298 when x"31" => y := x"00000001";
299 when x"32" => y := x"00000002";
300 when x"33" => y := x"00000003";
301 when x"34" => y := x"00000004";
302 when x"35" => y := x"00000005";
303 when x"36" => y := x"00000006";
304 when x"37" => y := x"00000007";
305 when x"38" => y := x"00000008";
306 when x"39" => y := x"00000009";
307 when others => assert(false) report "hbyte2csigned: shouldn't happen";
310 end function hbyte2csigned;
312 function csigned2hbyte (x : csigned) return hbyte is
316 when x"00000000" => y := x"30";
317 when x"00000001" => y := x"31";
318 when x"00000002" => y := x"32";
319 when x"00000003" => y := x"33";
320 when x"00000004" => y := x"34";
321 when x"00000005" => y := x"35";
322 when x"00000006" => y := x"36";
323 when x"00000007" => y := x"37";
324 when x"00000008" => y := x"38";
325 when x"00000009" => y := x"39";
326 when others => assert(false) report "csigned2hbyte: shouldn't happen";
329 end function csigned2hbyte;
332 variable multmp : signed(((2*CBITS)-1) downto 0);
333 variable tmp : csigned;
335 type errstrings is array (natural range 1 to 3) of hstring;
336 constant error_str : errstrings := (
337 1 => " Division durch Null" & nul,
338 2 => " Syntax" & nul,
339 3 => " Over- bzw. Underflow" & nul
344 z_sign_next <= z_sign_int;
345 strich_next <= strich_int;
346 punkt_next <= punkt_int;
347 wtmp_next <= wtmp_int;
348 rbyte_next <= rbyte_int;
349 aktop_next <= aktop_int;
352 errc_next <= errc_int;
353 errc_tmp_next <= errc_tmp_int;
354 firstz_next <= firstz_int;
357 p_write_next <= p_write_int;
359 p_finished_next <= '0';
360 opcode_next <= opcode_int;
371 strich_next <= (others => '0');
372 punkt_next <= (0 => '1', others => '0');
374 when SREAD_NEWNUMBER =>
375 z_next <= (others => '0');
378 rbyte_next <= (others => '0');
379 p_write_next <= (others => '0');
380 aktop_next <= ALU_NOP;
381 when SREAD_NEXTBYTE | SREAD_SPACE1_2 | SREAD_SPACE1_3 =>
383 when SREAD_SPACE2 | SREAD_SPACE3 =>
389 when SREAD_SPACE2 => goto_sign <= '1';
390 when SREAD_SPACE3 => goto_calcn1 <= '1'; p_rget_next <= '1';
391 when others => assert(false) report "SREAD_SPACE2/3: shouldn't happen";
398 when SREAD_CALCNUMBER1 =>
400 -- '+', '-', '*', '/'
401 when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
416 opcode_next <= ALU_MUL;
417 op2_next <= to_signed(10,CBITS);
418 firstz_next <= false;
423 when SREAD_CALCNUMBER2 =>
424 z_next <= op3 + hbyte2csigned(p_read);
429 when x"2B" => aktop_next <= ALU_ADD; -- '+'
430 when x"2D" => aktop_next <= ALU_SUB; -- '-'
431 when x"2A" => aktop_next <= ALU_MUL; -- '*'
432 when x"2F" => aktop_next <= ALU_DIV; -- '/'
433 when x"00" => aktop_next <= ALU_DONE; -- '\0'
435 when others => err_next <= 2;
440 if z_sign_int = '1' then
441 tmp := (not z_int) + 1;
449 when ALU_NOP | ALU_ADD | ALU_SUB =>
451 when ALU_SUB => op1_next <= (not tmp) + 1;
452 when others => op1_next <= tmp;
455 when ALU_ADD | ALU_SUB | ALU_DONE =>
456 opcode_next <= ALU_ADD;
457 op2_next <= strich_int;
458 when ALU_MUL | ALU_DIV =>
459 opcode_next <= ALU_MUL;
460 op2_next <= punkt_int;
461 when others => assert(false) report "SCALC_1/1: shouldn't happen!";
464 when ALU_MUL | ALU_DIV =>
466 when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
467 op1_next <= punkt_int;
468 opcode_next <= opp_int;
470 when others => assert(false) report "SCALC_1/2: shouldn't happen!";
472 when others => assert(false) report "SCALC_1/3: shouldn't happen!";
477 -- ueberpruefung kann man sich sparen, da diese ohnehin in
478 -- nextstate gemacht wird.
483 -- ueberpruefung kann man sich sparen, da diese ohnehin in
484 -- nextstate gemacht wird.
485 opcode_next <= ALU_ADD;
486 op2_next <= strich_int;
487 punkt_next <= (0 => '1', others => '0');
492 when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
494 when ALU_ADD | ALU_SUB | ALU_DONE =>
495 if aktop_int = ALU_DONE and op3 < 0 then
496 strich_next <= (not op3) + 1;
497 wtmp_next <= (not op3) + 1;
503 when ALU_MUL | ALU_DIV =>
505 when others => assert (false) report "SCALC_2/1: shouldn't happen!";
507 when others => assert (false) report "SCALC_2/2: shouldn't happen!";
509 -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
510 opp_next <= aktop_int;
513 op1_next <= strich_int;
514 opcode_next <= ALU_DIV;
515 op2_next <= to_signed(10,CBITS);
521 p_write_next <= csigned2hbyte(tmp);
524 strich_next <= wtmp_int;
529 if z_sign_int = '1' then
531 p_write_next <= x"2D";
533 assert(false) report "SWRITE_SIGN: shouldn't happen!";
538 p_write_next <= hbyte(to_unsigned (character'pos(error_str(err_int)(errc_int)),8));
539 errc_tmp_next <= errc_int - 1;
541 errc_next <= errc_tmp_int;
546 p_finished_next <= '1';
551 when SERROR1 | SERROR2 | SDONE => null;
553 if calc_error = '1' then
562 end architecture beh;