Add Tercel PHY reset synchronization
[microwatt.git] / divider.vhdl
index cfadc5115e492ba5481fafd209b5938dbf0e6806..aef65a4362fb24de47b6fb66e6fdac70bd81bd3c 100644 (file)
@@ -5,14 +5,13 @@ use ieee.numeric_std.all;
 library work;
 use work.common.all;
 use work.decode_types.all;
-use work.crhelpers.all;
 
 entity divider is
     port (
         clk   : in std_logic;
         rst   : in std_logic;
-        d_in  : in Decode2ToDividerType;
-        d_out : out DividerToWritebackType
+        d_in  : in Execute1ToDividerType;
+        d_out : out DividerToExecute1Type
         );
 end entity divider;
 
@@ -21,24 +20,18 @@ architecture behaviour of divider is
     signal div        : unsigned(63 downto 0);
     signal quot       : std_ulogic_vector(63 downto 0);
     signal result     : std_ulogic_vector(63 downto 0);
-    signal sresult    : std_ulogic_vector(63 downto 0);
+    signal sresult    : std_ulogic_vector(64 downto 0);
     signal oresult    : std_ulogic_vector(63 downto 0);
-    signal qbit       : std_ulogic;
     signal running    : std_ulogic;
-    signal signcheck  : std_ulogic;
     signal count      : unsigned(6 downto 0);
     signal neg_result : std_ulogic;
     signal is_modulus : std_ulogic;
     signal is_32bit   : std_ulogic;
     signal extended   : std_ulogic;
     signal is_signed  : std_ulogic;
-    signal rc         : std_ulogic;
-    signal write_reg  : std_ulogic_vector(4 downto 0);
     signal overflow   : std_ulogic;
     signal ovf32      : std_ulogic;
     signal did_ovf    : std_ulogic;
-    signal cr_data    : std_ulogic_vector(2 downto 0);
-
 begin
     divider_0: process(clk)
     begin
@@ -50,38 +43,22 @@ begin
                 running <= '0';
                 count <= "0000000";
             elsif d_in.valid = '1' then
-                if d_in.is_extended = '1' and not (d_in.is_signed = '1' and d_in.dividend(63) = '1') then
+                if d_in.is_extended = '1'  then
                     dend <= '0' & d_in.dividend & x"0000000000000000";
                 else
                     dend <= '0' & x"0000000000000000" & d_in.dividend;
                 end if;
                 div <= unsigned(d_in.divisor);
                 quot <= (others => '0');
-                write_reg <= d_in.write_reg;
-                neg_result <= '0';
+                neg_result <= d_in.neg_result;
                 is_modulus <= d_in.is_modulus;
                 extended <= d_in.is_extended;
                 is_32bit <= d_in.is_32bit;
                 is_signed <= d_in.is_signed;
-                rc <= d_in.rc;
                 count <= "1111111";
                 running <= '1';
                 overflow <= '0';
                 ovf32 <= '0';
-                signcheck <= d_in.is_signed and (d_in.dividend(63) or d_in.divisor(63));
-            elsif signcheck = '1' then
-                signcheck <= '0';
-                neg_result <= dend(63) xor (div(63) and not is_modulus);
-                if dend(63) = '1' then
-                    if extended = '1' then
-                        dend <= '0' & std_ulogic_vector(- signed(dend(63 downto 0))) & x"0000000000000000";
-                    else
-                        dend <= '0' & x"0000000000000000" & std_ulogic_vector(- signed(dend(63 downto 0)));
-                    end if;
-                end if;
-                if div(63) = '1' then
-                    div <= unsigned(- signed(div));
-                end if;
             elsif running = '1' then
                 if count = "0111111" then
                     running <= '0';
@@ -113,22 +90,19 @@ begin
 
     divider_1: process(all)
     begin
-        d_out.write_reg_nr <= write_reg;
-        d_out.write_cr_mask <= num_to_fxm(0);
-
         if is_modulus = '1' then
             result <= dend(128 downto 65);
         else
             result <= quot;
         end if;
         if neg_result = '1' then
-            sresult <= std_ulogic_vector(- signed(result));
+            sresult <= std_ulogic_vector(- signed('0' & result));
         else
-            sresult <= result;
+            sresult <= '0' & result;
         end if;
         did_ovf <= '0';
         if is_32bit = '0' then
-            did_ovf <= overflow or (is_signed and (sresult(63) xor neg_result));
+            did_ovf <= overflow or (is_signed and (sresult(64) xor sresult(63)));
         elsif is_signed = '1' then
             if ovf32 = '1' or sresult(32) /= sresult(31) then
                 did_ovf <= '1';
@@ -142,31 +116,18 @@ begin
             -- 32-bit divisions set the top 32 bits of the result to 0
             oresult <= x"00000000" & sresult(31 downto 0);
         else
-            oresult <= sresult;
-        end if;
-
-        if (did_ovf = '1') or (or (sresult) = '0') then
-            cr_data <= "001";
-        elsif (sresult(63) = '1') and not ((is_32bit = '1') and (is_modulus = '0')) then
-            cr_data <= "100";
-        else
-            cr_data <= "010";
+            oresult <= sresult(63 downto 0);
         end if;
     end process;
 
     divider_out: process(clk)
     begin
         if rising_edge(clk) then
+           d_out.valid <= '0';
             d_out.write_reg_data <= oresult;
-            d_out.write_cr_data <= cr_data & '0' & x"0000000";
+           d_out.overflow <= did_ovf;
             if count = "1000000" then
                 d_out.valid <= '1';
-                d_out.write_reg_enable <= '1';
-                d_out.write_cr_enable <= rc;
-            else
-                d_out.valid <= '0';
-                d_out.write_reg_enable <= '0';
-                d_out.write_cr_enable <= '0';
             end if;
         end if;
     end process;