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;
26 do_calc : out std_logic;
27 calc_done : in std_logic;
28 calc_error : in std_logic;
31 finished : out std_logic
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_SIGN1, SREAD_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1,
39 SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR1, SWRITE_CHAR2, SWRITE_SIGN1,
40 SWRITE_SIGN2, SDONE, SERROR1, SERROR2);
41 signal state_int, state_next : PARSER_STATE;
42 signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
43 signal punkt_int, punkt_next : csigned;
44 signal rbyte_int, rbyte_next : hbyte;
45 signal p_write_int, p_write_next : hbyte;
46 signal p_rget_int, p_rget_next : std_logic;
47 signal p_wtake_int, p_wtake_next : std_logic;
48 signal p_finished_int, p_finished_next : std_logic;
49 signal aktop_int, aktop_next : alu_ops;
50 signal opp_int, opp_next : alu_ops;
51 signal opcode_int, opcode_next : alu_ops;
52 signal op1_int, op1_next : csigned;
53 signal op2_int, op2_next : csigned;
54 signal do_calc_int, do_calc_next : std_logic;
55 signal goto_calcn1, goto_op1, goto_space3, goto_sign : std_logic;
56 signal z_sign_next, z_sign_int : std_logic;
57 signal err_next, err_int : natural;
58 signal errc_next, errc_int : natural;
59 signal errc_tmp_next, errc_tmp_int : natural;
60 signal firstz_next, firstz_int : boolean;
62 p_write <= p_write_int;
64 p_wtake <= p_wtake_int;
65 p_finished <= p_finished_int;
70 do_calc <= do_calc_int;
72 process(sys_clk, sys_res_n)
74 if sys_res_n = '0' then
76 z_int <= (others => '0');
78 strich_int <= (others => '0');
79 punkt_int <= (others => '0');
80 wtmp_int <= (others => '0');
81 rbyte_int <= (others => '0');
90 p_spalte <= (others => '0');
92 p_write_int <= (others => '0');
94 p_finished_int <= '0';
95 opcode_int <= ALU_NOP;
96 op1_int <= (others => '0');
97 op2_int <= (others => '0');
100 elsif rising_edge(sys_clk) then
102 state_int <= state_next;
104 z_sign_int <= z_sign_next;
105 strich_int <= strich_next;
106 punkt_int <= punkt_next;
107 wtmp_int <= wtmp_next;
108 rbyte_int <= rbyte_next;
109 aktop_int <= aktop_next;
112 errc_int <= errc_next;
113 errc_tmp_int <= errc_tmp_next;
114 firstz_int <= firstz_next;
116 p_rget_int <= p_rget_next;
117 p_write_int <= p_write_next;
118 p_wtake_int <= p_wtake_next;
119 p_finished_int <= p_finished_next;
120 opcode_int <= opcode_next;
123 do_calc_int <= do_calc_next;
128 process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
129 punkt_int, calc_done, wtmp_int, opp_int, goto_calcn1, goto_op1,
130 goto_space3, goto_sign, z_sign_int, err_int, errc_int, calc_error,
133 state_next <= state_int;
138 state_next <= SREAD_NEWNUMBER;
140 when SREAD_NEWNUMBER =>
141 state_next <= SREAD_SPACE1_2;
142 when SREAD_SPACE1_2 =>
143 if p_rdone = '1' then
144 state_next <= SREAD_SPACE2;
146 when SREAD_SPACE1_3 =>
147 if p_rdone = '1' then
148 state_next <= SREAD_SPACE3;
150 when SREAD_SPACE2 | SREAD_SPACE3 =>
151 if goto_calcn1 = '1' then
153 when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE;
154 when SREAD_SPACE3 => state_next <= SREAD_OP1;
155 when others => assert(false) report "wtf @ state2";
158 if goto_sign = '1' then
160 when SREAD_SPACE2 => state_next <= SREAD_SIGN1;
161 when others => assert(false) report "wtf @ state3";
164 if p_rdone = '0' then
165 if goto_calcn1 = '0' then
167 when SREAD_SPACE2 => state_next <= SREAD_SPACE1_2;
168 when SREAD_SPACE3 => state_next <= SREAD_SPACE1_3;
169 when others => assert(false) report "wtf @ state1";
174 if p_rdone = '0' then
175 state_next <= SREAD_NEXTBYTE;
177 when SREAD_NEXTBYTE =>
178 if p_rdone = '1' then
179 state_next <= SREAD_CALCNUMBER1;
181 when SREAD_CALCNUMBER1 =>
182 if goto_op1 = '1' then
183 state_next <= SREAD_OP1;
184 elsif goto_space3 = '1' then
185 state_next <= SREAD_SPACE3;
187 state_next <= SREAD_CALCNUMBER2;
190 state_next <= SREAD_OP2;
192 if p_rdone = '0' then
193 if aktop_int /= ALU_NOP then
194 state_next <= SCALC_1;
197 when SREAD_CALCNUMBER2 =>
198 if p_rdone = '0' then
199 state_next <= SREAD_NEXTBYTE;
202 if calc_done = '1' then
204 -- spezialfall: eine zwischenberechnung wird fuer diese
205 -- kombination benoetigt
206 when ALU_MUL | ALU_DIV =>
208 when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
209 when others => state_next <= SCALC_2;
211 when others => state_next <= SCALC_2;
215 if calc_done = '0' then
216 state_next <= SCALC_15;
219 if calc_done = '1' then
220 state_next <= SCALC_2;
223 if aktop_int = ALU_DONE then
224 state_next <= SWRITE_CHAR1;
226 state_next <= SREAD_NEWNUMBER;
229 if p_wdone = '1' then
230 if strich_int < 10 then
231 if z_sign_int = '1' then
232 state_next <= SWRITE_SIGN1;
237 state_next <= SWRITE_CHAR2;
241 if p_wdone = '1' then
242 if errc_int <= 2 then
245 state_next <= SERROR2;
249 if p_wdone = '0' then
250 state_next <= SERROR1;
253 if p_wdone = '0' then
254 state_next <= SWRITE_CHAR1;
257 if p_wdone = '0' then
258 state_next <= SWRITE_SIGN2;
261 if p_wdone = '1' then
266 if p_wdone = '0' and do_it = '0' then
273 when SERROR1 | SERROR2 | SDONE => null;
276 state_next <= SERROR1;
282 process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
283 strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3,
284 do_calc_int, wtmp_int, punkt_int, z_sign_int, err_int, errc_int,
285 errc_tmp_int, firstz_int, calc_done, calc_error)
286 function hbyte2csigned (x : hbyte) return csigned is
287 variable y : csigned;
290 when x"30" => y := to_signed(0, CBITS);
291 when x"31" => y := to_signed(1, CBITS);
292 when x"32" => y := to_signed(2, CBITS);
293 when x"33" => y := to_signed(3, CBITS);
294 when x"34" => y := to_signed(4, CBITS);
295 when x"35" => y := to_signed(5, CBITS);
296 when x"36" => y := to_signed(6, CBITS);
297 when x"37" => y := to_signed(7, CBITS);
298 when x"38" => y := to_signed(8, CBITS);
299 when x"39" => y := to_signed(9, CBITS);
300 when others => assert(false) report "hbyte2csigned: shouldn't happen";
303 end function hbyte2csigned;
305 function csigned2hbyte (x : csigned) return hbyte is
309 when x"00000000" => y := x"30";
310 when x"00000001" => y := x"31";
311 when x"00000002" => y := x"32";
312 when x"00000003" => y := x"33";
313 when x"00000004" => y := x"34";
314 when x"00000005" => y := x"35";
315 when x"00000006" => y := x"36";
316 when x"00000007" => y := x"37";
317 when x"00000008" => y := x"38";
318 when x"00000009" => y := x"39";
319 when others => assert(false) report "csigned2hbyte: shouldn't happen";
322 end function csigned2hbyte;
325 variable multmp : signed(((2*CBITS)-1) downto 0);
326 variable tmp : csigned;
328 type errstrings is array (natural range 1 to 3) of hstring;
329 variable error_str : errstrings := (
330 --1 => (71 => character'val(0), 50 to 70 => " Division durch 0", others => character'val(20)),
331 1 => " Division durch Null ",
333 3 => " Over- bzw. Underflow "
338 z_sign_next <= z_sign_int;
339 strich_next <= strich_int;
340 punkt_next <= punkt_int;
341 wtmp_next <= wtmp_int;
342 rbyte_next <= rbyte_int;
343 aktop_next <= aktop_int;
346 errc_next <= errc_int;
347 errc_tmp_next <= errc_tmp_int;
348 firstz_next <= firstz_int;
351 p_write_next <= p_write_int;
353 p_finished_next <= '0';
354 opcode_next <= opcode_int;
365 strich_next <= (others => '0');
366 punkt_next <= (0 => '1', others => '0');
368 when SREAD_NEWNUMBER =>
369 z_next <= (others => '0');
372 rbyte_next <= (others => '0');
373 p_write_next <= (others => '0');
374 aktop_next <= ALU_NOP;
375 when SREAD_NEXTBYTE | SREAD_SPACE1_2 | SREAD_SPACE1_3 =>
377 when SREAD_SPACE2 | SREAD_SPACE3 =>
383 when SREAD_SPACE2 => goto_sign <= '1';
384 when SREAD_SPACE3 => goto_calcn1 <= '1'; p_rget_next <= '1';
385 when others => assert(false) report "SREAD_SPACE2/3: shouldn't happen";
392 when SREAD_CALCNUMBER1 =>
394 -- '+', '-', '*', '/'
395 when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
409 -- TODO: check auf overflow
410 multmp := (z_int * 10) + hbyte2csigned(p_read);
411 z_next <= multmp((CBITS-1) downto 0);
412 firstz_next <= false;
416 when SREAD_CALCNUMBER2 | SREAD_OP2 =>
421 when x"2B" => aktop_next <= ALU_ADD;
423 when x"2D" => aktop_next <= ALU_SUB;
425 when x"2A" => aktop_next <= ALU_MUL;
427 when x"2F" => aktop_next <= ALU_DIV;
429 when x"00" => aktop_next <= ALU_DONE;
431 when others => err_next <= 2;
436 if z_sign_int = '1' then
437 tmp := (not z_int) + 1;
445 when ALU_NOP | ALU_ADD | ALU_SUB =>
447 when ALU_SUB => op1_next <= (not tmp) + 1;
448 when others => op1_next <= tmp;
451 when ALU_ADD | ALU_SUB | ALU_DONE =>
452 opcode_next <= ALU_ADD;
453 op2_next <= strich_int;
454 when ALU_MUL | ALU_DIV =>
455 opcode_next <= ALU_MUL;
456 op2_next <= punkt_int;
457 when others => assert(false) report "SCALC_1/1: shouldn't happen!";
460 when ALU_MUL | ALU_DIV =>
462 when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
463 op1_next <= punkt_int;
464 opcode_next <= opp_int;
466 when others => assert(false) report "SCALC_1/2: shouldn't happen!";
468 when others => assert(false) report "SCALC_1/3: shouldn't happen!";
473 -- ueberpruefung kann man sich sparen, da diese ohnehin in
474 -- nextstate gemacht wird.
479 -- ueberpruefung kann man sich sparen, da diese ohnehin in
480 -- nextstate gemacht wird.
481 opcode_next <= ALU_ADD;
482 op2_next <= strich_int;
483 punkt_next <= (0 => '1', others => '0');
488 when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
490 when ALU_ADD | ALU_SUB | ALU_DONE =>
491 if aktop_int = ALU_DONE and op3 < 0 then
492 strich_next <= (not op3) + 1;
497 when ALU_MUL | ALU_DIV =>
499 when others => assert (false) report "SCALC_2/1: shouldn't happen!";
501 when others => assert (false) report "SCALC_2/2: shouldn't happen!";
503 -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
504 opp_next <= aktop_int;
508 tmp := strich_int mod 10;
509 p_write_next <= csigned2hbyte(tmp);
510 wtmp_next <= strich_int / 10;
512 strich_next <= wtmp_int;
517 if z_sign_int = '1' then
519 p_write_next <= x"2D";
521 assert(false) report "SWRITE_SIGN: shouldn't happen!";
527 error_str(err_int)(71) := character'val(0);
528 p_write_next <= hbyte(to_unsigned (character'pos(error_str(err_int)(errc_int)),8));
529 errc_tmp_next <= errc_int - 1;
531 errc_next <= errc_tmp_int;
536 p_finished_next <= '1';
541 when SERROR1 | SERROR2 | SDONE => null;
543 if calc_error = '1' then
552 end architecture beh;