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;
58 p_write <= p_write_int;
60 p_wtake <= p_wtake_int;
61 p_finished <= p_finished_int;
66 do_calc <= do_calc_int;
68 process(sys_clk, sys_res_n)
70 if sys_res_n = '0' then
72 z_int <= (others => '0');
74 strich_int <= (others => '0');
75 punkt_int <= (others => '0');
76 wtmp_int <= (others => '0');
77 rbyte_int <= (others => '0');
82 p_spalte <= (others => '0');
84 p_write_int <= (others => '0');
86 p_finished_int <= '0';
87 opcode_int <= ALU_NOP;
88 op1_int <= (others => '0');
89 op2_int <= (others => '0');
92 elsif rising_edge(sys_clk) then
94 state_int <= state_next;
96 z_sign_int <= z_sign_next;
97 strich_int <= strich_next;
98 punkt_int <= punkt_next;
99 wtmp_int <= wtmp_next;
100 rbyte_int <= rbyte_next;
101 aktop_int <= aktop_next;
104 p_rget_int <= p_rget_next;
105 p_write_int <= p_write_next;
106 p_wtake_int <= p_wtake_next;
107 p_finished_int <= p_finished_next;
108 opcode_int <= opcode_next;
111 do_calc_int <= do_calc_next;
116 process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
117 punkt_int, calc_done, wtmp_int, opp_int, goto_calcn1, goto_op1,
118 goto_space3, goto_sign, z_sign_int)
120 state_next <= state_int;
125 state_next <= SREAD_NEWNUMBER;
127 when SREAD_NEWNUMBER =>
128 state_next <= SREAD_SPACE1_2;
129 when SREAD_SPACE1_2 =>
130 if p_rdone = '1' then
131 state_next <= SREAD_SPACE2;
133 when SREAD_SPACE1_3 =>
134 if p_rdone = '1' then
135 state_next <= SREAD_SPACE3;
137 when SREAD_SPACE2 | SREAD_SPACE3 =>
138 if goto_calcn1 = '1' then
140 when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE;
141 when SREAD_SPACE3 => state_next <= SREAD_OP1;
142 when others => assert(false) report "wtf @ state2";
145 if goto_sign = '1' then
147 when SREAD_SPACE2 => state_next <= SREAD_SIGN1;
148 when others => assert(false) report "wtf @ state3";
151 if p_rdone = '0' then
152 if goto_calcn1 = '0' then
154 when SREAD_SPACE2 => state_next <= SREAD_SPACE1_2;
155 when SREAD_SPACE3 => state_next <= SREAD_SPACE1_3;
156 when others => assert(false) report "wtf @ state1";
161 if p_rdone = '0' then
162 state_next <= SREAD_NEXTBYTE;
164 when SREAD_NEXTBYTE =>
165 if p_rdone = '1' then
166 state_next <= SREAD_CALCNUMBER1;
168 when SREAD_CALCNUMBER1 =>
169 if goto_op1 = '1' then
170 state_next <= SREAD_OP1;
171 elsif goto_space3 = '1' then
172 state_next <= SREAD_SPACE3;
174 state_next <= SREAD_CALCNUMBER2;
177 state_next <= SREAD_OP2;
179 if p_rdone = '0' then
180 if aktop_int /= ALU_NOP then
181 state_next <= SCALC_1;
184 when SREAD_CALCNUMBER2 =>
185 if p_rdone = '0' then
186 state_next <= SREAD_NEXTBYTE;
189 if calc_done = '1' then
191 -- spezialfall: eine zwischenberechnung wird fuer diese
192 -- kombination benoetigt
193 when ALU_MUL | ALU_DIV =>
195 when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
196 when others => state_next <= SCALC_2;
198 when others => state_next <= SCALC_2;
202 if calc_done = '0' then
203 state_next <= SCALC_15;
206 if calc_done = '1' then
207 state_next <= SCALC_2;
210 if aktop_int = ALU_DONE then
211 state_next <= SWRITE_CHAR1;
213 state_next <= SREAD_NEWNUMBER;
216 if p_wdone = '1' then
217 if strich_int < 10 then
218 if z_sign_int = '1' then
219 state_next <= SWRITE_SIGN1;
224 state_next <= SWRITE_CHAR2;
228 if p_wdone = '1' then
230 if strich_int < 10 then
233 state_next <= SWRITE_CHAR2;
236 when SWRITE_CHAR2 | SERROR2 =>
237 if p_wdone = '0' then
238 state_next <= SWRITE_CHAR1;
241 if p_wdone = '0' then
242 state_next <= SWRITE_SIGN2;
245 if p_wdone = '1' then
250 if p_wdone = '0' and do_it = '0' then
257 process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
258 strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3,
259 do_calc_int, wtmp_int, punkt_int, z_sign_int)
260 function hbyte2csigned (x : hbyte) return csigned is
261 variable y : csigned;
264 when x"30" => y := to_signed(0, CBITS);
265 when x"31" => y := to_signed(1, CBITS);
266 when x"32" => y := to_signed(2, CBITS);
267 when x"33" => y := to_signed(3, CBITS);
268 when x"34" => y := to_signed(4, CBITS);
269 when x"35" => y := to_signed(5, CBITS);
270 when x"36" => y := to_signed(6, CBITS);
271 when x"37" => y := to_signed(7, CBITS);
272 when x"38" => y := to_signed(8, CBITS);
273 when x"39" => y := to_signed(9, CBITS);
274 when others => assert(false) report "hbyte2csigned: shouldn't happen";
277 end function hbyte2csigned;
279 function csigned2hbyte (x : csigned) return hbyte is
283 when x"00000000" => y := x"30";
284 when x"00000001" => y := x"31";
285 when x"00000002" => y := x"32";
286 when x"00000003" => y := x"33";
287 when x"00000004" => y := x"34";
288 when x"00000005" => y := x"35";
289 when x"00000006" => y := x"36";
290 when x"00000007" => y := x"37";
291 when x"00000008" => y := x"38";
292 when x"00000009" => y := x"39";
293 when others => assert(false) report "csigned2hbyte: shouldn't happen";
296 end function csigned2hbyte;
298 variable multmp : signed(((2*CBITS)-1) downto 0);
299 variable tmp : csigned;
303 z_sign_next <= z_sign_int;
304 strich_next <= strich_int;
305 punkt_next <= punkt_int;
306 wtmp_next <= wtmp_int;
307 rbyte_next <= rbyte_int;
308 aktop_next <= aktop_int;
312 p_write_next <= p_write_int;
314 p_finished_next <= '0';
315 opcode_next <= opcode_int;
326 strich_next <= (others => '0');
327 punkt_next <= (0 => '1', others => '0');
329 when SREAD_NEWNUMBER =>
330 z_next <= (others => '0');
332 rbyte_next <= (others => '0');
333 p_write_next <= (others => '0');
334 aktop_next <= ALU_NOP;
335 when SREAD_NEXTBYTE | SREAD_SPACE1_2 | SREAD_SPACE1_3 =>
337 when SREAD_SPACE2 | SREAD_SPACE3 =>
343 when SREAD_SPACE2 => goto_sign <= '1';
344 when SREAD_SPACE3 => goto_calcn1 <= '1'; p_rget_next <= '1';
345 when others => assert(false) report "SREAD_SPACE2/3: shouldn't happen";
352 when SREAD_CALCNUMBER1 =>
354 -- '+', '-', '*', '/'
355 when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
365 -- TODO: check auf overflow
366 multmp := (z_int * 10) + hbyte2csigned(p_read);
367 z_next <= multmp((CBITS-1) downto 0);
371 when SREAD_CALCNUMBER2 | SREAD_OP2 =>
377 aktop_next <= ALU_ADD;
380 -- TODO: sign check beim ersten byte lesen!
381 aktop_next <= ALU_SUB;
384 aktop_next <= ALU_MUL;
387 aktop_next <= ALU_DIV;
391 aktop_next <= ALU_DONE;
394 when others => assert(false) report "TODO: ...";
399 if z_sign_int = '1' then
400 tmp := (not z_int) + 1;
408 when ALU_NOP | ALU_ADD | ALU_SUB =>
410 when ALU_SUB => op1_next <= (not tmp) + 1;
411 when others => op1_next <= tmp;
414 when ALU_ADD | ALU_SUB | ALU_DONE =>
415 opcode_next <= ALU_ADD;
416 op2_next <= strich_int;
417 when ALU_MUL | ALU_DIV =>
418 opcode_next <= ALU_MUL;
419 op2_next <= punkt_int;
420 when others => assert(false) report "SCALC_1/1: shouldn't happen!";
423 when ALU_MUL | ALU_DIV =>
425 when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
426 op1_next <= punkt_int;
427 opcode_next <= opp_int;
429 when others => assert(false) report "SCALC_1/2: shouldn't happen!";
431 when others => assert(false) report "SCALC_1/3: shouldn't happen!";
436 -- ueberpruefung kann man sich sparen, da diese ohnehin in
437 -- nextstate gemacht wird.
442 -- ueberpruefung kann man sich sparen, da diese ohnehin in
443 -- nextstate gemacht wird.
444 opcode_next <= ALU_ADD;
445 op2_next <= strich_int;
446 punkt_next <= (0 => '1', others => '0');
451 when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
453 when ALU_ADD | ALU_SUB | ALU_DONE =>
454 if aktop_int = ALU_DONE and op3 < 0 then
455 strich_next <= (not op3) + 1;
460 when ALU_MUL | ALU_DIV =>
462 when others => assert (false) report "SCALC_2/1: shouldn't happen!";
464 when others => assert (false) report "SCALC_2/2: shouldn't happen!";
466 -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
467 opp_next <= aktop_int;
471 tmp := strich_int mod 10;
472 p_write_next <= csigned2hbyte(tmp);
473 wtmp_next <= strich_int / 10;
475 strich_next <= wtmp_int;
480 if z_sign_int = '1' then
482 p_write_next <= x"2D";
484 assert(false) report "SWRITE_SIGN: shouldn't happen!";
495 p_finished_next <= '1';
498 end architecture beh;