+ if p_rdone = '1' then
+ state_next <= SREAD_SPACE_PROC;
+ end if;
+ when SREAD_SPACE_GET_SIGN =>
+ p_rget_next <= '1';
+ if p_rdone = '1' then
+ state_next <= SREAD_SPACE_PROC_SIGN;
+ end if;
+ when SREAD_SPACE_PROC | SREAD_SPACE_PROC_SIGN =>
+ case p_read is
+ when x"20" => null;
+ when x"2D" =>
+ case state_int is
+ when SREAD_SPACE_PROC =>
+ case state_int is
+ when SREAD_SPACE_PROC => state_next <= SREAD_SIGN;
+ when others => assert(false) report "wtf @ state3";
+ end case;
+
+ when SREAD_SPACE_PROC_SIGN =>
+ p_rget_next <= '1';
+ case state_int is
+ when SREAD_SPACE_PROC => state_next <= SREAD_NEXTBYTE;
+ when SREAD_SPACE_PROC_SIGN => state_next <= SREAD_OP1;
+ when others => assert(false) report "wtf @ state2";
+ end case;
+
+ when others => assert(false) report "SREAD_SPACE_PROC/3: shouldn't happen";
+ end case;
+ when others =>
+ p_rget_next <= '1';
+ case state_int is
+ when SREAD_SPACE_PROC => state_next <= SREAD_NEXTBYTE;
+ when SREAD_SPACE_PROC_SIGN => state_next <= SREAD_OP1;
+ when others => assert(false) report "wtf @ state2";
+ end case;
+ end case;
+
+ if p_rdone = '0' then
+ case state_int is
+ when SREAD_SPACE_PROC => state_next <= SREAD_SPACE_GET;
+ when SREAD_SPACE_PROC_SIGN => state_next <= SREAD_SPACE_GET_SIGN;
+ when others => assert(false) report "wtf @ state1";
+ end case;
+ end if;
+ when SREAD_SIGN =>
+ z_sign_next <= '1';
+ if p_rdone = '0' then
+ state_next <= SREAD_NEXTBYTE;
+ end if;
+ when SREAD_NEXTBYTE =>
+ p_rget_next <= '1';
+ if p_rdone = '1' then
+ state_next <= SREAD_CALCNUMBER1;
+ end if;
+ when SREAD_CALCNUMBER1 =>
+ case p_read is
+ -- '+', '-', '*', '/'
+ when x"2B" | x"2D" | x"2A" | x"2F" | x"00" =>
+ if firstz_int then
+ err_next <= 2;
+ else
+ state_next <= SREAD_OP1;
+ p_rget_next <= '1';
+ end if;
+
+ -- ' '
+ when x"20" =>
+ state_next <= SREAD_SPACE_PROC_SIGN;
+ p_rget_next <= '1';
+
+ when others =>
+ op1_next <= z_int;
+ opcode_next <= ALU_MUL;
+ op2_next <= to_signed(10,CBITS);
+ firstz_next <= false;
+ do_calc_next <= '1';
+ end case;
+ if calc_done = '1' then
+ state_next <= SREAD_CALCNUMBER2;
+ end if;
+ when SREAD_CALCNUMBER2 =>
+ z_next <= op3 + hbyte2csigned(p_read);
+ if p_rdone = '0' and calc_done = '0' then
+ state_next <= SREAD_NEXTBYTE;
+ end if;
+
+ when SREAD_OP1 =>
+ case p_read is
+ when x"2B" => aktop_next <= ALU_ADD; -- '+'
+ when x"2D" => aktop_next <= ALU_SUB; -- '-'
+ when x"2A" => aktop_next <= ALU_MUL; -- '*'
+ when x"2F" => aktop_next <= ALU_DIV; -- '/'
+ when x"00" => aktop_next <= ALU_DONE; -- '\0'
+
+ when others => err_next <= 2;
+ end case;
+ state_next <= SREAD_OP2;
+ when SREAD_OP2 =>
+ if p_rdone = '0' then
+ if aktop_int /= ALU_NOP then
+ state_next <= SCALC_1;
+ end if;
+ end if;
+
+ when SCALC_1 =>
+ if z_sign_int = '1' then
+ tmp := (not z_int) + 1;
+ z_next <= tmp;
+ z_sign_next <= '0';
+ else
+ tmp := z_int;
+ end if;
+
+ case opp_int is
+ when ALU_NOP | ALU_ADD | ALU_SUB =>
+ case opp_int is
+ when ALU_SUB =>
+ -- xst (xilinx) workaround
+ if x"80000000" = tmp then
+ -- vgl. testfall 37 und 38
+ err_next <= 3;
+ op1_next <= tmp;
+ else
+ op1_next <= (not tmp) + 1;
+ end if;
+ when others => op1_next <= tmp;
+ end case;
+ case aktop_int is
+ when ALU_ADD | ALU_SUB | ALU_DONE =>
+ opcode_next <= ALU_ADD;
+ op2_next <= strich_int;
+ when ALU_MUL | ALU_DIV =>
+ opcode_next <= ALU_MUL;
+ op2_next <= punkt_int;
+ when others => assert(false) report "SCALC_1/1: shouldn't happen!";
+ end case;
+
+ when ALU_MUL | ALU_DIV =>
+ case aktop_int is
+ when ALU_ADD | ALU_SUB | ALU_DONE | ALU_MUL | ALU_DIV =>
+ op1_next <= punkt_int;
+ opcode_next <= opp_int;
+ op2_next <= tmp;
+ when others => assert(false) report "SCALC_1/2: shouldn't happen!";
+ end case;
+ when others => assert(false) report "SCALC_1/3: shouldn't happen!";
+ end case;
+ do_calc_next <= '1';
+
+ if calc_done = '1' then
+ case opp_int is
+ -- spezialfall: eine zwischenberechnung wird fuer diese
+ -- kombination benoetigt
+ when ALU_MUL | ALU_DIV =>
+ case aktop_int is
+ when ALU_ADD | ALU_SUB | ALU_DONE => state_next <= SCALC_14;
+ when others => state_next <= SCALC_2;
+ end case;
+ when others => state_next <= SCALC_2;
+ end case;
+ end if;
+ when SCALC_14 =>
+ -- ueberpruefung kann man sich sparen, da diese ohnehin in
+ -- nextstate gemacht wird.
+ op1_next <= op3;
+ do_calc_next <= '0';
+
+ if calc_done = '0' then
+ state_next <= SCALC_15;
+ end if;
+ when SCALC_15 =>
+ -- ueberpruefung kann man sich sparen, da diese ohnehin in
+ -- nextstate gemacht wird.
+ opcode_next <= ALU_ADD;
+ op2_next <= strich_int;
+ punkt_next <= (0 => '1', others => '0');
+ do_calc_next <= '1';
+
+ if calc_done = '1' then
+ state_next <= SCALC_2;
+ end if;
+ when SCALC_2 =>
+ case opp_int is
+ when ALU_NOP | ALU_ADD | ALU_SUB | ALU_MUL | ALU_DIV =>
+ case aktop_int is
+ when ALU_ADD | ALU_SUB | ALU_DONE =>
+ if aktop_int = ALU_DONE and op3 < 0 then
+ strich_next <= (not op3) + 1;
+ wtmp_next <= (not op3) + 1;
+ z_sign_next <= '1';
+ else
+ strich_next <= op3;
+ wtmp_next <= op3;
+ end if;
+ when ALU_MUL | ALU_DIV =>
+ punkt_next <= op3;
+ when others => assert (false) report "SCALC_2/1: shouldn't happen!";
+ end case;
+ when ALU_DONE => null;
+ when others => assert (false) report "SCALC_2/2: shouldn't happen!";
+ end case;
+ -- aktuelle rechenoperation fuer naechste 'runde' uebernehmen
+ opp_next <= aktop_int;
+
+ if calc_done = '0' then
+ if aktop_int = ALU_DONE then
+ state_next <= SWRITE_CHAR2;
+ else
+ state_next <= SREAD_NEWNUMBER;
+ end if;
+ end if;
+
+ when SWRITE_CHAR0 =>
+ -- fuer testfall 39 und 40
+ if strich_int = to_signed(-214748364,CBITS) then
+ op1_next <= to_signed(214748364,CBITS);
+ strich_next <= to_signed(214748364,CBITS);
+ else
+ op1_next <= strich_int;
+ end if;
+ opcode_next <= ALU_DIV;
+ op2_next <= to_signed(10,CBITS);
+ do_calc_next <= '1';
+
+ if calc_done = '1' then
+ state_next <= SWRITE_CHAR1;
+ end if;
+ when SWRITE_CHAR1 =>
+ do_calc_next <= '1';