diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/synth/synth-ieee-numeric_std.adb | 64 | ||||
| -rw-r--r-- | src/synth/synth-ieee-numeric_std.ads | 4 | ||||
| -rw-r--r-- | src/synth/synth-ieee-std_logic_1164.ads | 12 | ||||
| -rw-r--r-- | src/synth/synth-static_oper.adb | 19 | 
4 files changed, 87 insertions, 12 deletions
diff --git a/src/synth/synth-ieee-numeric_std.adb b/src/synth/synth-ieee-numeric_std.adb index 5319a3113..096e7fd9f 100644 --- a/src/synth/synth-ieee-numeric_std.adb +++ b/src/synth/synth-ieee-numeric_std.adb @@ -58,16 +58,16 @@ package body Synth.Ieee.Numeric_Std is           return Null_Vec;        end if;        Carry := '0'; -      for I in 1 .. Len loop -         if I > L'Last then +      for I in 0 .. Len - 1 loop +         if I >= L'Last then              Lb := '0';           else -            Lb := Sl_To_X01 (L (I)); +            Lb := Sl_To_X01 (L (L'Last - I));           end if; -         if I > R'Last then +         if I >= R'Last then              Rb := '0';           else -            Rb := Sl_To_X01 (R (I)); +            Rb := Sl_To_X01 (R (R'Last - I));           end if;           if Lb = 'X' or Rb = 'X' then              --assert NO_WARNING @@ -76,7 +76,7 @@ package body Synth.Ieee.Numeric_Std is              Res := (others => 'X');              exit;           end if; -         Res (I) := Compute_Sum (Carry, Rb, Lb); +         Res (Res'Last - I) := Compute_Sum (Carry, Rb, Lb);           Carry := Compute_Carry (Carry, Rb, Lb);        end loop;        return Res; @@ -86,9 +86,8 @@ package body Synth.Ieee.Numeric_Std is                          return Std_Logic_Vector     is        pragma Assert (L'First = 1); -      subtype Res_Type is Std_Logic_Vector (1 .. L'Last); +      Res : Std_Logic_Vector (1 .. L'Last);        V : Uns64; -      Res : Res_Type;        Lb, Rb, Carry : Sl_X01;     begin        if L'Last < 1 then @@ -96,7 +95,7 @@ package body Synth.Ieee.Numeric_Std is        end if;        V := To_Uns64 (R);        Carry := '0'; -      for I in Res'Range loop +      for I in reverse Res'Range loop           Lb := Sl_To_X01 (L (I));           Rb := Uns_To_01 (V and 1);           if Lb = 'X' then @@ -117,9 +116,8 @@ package body Synth.Ieee.Numeric_Std is                          return Std_Logic_Vector     is        pragma Assert (L'First = 1); -      subtype Res_Type is Std_Logic_Vector (1 .. L'Last); +      Res : Std_Logic_Vector (1 .. L'Last);        V : Uns64; -      Res : Res_Type;        Lb, Rb, Carry : Sl_X01;     begin        if L'Last < 1 then @@ -127,7 +125,7 @@ package body Synth.Ieee.Numeric_Std is        end if;        V := R;        Carry := '0'; -      for I in Res'Range loop +      for I in reverse Res'Range loop           Lb := Sl_To_X01 (L (I));           Rb := Uns_To_01 (V and 1);           if Lb = 'X' then @@ -143,4 +141,46 @@ package body Synth.Ieee.Numeric_Std is        end loop;        return Res;     end Add_Uns_Nat; + +   function Mul_Uns_Uns (L, R : Std_Logic_Vector) return Std_Logic_Vector +   is +      pragma Assert (L'First = 1); +      pragma Assert (R'First = 1); +      Len : constant Integer := L'Last + R'Last; +      Res : Std_Logic_Vector (1 .. Len); +      Lb, Rb, Vb, Carry : Sl_X01; +   begin +      if L'Last < 1 or R'Last < 1 then +         return Null_Vec; +      end if; +      Res := (others => '0'); +      --  Shift and add L. +      for I in 0 .. R'Last - 1 loop +         Rb := Sl_To_X01 (R (R'Last - I)); +         if Rb = '1' then +            --  Compute res := res + shift_left (l, i). +            Carry := '0'; +            for J in 0 .. L'Last - 1 loop +               Lb := L (L'Last - J); +               Vb := Res (Len - (I + J)); +               Res (Len - (I + J)) := Compute_Sum (Carry, Vb, Lb); +               Carry := Compute_Carry (Carry, Vb, Lb); +            end loop; +            --  Propagate carry. +            for J in I + L'Last .. Res'Last loop +               exit when Carry = '0'; +               Vb := Res (Len - J); +               Res (Len - J) := Xor_Table (Carry, Vb); +               Carry := And_Table (Carry, Vb); +            end loop; +         elsif Rb = 'X' then +            null; +            -- assert NO_WARNING +            --  report "NUMERIC_STD.""*"": non logical value detected" +            --  severity warning; +         end if; +      end loop; +      return Res; +   end Mul_Uns_Uns; +  end Synth.Ieee.Numeric_Std; diff --git a/src/synth/synth-ieee-numeric_std.ads b/src/synth/synth-ieee-numeric_std.ads index 340dac3d6..3d9b8be0b 100644 --- a/src/synth/synth-ieee-numeric_std.ads +++ b/src/synth/synth-ieee-numeric_std.ads @@ -23,10 +23,14 @@ with Types; use Types;  with Synth.Ieee.Std_Logic_1164; use Synth.Ieee.Std_Logic_1164;  package Synth.Ieee.Numeric_Std is +   --  Reminder: vectors elements are from left to right. +     function Add_Uns_Uns (L, R : Std_Logic_Vector) return Std_Logic_Vector;     function Add_Sgn_Int (L : Std_Logic_Vector; R : Int64)                          return Std_Logic_Vector;     function Add_Uns_Nat (L : Std_Logic_Vector; R : Uns64)                          return Std_Logic_Vector; + +   function Mul_Uns_Uns (L, R : Std_Logic_Vector) return Std_Logic_Vector;  end Synth.Ieee.Numeric_Std; diff --git a/src/synth/synth-ieee-std_logic_1164.ads b/src/synth/synth-ieee-std_logic_1164.ads index c90e4e5ca..242a417fb 100644 --- a/src/synth/synth-ieee-std_logic_1164.ads +++ b/src/synth/synth-ieee-std_logic_1164.ads @@ -67,4 +67,16 @@ package Synth.Ieee.Std_Logic_1164 is        "UXX1XXX1X"    -- -       ); +   Xor_Table : constant Table_2d := +   --  UX01ZWLH- +     ("UUUUUUUUU",   -- U +      "UXXXXXXXX",   -- X +      "UX01XX01X",   -- 0 +      "UX10XX10X",   -- 1 +      "UXXXXXXXX",   -- Z +      "UXXXXXXXX",   -- W +      "UX01XX01X",   -- L +      "UX10XX10X",   -- H +      "UXXXXXXXX"    -- - +     );  end Synth.Ieee.Std_Logic_1164; diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb index 645456db0..76c653329 100644 --- a/src/synth/synth-static_oper.adb +++ b/src/synth/synth-static_oper.adb @@ -138,6 +138,22 @@ package body Synth.Static_Oper is        end;     end Synth_Add_Uns_Nat; +   function Synth_Mul_Uns_Uns (L, R : Value_Acc; Loc : Syn_Src) +                              return Value_Acc +   is +      pragma Unreferenced (Loc); +      L_Arr : Std_Logic_Vector (1 .. Natural (L.Arr.Len)); +      R_Arr : Std_Logic_Vector (1 .. Natural (R.Arr.Len)); +   begin +      To_Std_Logic_Vector (L, L_Arr); +      To_Std_Logic_Vector (R, R_Arr); +      declare +         Res_Arr : constant Std_Logic_Vector := Mul_Uns_Uns (L_Arr, R_Arr); +      begin +         return To_Value_Acc (Res_Arr, L.Typ.Vec_El); +      end; +   end Synth_Mul_Uns_Uns; +     function Synth_Static_Dyadic_Predefined (Syn_Inst : Synth_Instance_Acc;                                              Imp : Node;                                              Left : Value_Acc; @@ -242,6 +258,9 @@ package body Synth.Static_Oper is           when Iir_Predefined_Ieee_Numeric_Std_Add_Uns_Nat =>              return Synth_Add_Uns_Nat (Left, Right, Expr); +         when Iir_Predefined_Ieee_Numeric_Std_Mul_Uns_Uns => +            return Synth_Mul_Uns_Uns (Left, Right, Expr); +           when others =>              Error_Msg_Synth                (+Expr, "synth_static_dyadic_predefined: unhandled "  | 
