+ -- division implementiert nach ~hwmod/doc/division.pdf
+ if ((op1 = x"80000000" and op2 = to_signed(-1, CBITS)) or op2 = to_signed(0, CBITS)) then
+ error_intern <= '1';
+ else
+ -- sign check
+ op1_var := op1;
+ op2_var := op2;
+ if op1(CBITS-1) = '1' then
+ op1_var := (not op1_var) + 1;
+ end if;
+ if op2(CBITS-1) = '1' then
+ op2_var := (not op2_var) + 1;
+ end if;
+
+ dividend_msb_var := find_msb(op1_var)-1;
+ laengediv_var := find_msb(op2_var)-1;
+
+ aktdiv_int_next <= op1_var srl (dividend_msb_var - laengediv_var + 1);
+
+ div_go_calc <= '1';
+ dividend_msb_next <= dividend_msb_var;
+ laengediv_next <= laengediv_var;
+ quo_next <= (others => '0');
+ op1_next <= op1_var;
+ op2_next <= op2_var;
+ sign_next <= op1(CBITS-1) xor op2(CBITS-1);
+ end if;
+ when SDIV_CALC =>
+ if (dividend_msb_int - laengediv_int + 1) > 0 then
+ aktdiv_int_var := aktdiv_int sll 1;
+ aktdiv_int_var(0) := op1_int(dividend_msb_int - laengediv_int);
+
+ quo_var := quo_int sll 1;
+ if aktdiv_int_var >= op2_int then
+ quo_var(0) := '1';
+ aktdiv_int_var := aktdiv_int_var - op2_int;
+ end if;
+
+ quo_next <= quo_var;
+ aktdiv_int_next <= aktdiv_int_var;
+ dividend_msb_next <= dividend_msb_int;
+ laengediv_next <= laengediv_int + 1;
+ op1_next <= op1_int;
+ op2_next <= op2_int;
+ sign_next <= sign_int;
+ else
+ if sign_int = '1' then
+ quo_next <= (not quo_int) + 1;
+ else
+ quo_next <= quo_int;
+ end if;
+ div_calc_done <= '1';
+ end if;
+ when SDIV_DONE =>
+ op3_next <= quo_int;