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_NEXTBYTE, SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1, SCALC_14,
39 SCALC_15, SCALC_2, SWRITE_CHAR1, SWRITE_CHAR2, SDONE, SERROR1, SERROR2);
40 signal state_int, state_next : PARSER_STATE;
41 signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
42 signal punkt_int, punkt_next : csigned;
43 signal rbyte_int, rbyte_next : hbyte;
44 signal p_write_int, p_write_next : hbyte;
45 signal p_rget_int, p_rget_next : std_logic;
46 signal p_wtake_int, p_wtake_next : std_logic;
47 signal p_finished_int, p_finished_next : std_logic;
48 signal aktop_int, aktop_next : alu_ops;
49 signal opp_int, opp_next : alu_ops;
50 signal opcode_int, opcode_next : alu_ops;
51 signal op1_int, op1_next : csigned;
52 signal op2_int, op2_next : csigned;
53 signal do_calc_int, do_calc_next : std_logic;
54 signal goto_calcn1, goto_op1, goto_space3 : std_logic;
56 p_write <= p_write_int;
58 p_wtake <= p_wtake_int;
59 p_finished <= p_finished_int;
64 do_calc <= do_calc_int;
66 process(sys_clk, sys_res_n)
68 if sys_res_n = '0' then
70 z_int <= (others => '0');
71 strich_int <= (others => '0');
72 punkt_int <= (others => '0');
73 wtmp_int <= (others => '0');
74 rbyte_int <= (others => '0');
79 p_spalte <= (others => '0');
81 p_write_int <= (others => '0');
83 p_finished_int <= '0';
84 opcode_int <= ALU_NOP;
85 op1_int <= (others => '0');
86 op2_int <= (others => '0');
89 elsif rising_edge(sys_clk) then
91 state_int <= state_next;
93 strich_int <= strich_next;
94 punkt_int <= punkt_next;
95 wtmp_int <= wtmp_next;
96 rbyte_int <= rbyte_next;
97 aktop_int <= aktop_next;
100 p_rget_int <= p_rget_next;
101 p_write_int <= p_write_next;
102 p_wtake_int <= p_wtake_next;
103 p_finished_int <= p_finished_next;
104 opcode_int <= opcode_next;
107 do_calc_int <= do_calc_next;
112 process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
113 punkt_int, calc_done, wtmp_int, opp_int, goto_calcn1, goto_op1,
116 state_next <= state_int;
121 state_next <= SREAD_NEWNUMBER;
123 when SREAD_NEWNUMBER =>
124 state_next <= SREAD_SPACE1_2;
125 when SREAD_SPACE1_2 =>
126 if p_rdone = '1' then
127 state_next <= SREAD_SPACE2;
129 when SREAD_SPACE1_3 =>
130 if p_rdone = '1' then
131 state_next <= SREAD_SPACE3;
133 when SREAD_SPACE2 | SREAD_SPACE3 =>
134 if p_rdone = '0' then
135 if goto_calcn1 = '0' then
137 when SREAD_SPACE2 => state_next <= SREAD_SPACE1_2;
138 when SREAD_SPACE3 => state_next <= SREAD_SPACE1_3;
139 when others => assert(false) report "wtf @ state2";
143 if goto_calcn1 = '1' then
145 when SREAD_SPACE2 => state_next <= SREAD_NEXTBYTE;
146 when SREAD_SPACE3 => state_next <= SREAD_OP1;
147 when others => assert(false) report "wtf @ state1";
150 when SREAD_NEXTBYTE =>
151 if p_rdone = '1' then
152 state_next <= SREAD_CALCNUMBER1;
154 when SREAD_CALCNUMBER1 =>
155 if goto_op1 = '1' then
156 state_next <= SREAD_OP1;
157 elsif goto_space3 = '1' then
158 state_next <= SREAD_SPACE3;
160 state_next <= SREAD_CALCNUMBER2;
163 state_next <= SREAD_OP2;
165 if p_rdone = '0' then
166 if aktop_int /= ALU_NOP then
167 state_next <= SCALC_1;
170 when SREAD_CALCNUMBER2 =>
171 if p_rdone = '0' then
172 state_next <= SREAD_NEXTBYTE;
175 if calc_done = '1' then
177 -- spezialfall: eine zwischenberechnung wird fuer diese
178 -- kombination benoetigt
179 when ALU_MUL | ALU_DIV =>
181 when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
182 when others => state_next <= SCALC_2;
184 when others => state_next <= SCALC_2;
188 if calc_done = '0' then
189 state_next <= SCALC_15;
192 if calc_done = '1' then
193 state_next <= SCALC_2;
196 if aktop_int = ALU_DONE then
197 state_next <= SWRITE_CHAR1;
199 state_next <= SREAD_NEWNUMBER;
202 if p_wdone = '1' then
203 if strich_int < 10 then
206 state_next <= SWRITE_CHAR2;
210 if p_wdone = '1' then
212 if strich_int < 10 then
215 state_next <= SWRITE_CHAR2;
218 when SWRITE_CHAR2 | SERROR2 =>
219 if p_wdone = '0' then
220 state_next <= SWRITE_CHAR1;
223 if p_wdone = '0' and do_it = '0' then
230 process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
231 strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3,
232 do_calc_int, wtmp_int, punkt_int)
233 function hbyte2csigned (x : hbyte) return csigned is
234 variable y : csigned;
237 when x"30" => y := to_signed(0, CBITS);
238 when x"31" => y := to_signed(1, CBITS);
239 when x"32" => y := to_signed(2, CBITS);
240 when x"33" => y := to_signed(3, CBITS);
241 when x"34" => y := to_signed(4, CBITS);
242 when x"35" => y := to_signed(5, CBITS);
243 when x"36" => y := to_signed(6, CBITS);
244 when x"37" => y := to_signed(7, CBITS);
245 when x"38" => y := to_signed(8, CBITS);
246 when x"39" => y := to_signed(9, CBITS);
247 when others => assert(false) report "hbyte2csigned: shouldn't happen";
250 end function hbyte2csigned;
252 function csigned2hbyte (x : csigned) return hbyte is
256 when x"00000000" => y := x"30";
257 when x"00000001" => y := x"31";
258 when x"00000002" => y := x"32";
259 when x"00000003" => y := x"33";
260 when x"00000004" => y := x"34";
261 when x"00000005" => y := x"35";
262 when x"00000006" => y := x"36";
263 when x"00000007" => y := x"37";
264 when x"00000008" => y := x"38";
265 when x"00000009" => y := x"39";
266 when others => assert(false) report "csigned2hbyte: shouldn't happen";
269 end function csigned2hbyte;
271 variable multmp : signed(((2*CBITS)-1) downto 0);
272 variable tmp : csigned;
276 strich_next <= strich_int;
277 punkt_next <= punkt_int;
278 wtmp_next <= wtmp_int;
279 rbyte_next <= rbyte_int;
280 aktop_next <= aktop_int;
284 p_write_next <= p_write_int;
286 p_finished_next <= '0';
287 opcode_next <= opcode_int;
297 strich_next <= (others => '0');
298 punkt_next <= (0 => '1', others => '0');
300 when SREAD_NEWNUMBER =>
301 z_next <= (others => '0');
302 rbyte_next <= (others => '0');
303 p_write_next <= (others => '0');
304 aktop_next <= ALU_NOP;
305 when SREAD_NEXTBYTE | SREAD_SPACE1_2 | SREAD_SPACE1_3 =>
307 when SREAD_SPACE2 | SREAD_SPACE3 =>
316 when SREAD_CALCNUMBER1 =>
318 -- '+', '-', '*', '/'
319 when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
329 -- TODO: check auf overflow
330 multmp := (z_int * 10) + hbyte2csigned(p_read);
331 z_next <= multmp((CBITS-1) downto 0);
333 when SREAD_CALCNUMBER2 | SREAD_OP2 =>
339 aktop_next <= ALU_ADD;
342 -- TODO: sign check beim ersten byte lesen!
343 aktop_next <= ALU_SUB;
346 aktop_next <= ALU_MUL;
349 aktop_next <= ALU_DIV;
353 aktop_next <= ALU_DONE;
356 when others => assert(false) report "TODO: ...";
362 when ALU_NOP | ALU_ADD | ALU_SUB =>
364 when ALU_SUB => op1_next <= (not z_int) + 1;
365 when others => op1_next <= z_int;
368 when ALU_ADD | ALU_SUB | ALU_DONE =>
369 opcode_next <= ALU_ADD;
370 op2_next <= strich_int;
371 when ALU_MUL | ALU_DIV =>
372 opcode_next <= ALU_MUL;
373 op2_next <= punkt_int;
374 when others => assert(false) report "SCALC_1/1: shouldn't happen!";
377 when ALU_MUL | ALU_DIV =>
379 when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
380 op1_next <= punkt_int;
381 opcode_next <= opp_int;
383 when others => assert(false) report "SCALC_1/2: shouldn't happen!";
385 when others => assert(false) report "SCALC_1/3: shouldn't happen!";
390 -- ueberpruefung kann man sich sparen, da diese ohnehin in
391 -- nextstate gemacht wird.
396 -- ueberpruefung kann man sich sparen, da diese ohnehin in
397 -- nextstate gemacht wird.
398 opcode_next <= ALU_ADD;
399 op2_next <= strich_int;
400 punkt_next <= (0 => '1', others => '0');
405 when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
407 when ALU_ADD | ALU_SUB | ALU_DONE =>
409 when ALU_MUL | ALU_DIV =>
411 when others => assert (false) report "SCALC_2/1: shouldn't happen!";
413 when others => assert (false) report "SCALC_2/2: shouldn't happen!";
415 -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
416 opp_next <= aktop_int;
420 tmp := strich_int mod 10;
421 p_write_next <= csigned2hbyte(tmp);
422 wtmp_next <= strich_int / 10;
424 strich_next <= wtmp_int;
434 p_finished_next <= '1';
437 end architecture beh;