SDONE, SERROR);
signal state_int, state_next : ALU_STATE;
signal done_intern, error_intern, div_calc_done, div_go_calc : std_logic;
- signal op3_int, op3_next : csigned := (others => '0');
+ signal op3_int, op3_next : csigned;
signal calc_done_int, calc_done_next : std_logic;
signal calc_error_int, calc_error_next : std_logic;
-- signale fuer division
op1_next <= (others => '0');
op2_next <= (others => '0');
sign_next <= '0';
- op3_next <= (others => '0');
+ op3_next <= op3_int;
case state_int is
when SIDLE =>
op3_next(CBITS-1) <= mulsign;
if mulsign = '1' then
- multmp2 := not (multmp + 1);
+ multmp2 := (not multmp) + 1;
else
multmp2 := multmp;
end if;
op1_var := op1;
op2_var := op2;
if op1(CBITS-1) = '1' then
- op1_var := not (op1_var + 1);
+ op1_var := (not op1_var) + 1;
end if;
if op2(CBITS-1) = '1' then
- op2_var := not (op2_var + 1);
+ op2_var := (not op2_var) + 1;
end if;
dividend_msb_var := find_msb(op1_var)-1;
if (state_int = SERROR) then
calc_error_next <= '1';
end if;
- op3_next <= op3_int;
end case;
end process;
end architecture beh;
op3 : in csigned;
do_calc : out std_logic;
calc_done : in std_logic;
- -- TODO: calc_error : in std_logic;
+ calc_error : in std_logic;
-- Scanner
do_it : in std_logic;
finished : out std_logic
architecture beh of parser is
type PARSER_STATE is (SIDLE, SREAD_NEWNUMBER, SREAD_NEXTBYTE,
- SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1, SCALC_2, SWRITE_CHAR1, SWRITE_CHAR2, SDONE);
+ SREAD_CALCNUMBER1, SREAD_CALCNUMBER2, SCALC_1, SCALC_14, SCALC_15, SCALC_2, SWRITE_CHAR1,
+ SWRITE_CHAR2, SDONE, SERROR1, SERROR2);
signal state_int, state_next : PARSER_STATE;
signal z_int, z_next, strich_int, strich_next, wtmp_int, wtmp_next : csigned;
+ signal punkt_int, punkt_next : csigned;
signal rbyte_int, rbyte_next : hbyte;
signal p_write_int, p_write_next : hbyte;
signal p_rget_int, p_rget_next : std_logic;
state_int <= SIDLE;
z_int <= (others => '0');
strich_int <= (others => '0');
+ punkt_int <= (others => '0');
wtmp_int <= (others => '0');
rbyte_int <= (others => '0');
aktop_int <= ALU_NOP;
state_int <= state_next;
z_int <= z_next;
strich_int <= strich_next;
+ punkt_int <= punkt_next;
wtmp_int <= wtmp_next;
rbyte_int <= rbyte_next;
aktop_int <= aktop_next;
-- next state
process(state_int, do_it, p_rdone, p_wdone, p_read, aktop_int, strich_int,
- strich_next, calc_done, wtmp_int)
+ punkt_int, calc_done, wtmp_int, opp_int)
begin
state_next <= state_int;
state_next <= SREAD_NEXTBYTE;
end if;
when SCALC_1 =>
+ if calc_done = '1' then
+ case opp_int is
+ 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 =>
+ if calc_done = '0' then
+ state_next <= SCALC_15;
+ end if;
+ when SCALC_15 =>
if calc_done = '1' then
state_next <= SCALC_2;
end if;
state_next <= SWRITE_CHAR2;
end if;
end if;
- when SWRITE_CHAR2 =>
+ when SERROR1 =>
+ if p_wdone = '1' then
+ -- TODO
+ if strich_int < 10 then
+ state_next <= SDONE;
+ else
+ state_next <= SWRITE_CHAR2;
+ end if;
+ end if;
+ when SWRITE_CHAR2 | SERROR2 =>
if p_wdone = '0' then
state_next <= SWRITE_CHAR1;
end if;
-- out
process(state_int, p_read, p_write_int, z_int, rbyte_int, p_rget_int,
strich_int, aktop_int, opp_int, opcode_int, op1_int, op2_int, op3,
- do_calc_int, wtmp_int)
+ do_calc_int, wtmp_int, punkt_int)
function hbyte2csigned (x : hbyte) return csigned is
variable y : csigned;
begin
-- internal
z_next <= z_int;
strich_next <= strich_int;
+ punkt_next <= punkt_int;
wtmp_next <= wtmp_int;
rbyte_next <= rbyte_int;
aktop_next <= aktop_int;
case state_int is
when SIDLE =>
strich_next <= (others => '0');
+ punkt_next <= (0 => '1', others => '0');
opp_next <= ALU_NOP;
when SREAD_NEWNUMBER =>
z_next <= (others => '0');
-- '+'
when x"2B" =>
aktop_next <= ALU_ADD;
+ -- '-'
+ when x"2D" =>
+ -- TODO: sign check beim ersten byte lesen!
+ aktop_next <= ALU_SUB;
+ -- '*'
+ when x"2A" =>
+ aktop_next <= ALU_MUL;
+ -- '/'
+ when x"2F" =>
+ aktop_next <= ALU_DIV;
-- '\0'
when x"00" =>
when SCALC_1 =>
case opp_int is
- when ALU_NOP | ALU_ADD =>
- op1_next <= z_int;
+ when ALU_NOP | ALU_ADD | ALU_SUB =>
+ case opp_int is
+ when ALU_SUB => op1_next <= (not z_int) + 1;
+ when others => op1_next <= z_int;
+ end case;
case aktop_int is
- when ALU_ADD | ALU_SUB | ALU_NOP | ALU_DONE =>
+ 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 =>
+ op2_next <= z_int;
+ opcode_next <= opp_int;
+ op1_next <= punkt_int;
+ when ALU_MUL | ALU_DIV =>
+ op2_next <= z_int;
+ opcode_next <= opp_int;
+ op1_next <= punkt_int;
+ 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';
+
+ when SCALC_14 =>
+ case opp_int is
+ when ALU_MUL | ALU_DIV =>
+ case aktop_int is
+ when ALU_ADD | ALU_SUB | ALU_DONE =>
+ op1_next <= op3;
+ do_calc_next <= '0';
+ when others => assert(false) report("SCALC_14/1: bla!");
+ end case;
+ when others => assert(false) report("SCALC_14/2: bla!");
+ end case;
+
+ when SCALC_15 =>
+ case opp_int is
+ when ALU_MUL | ALU_DIV =>
+ case aktop_int is
+ when ALU_ADD | ALU_SUB | ALU_DONE =>
+ opcode_next <= ALU_ADD;
op2_next <= strich_int;
- when others => assert(false) report "SCALC_1/ALU_NOP: not implemented yet";
+ punkt_next <= (0 => '1', others => '0');
+ do_calc_next <= '1';
+ when others => assert(false) report("SCALC_15/1: bla!");
end case;
- do_calc_next <= '1';
- when others => assert(false) report "SCALC_1: not implemented yet";
+ when others => assert(false) report("SCALC_15/2: bla!");
end case;
+
when SCALC_2 =>
case opp_int is
- when ALU_NOP | ALU_ADD =>
- strich_next <= op3;
- when others => assert (false) report "SCALC_2: not implemented yet";
+ when ALU_NOP | ALU_ADD | ALU_SUB =>
+ case aktop_int is
+ when ALU_ADD | ALU_SUB | ALU_DONE =>
+ strich_next <= op3;
+ when ALU_MUL | ALU_DIV =>
+ punkt_next <= op3;
+ when others => assert (false) report "SCALC_2/1: shouldn't happen!";
+ end case;
+ when ALU_MUL | ALU_DIV =>
+ case aktop_int is
+ when ALU_ADD | ALU_SUB | ALU_DONE =>
+ strich_next <= op3;
+ when ALU_MUL | ALU_DIV =>
+ punkt_next <= op3;
+ when others => assert(false) report "SCALC_2/2: shouldn't happen!";
+ end case;
+ when others => assert (false) report "SCALC_2/3: shouldn't happen!";
end case;
+
opp_next <= aktop_int;
when SWRITE_CHAR1 =>
when SWRITE_CHAR2 =>
strich_next <= wtmp_int;
+ when SERROR1 =>
+ -- TODO
+ null;
+ when SERROR2 =>
+ -- TODO
+ null;
+
when SDONE =>
p_finished_next <= '1';
end case;