diff options
-rw-r--r-- | src/synth/synth-context.adb | 6 | ||||
-rw-r--r-- | src/synth/synth-expr.adb | 45 | ||||
-rw-r--r-- | src/synth/synth-types.adb | 37 | ||||
-rw-r--r-- | src/synth/synth-types.ads | 6 | ||||
-rw-r--r-- | src/synth/synth-values.ads | 6 |
5 files changed, 52 insertions, 48 deletions
diff --git a/src/synth/synth-context.adb b/src/synth/synth-context.adb index e4c0436e8..67ed96f3f 100644 --- a/src/synth/synth-context.adb +++ b/src/synth/synth-context.adb @@ -122,15 +122,13 @@ package body Synth.Context is when Iir_Kind_Integer_Subtype_Definition => declare Rng : Value_Acc; - W : Width; Bnd : Value_Bound_Acc; begin Rng := Get_Value (Syn_Inst, Obj_Type); - W := Get_Range_Width (Rng.Rng); Bnd := Create_Value_Bound ((Dir => Iir_Downto, - Left => Int32 (W - 1), + Left => Int32 (Rng.Rng.W - 1), Right => 0, - Len => W)); + Len => Rng.Rng.W)); return Alloc_Wire (Kind, Obj, Bnd); end; when others => diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index 74b07b446..f16dc1990 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -22,6 +22,7 @@ with Ada.Unchecked_Conversion; with Types_Utils; use Types_Utils; with Std_Names; with Str_Table; +with Mutils; use Mutils; with Vhdl.Ieee.Std_Logic_1164; use Vhdl.Ieee.Std_Logic_1164; with Vhdl.Std_Package; with Vhdl.Errors; use Vhdl.Errors; @@ -426,7 +427,49 @@ package body Synth.Expr is Error_Msg_Synth (+Rng, "limits of range are not constant"); return null; end if; - Res := Create_Value_Range ((Get_Direction (Rng), L.Scal, R.Scal)); + declare + V : Value_Range_Type; + Lo, Hi : Int64; + begin + V.Dir := Get_Direction (Rng); + V.Left := L.Scal; + V.Right := R.Scal; + + case V.Dir is + when Iir_To => + Lo := V.Left; + Hi := V.Right; + when Iir_Downto => + Lo := V.Right; + Hi := V.Left; + end case; + if Lo > Hi then + -- Null range. + V.Is_Signed := False; + V.W := 0; + elsif Lo >= 0 then + -- Positive. + V.Is_Signed := False; + V.W := Width (Clog2 (Uns64 (Hi))); + elsif Lo = Int64'First then + -- Handle possible overflow. + V.Is_Signed := True; + V.W := 64; + elsif Hi < 0 then + -- Negative only. + V.Is_Signed := True; + V.W := Width (Clog2 (Uns64 (-Lo))) + 1; + else + declare + Wl : constant Width := Width (Clog2 (Uns64 (-Lo))); + Wh : constant Width := Width (Clog2 (Uns64 (Hi))); + begin + V.Is_Signed := True; + V.W := Width'Max (Wl, Wh) + 1; + end; + end if; + Res := Create_Value_Range (V); + end; when Iir_Kind_Floating_Type_Definition | Iir_Kind_Floating_Subtype_Definition => Res := Create_Value_Fp_Range ((Get_Direction (Rng), L.Fp, R.Fp)); diff --git a/src/synth/synth-types.adb b/src/synth/synth-types.adb index cbccbb628..df1712ac2 100644 --- a/src/synth/synth-types.adb +++ b/src/synth/synth-types.adb @@ -18,8 +18,6 @@ -- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, -- MA 02110-1301, USA. -with Types; use Types; -with Mutils; use Mutils; with Vhdl.Std_Package; with Vhdl.Ieee.Std_Logic_1164; with Vhdl.Utils; use Vhdl.Utils; @@ -49,39 +47,4 @@ package body Synth.Types is return Is_Bit_Type (Get_Element_Subtype (Atype)) and then Get_Nbr_Dimensions (Atype) = 1; end Is_Vector_Type; - - function Get_Range_Width (Rng : Value_Range_Type) return Width - is - Low : Int64; - High : Int64; - begin - case Rng.Dir is - when Iir_To => - Low := Rng.Left; - High := Rng.Right; - when Iir_Downto => - Low := Rng.Right; - High := Rng.Left; - end case; - if Low > High then - return 0; - end if; - - if Low >= 0 then - -- Positive. - return Width (Clog2 (Uns64 (High))); - elsif High < 0 then - -- Negative only. - -- FIXME: overflow. - return Width (Clog2 (Uns64 (-Low))) + 1; - else - declare - -- FIXME: overflow. - L : constant Width := Width (Clog2 (Uns64 (-Low))); - H : constant Width := Width (Clog2 (Uns64 (-High))); - begin - return Width'Max (L, H) + 1; - end; - end if; - end Get_Range_Width; end Synth.Types; diff --git a/src/synth/synth-types.ads b/src/synth/synth-types.ads index e82ece9bd..0212ad609 100644 --- a/src/synth/synth-types.ads +++ b/src/synth/synth-types.ads @@ -18,8 +18,6 @@ -- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, -- MA 02110-1301, USA. -with Netlists; use Netlists; -with Synth.Values; use Synth.Values; with Vhdl.Nodes; use Vhdl.Nodes; package Synth.Types is @@ -27,8 +25,4 @@ package Synth.Types is function Is_Bit_Type (Atype : Node) return Boolean; function Is_Vector_Type (Atype : Node) return Boolean; - - -- Number of bits for RNG. - function Get_Range_Width (Rng : Value_Range_Type) return Width; - end Synth.Types; diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads index 357bd1006..21eeaf0c2 100644 --- a/src/synth/synth-values.ads +++ b/src/synth/synth-values.ads @@ -79,7 +79,13 @@ package Synth.Values is type Value_Array_Acc is access Value_Array_Type; type Value_Range_Type is record + -- An integer range. Dir : Iir_Direction; + + -- Netlist representation: signed or unsigned, width of bus. + Is_Signed : Boolean; + W : Width; + Left : Int64; Right : Int64; end record; |