alu: bessere find_msb, von 1295 auf 1054 logic cells (fuer alu)
[hwmod.git] / src / alu.vhd
index 014fc766c6f0210f219d1cddd57373cebc9c9304..9abd7da3c30b8e52cfcc2cd818cab9c3b9112255 100644 (file)
@@ -50,8 +50,8 @@ begin
                        calc_done_int <= '0';
                        calc_error_int <= '0';
                        --div
-                       dividend_msb_int <= 0;
-                       laengediv_int <= 0;
+                       dividend_msb_int <= (others => '0');
+                       laengediv_int <= (others => '0');
                        quo_int <= (others => '0');
                        aktdiv_int <= (others => '0');
                        op1_int <= (others => '0');
@@ -143,8 +143,8 @@ begin
                done_intern <= '0';
                error_intern <= '0';
                -- default fuer div
-               dividend_msb_next <= 0;
-               laengediv_next <= 0;
+               dividend_msb_next <= (others => '0');
+               laengediv_next <= (others => '0');
                quo_next <= (others => '0');
                aktdiv_int_next <= aktdiv_int;
                op1_next <= (others => '0');
@@ -210,12 +210,20 @@ begin
                                                op2_var := (not op2_var) + 1;
                                        end if;
 
-                                       dividend_msb_var := find_msb(op1_var)-1;
-                                       laengediv_var := find_msb(op2_var)-1;
+                                       dividend_msb_var := divinteger(find_msb(std_logic_vector(op1_var)))-1;
+                                       laengediv_var := divinteger(find_msb(std_logic_vector(op2_var)))-1;
 
-                                       aktdiv_int_next <= op1_var srl (dividend_msb_var - laengediv_var + 1);
+                                       aktdiv_int_next <= op1_var srl to_integer(dividend_msb_var - laengediv_var + 1);
 
-                                       if op1_var < op2_var then
+                                       -- anmerkung: xst (xilinx) kann folgende zeile nicht uebersetzen
+                                       -- > if op1 = to_signed(-2147483648, CBITS) then
+                                       -- darum folgende schreibweise ->
+                                       if op1 = x"80000000" then
+                                               -- so ziemlich das boeseste was passieren kann
+                                               div_calc_done2_int <= '1';
+                                               quo_next <= to_signed(-214748364,CBITS);
+                                               aktdiv_int_next <= to_signed(8,CBITS);
+                                       elsif (op1_var < op2_var) then
                                                div_calc_done2_int <= '1';
                                                quo_next <= to_signed(0,CBITS);
                                                aktdiv_int_next <= op1_var;
@@ -234,7 +242,7 @@ begin
 
                                if divtmp > 0 then
                                        aktdiv_int_var := aktdiv_int sll 1;
-                                       aktdiv_int_var(0) := op1_int(divtmp - 1);
+                                       aktdiv_int_var(0) := op1_int(to_integer(divtmp) - 1);
 
                                        quo_var := quo_int sll 1;
                                        if aktdiv_int_var >= op2_int then