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_NEXTBYTE,
37 SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1, SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR1,
38 SWRITE_CHAR2, SDONE, SERROR1, SERROR2);
39 signal state_int, state_next : PARSER_STATE;
40 signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
41 signal punkt_int, punkt_next : csigned;
42 signal rbyte_int, rbyte_next : hbyte;
43 signal p_write_int, p_write_next : hbyte;
44 signal p_rget_int, p_rget_next : std_logic;
45 signal p_wtake_int, p_wtake_next : std_logic;
46 signal p_finished_int, p_finished_next : std_logic;
47 signal aktop_int, aktop_next : alu_ops;
48 signal opp_int, opp_next : alu_ops;
49 signal opcode_int, opcode_next : alu_ops;
50 signal op1_int, op1_next : csigned;
51 signal op2_int, op2_next : csigned;
52 signal do_calc_int, do_calc_next : std_logic;
54 p_write <= p_write_int;
56 p_wtake <= p_wtake_int;
57 p_finished <= p_finished_int;
62 do_calc <= do_calc_int;
64 process(sys_clk, sys_res_n)
66 if sys_res_n = '0' then
68 z_int <= (others => '0');
69 strich_int <= (others => '0');
70 punkt_int <= (others => '0');
71 wtmp_int <= (others => '0');
72 rbyte_int <= (others => '0');
77 p_spalte <= (others => '0');
79 p_write_int <= (others => '0');
81 p_finished_int <= '0';
82 opcode_int <= ALU_NOP;
83 op1_int <= (others => '0');
84 op2_int <= (others => '0');
87 elsif rising_edge(sys_clk) then
89 state_int <= state_next;
91 strich_int <= strich_next;
92 punkt_int <= punkt_next;
93 wtmp_int <= wtmp_next;
94 rbyte_int <= rbyte_next;
95 aktop_int <= aktop_next;
98 p_rget_int <= p_rget_next;
99 p_write_int <= p_write_next;
100 p_wtake_int <= p_wtake_next;
101 p_finished_int <= p_finished_next;
102 opcode_int <= opcode_next;
105 do_calc_int <= do_calc_next;
110 process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
111 punkt_int, calc_done, wtmp_int, opp_int)
113 state_next <= state_int;
118 state_next <= SREAD_NEWNUMBER;
120 when SREAD_NEWNUMBER =>
121 state_next <= SREAD_NEXTBYTE;
122 when SREAD_NEXTBYTE =>
123 if p_rdone = '1' then
124 state_next <= SREAD_CALCNUMBER1;
126 when SREAD_CALCNUMBER1 =>
127 state_next <= SREAD_CALCNUMBER2;
128 when SREAD_CALCNUMBER2 =>
129 if p_rdone = '0' then
130 if aktop_int /= ALU_NOP then
131 state_next <= SCALC_1;
133 state_next <= SREAD_NEXTBYTE;
137 if calc_done = '1' then
139 -- spezialfall: eine zwischenberechnung wird fuer diese
140 -- kombination benoetigt
141 when ALU_MUL | ALU_DIV =>
143 when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
144 when others => state_next <= SCALC_2;
146 when others => state_next <= SCALC_2;
150 if calc_done = '0' then
151 state_next <= SCALC_15;
154 if calc_done = '1' then
155 state_next <= SCALC_2;
158 if aktop_int = ALU_DONE then
159 state_next <= SWRITE_CHAR1;
161 state_next <= SREAD_NEWNUMBER;
164 if p_wdone = '1' then
165 if strich_int < 10 then
168 state_next <= SWRITE_CHAR2;
172 if p_wdone = '1' then
174 if strich_int < 10 then
177 state_next <= SWRITE_CHAR2;
180 when SWRITE_CHAR2 | SERROR2 =>
181 if p_wdone = '0' then
182 state_next <= SWRITE_CHAR1;
185 if p_wdone = '0' and do_it = '0' then
192 process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
193 strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3,
194 do_calc_int, wtmp_int, punkt_int)
195 function hbyte2csigned (x : hbyte) return csigned is
196 variable y : csigned;
199 when x"30" => y := to_signed(0, CBITS);
200 when x"31" => y := to_signed(1, CBITS);
201 when x"32" => y := to_signed(2, CBITS);
202 when x"33" => y := to_signed(3, CBITS);
203 when x"34" => y := to_signed(4, CBITS);
204 when x"35" => y := to_signed(5, CBITS);
205 when x"36" => y := to_signed(6, CBITS);
206 when x"37" => y := to_signed(7, CBITS);
207 when x"38" => y := to_signed(8, CBITS);
208 when x"39" => y := to_signed(9, CBITS);
209 when others => assert(false) report "hbyte2csigned: shouldn't happen";
212 end function hbyte2csigned;
214 function csigned2hbyte (x : csigned) return hbyte is
218 when x"00000000" => y := x"30";
219 when x"00000001" => y := x"31";
220 when x"00000002" => y := x"32";
221 when x"00000003" => y := x"33";
222 when x"00000004" => y := x"34";
223 when x"00000005" => y := x"35";
224 when x"00000006" => y := x"36";
225 when x"00000007" => y := x"37";
226 when x"00000008" => y := x"38";
227 when x"00000009" => y := x"39";
228 when others => assert(false) report "csigned2hbyte: shouldn't happen";
231 end function csigned2hbyte;
233 variable multmp : signed(((2*CBITS)-1) downto 0);
234 variable tmp : csigned;
238 strich_next <= strich_int;
239 punkt_next <= punkt_int;
240 wtmp_next <= wtmp_int;
241 rbyte_next <= rbyte_int;
242 aktop_next <= aktop_int;
246 p_write_next <= p_write_int;
248 p_finished_next <= '0';
249 opcode_next <= opcode_int;
256 strich_next <= (others => '0');
257 punkt_next <= (0 => '1', others => '0');
259 when SREAD_NEWNUMBER =>
260 z_next <= (others => '0');
261 rbyte_next <= (others => '0');
262 p_write_next <= (others => '0');
263 aktop_next <= ALU_NOP;
264 when SREAD_NEXTBYTE =>
266 when SREAD_CALCNUMBER1 =>
270 aktop_next <= ALU_ADD;
273 -- TODO: sign check beim ersten byte lesen!
274 aktop_next <= ALU_SUB;
277 aktop_next <= ALU_MUL;
280 aktop_next <= ALU_DIV;
284 aktop_next <= ALU_DONE;
287 -- TODO: check auf overflow
288 multmp := (z_int * 10) + hbyte2csigned(p_read);
289 z_next <= multmp((CBITS-1) downto 0);
291 when SREAD_CALCNUMBER2 =>
296 when ALU_NOP | ALU_ADD | ALU_SUB =>
298 when ALU_SUB => op1_next <= (not z_int) + 1;
299 when others => op1_next <= z_int;
302 when ALU_ADD | ALU_SUB | ALU_DONE =>
303 opcode_next <= ALU_ADD;
304 op2_next <= strich_int;
305 when ALU_MUL | ALU_DIV =>
306 opcode_next <= ALU_MUL;
307 op2_next <= punkt_int;
308 when others => assert(false) report "SCALC_1/1: shouldn't happen!";
311 when ALU_MUL | ALU_DIV =>
313 when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
314 op1_next <= punkt_int;
315 opcode_next <= opp_int;
317 when others => assert(false) report "SCALC_1/2: shouldn't happen!";
319 when others => assert(false) report "SCALC_1/3: shouldn't happen!";
324 -- ueberpruefung kann man sich sparen, da diese ohnehin in
325 -- nextstate gemacht wird.
330 -- ueberpruefung kann man sich sparen, da diese ohnehin in
331 -- nextstate gemacht wird.
332 opcode_next <= ALU_ADD;
333 op2_next <= strich_int;
334 punkt_next <= (0 => '1', others => '0');
339 when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
341 when ALU_ADD | ALU_SUB | ALU_DONE =>
343 when ALU_MUL | ALU_DIV =>
345 when others => assert (false) report "SCALC_2/1: shouldn't happen!";
347 when others => assert (false) report "SCALC_2/2: shouldn't happen!";
349 -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
350 opp_next <= aktop_int;
354 tmp := strich_int mod 10;
355 p_write_next <= csigned2hbyte(tmp);
356 wtmp_next <= strich_int / 10;
358 strich_next <= wtmp_int;
368 p_finished_next <= '1';
371 end architecture beh;