diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-09-08 08:00:42 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-09-11 06:37:27 +0200 |
commit | 1e1eab735ecad00ee663a68e3a5118e041c20739 (patch) | |
tree | 2fe36697581fd0b4e8499f3bacd2322a1cb53ae1 /src/synth/synth-expr.adb | |
parent | 67333b39047b444ea93f1efcabf7ea7b0371a972 (diff) | |
download | ghdl-1e1eab735ecad00ee663a68e3a5118e041c20739.tar.gz ghdl-1e1eab735ecad00ee663a68e3a5118e041c20739.tar.bz2 ghdl-1e1eab735ecad00ee663a68e3a5118e041c20739.zip |
synth: Add width field in type_type record.
Diffstat (limited to 'src/synth/synth-expr.adb')
-rw-r--r-- | src/synth/synth-expr.adb | 109 |
1 files changed, 42 insertions, 67 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index d0abeec7b..b68637498 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -228,7 +228,7 @@ package body Synth.Expr is -- Resize for a discrete value. function Synth_Resize (Val : Value_Acc; W : Width; Loc : Node) return Net is - Wn : constant Width := Val.Typ.Drange.W; + Wn : constant Width := Val.Typ.W; N : Net; Res : Net; begin @@ -547,49 +547,12 @@ package body Synth.Expr is end Vectorize_Array; function Synth_Discrete_Range_Expression - (L : Int64; R : Int64; Dir : Iir_Direction) return Discrete_Range_Type - is - V : Discrete_Range_Type; - Lo, Hi : Int64; + (L : Int64; R : Int64; Dir : Iir_Direction) return Discrete_Range_Type is begin - V.Dir := Dir; - V.Left := L; - V.Right := R; - - 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) + 1)); - 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; - return V; + return (Dir => Dir, + Left => L, + Right => R, + Is_Signed => L < 0 or R < 0); end Synth_Discrete_Range_Expression; function Synth_Discrete_Range_Expression @@ -605,8 +568,10 @@ package body Synth.Expr is raise Internal_Error; end if; - return Synth_Discrete_Range_Expression - (L.Scal, R.Scal, Get_Direction (Rng)); + return (Dir => Get_Direction (Rng), + Left => L.Scal, + Right => R.Scal, + Is_Signed => L.Scal < 0 or R.Scal < 0); end Synth_Discrete_Range_Expression; function Synth_Float_Range_Expression @@ -639,31 +604,40 @@ package body Synth.Expr is end if; end Synth_Array_Attribute; - function Synth_Discrete_Range (Syn_Inst : Synth_Instance_Acc; Bound : Node) - return Discrete_Range_Type is + procedure Synth_Discrete_Range (Syn_Inst : Synth_Instance_Acc; + Bound : Node; + Rng : out Discrete_Range_Type; + W : out Width) is begin case Get_Kind (Bound) is when Iir_Kind_Range_Expression => - return Synth_Discrete_Range_Expression (Syn_Inst, Bound); + Rng := Synth_Discrete_Range_Expression (Syn_Inst, Bound); + W := Discrete_Range_Width (Rng); when Iir_Kind_Integer_Subtype_Definition | Iir_Kind_Enumeration_Subtype_Definition => if Get_Type_Declarator (Bound) /= Null_Node then - -- This is a named subtype, so it has been evaluated. - return Get_Value_Type (Syn_Inst, Bound).Drange; + declare + Typ : Type_Acc; + begin + -- This is a named subtype, so it has been evaluated. + Typ := Get_Value_Type (Syn_Inst, Bound); + Rng := Typ.Drange; + W := Typ.W; + end; else - return Synth_Discrete_Range - (Syn_Inst, Get_Range_Constraint (Bound)); + Synth_Discrete_Range + (Syn_Inst, Get_Range_Constraint (Bound), Rng, W); end if; when Iir_Kind_Range_Array_Attribute => declare B : Bound_Type; begin B := Synth_Array_Attribute (Syn_Inst, Bound); - return Discrete_Range_Type'(Dir => B.Dir, + Rng := Discrete_Range_Type'(Dir => B.Dir, Is_Signed => True, - W => B.Wbounds, Left => Int64 (B.Left), Right => Int64 (B.Right)); + W := B.Wbounds; end; when others => Error_Kind ("synth_discrete_range", Bound); @@ -704,9 +678,10 @@ package body Synth.Expr is Atype : Node) return Bound_Type is Rng : Discrete_Range_Type; + W : Width; Len : Int64; begin - Rng := Synth_Discrete_Range (Syn_Inst, Atype); + Synth_Discrete_Range (Syn_Inst, Atype, Rng, W); case Rng.Dir is when Iir_To => Len := Rng.Right - Rng.Left + 1; @@ -718,7 +693,7 @@ package body Synth.Expr is end if; return (Dir => Rng.Dir, Wlen => Width (Clog2 (Uns64 (Len))), - Wbounds => Rng.W, + Wbounds => W, Left => Int32 (Rng.Left), Right => Int32 (Rng.Right), Len => Uns32 (Len)); end Synth_Bounds_From_Range; @@ -851,13 +826,14 @@ package body Synth.Expr is is Res : Bound_Type; Index_Bounds : Discrete_Range_Type; + W : Width; begin - Index_Bounds := Synth_Discrete_Range (Syn_Inst, Atype); + Synth_Discrete_Range (Syn_Inst, Atype, Index_Bounds, W); Res := (Left => Int32 (Index_Bounds.Left), Right => 0, Dir => Index_Bounds.Dir, - Wbounds => Index_Bounds.W, + Wbounds => W, Wlen => Width (Clog2 (Uns64 (Len))), Len => Uns32 (Len)); @@ -894,18 +870,17 @@ package body Synth.Expr is when Type_Discrete => pragma Assert (Vtype.Kind = Type_Discrete); declare - Vrng : Discrete_Range_Type renames Vtype.Drange; - Drng : Discrete_Range_Type renames Dtype.Drange; N : Net; begin - if Vrng.W > Drng.W then + if Vtype.W > Dtype.W then -- Truncate. -- TODO: check overflow. case Val.Kind is when Value_Net | Value_Wire => N := Get_Net (Val); - N := Build_Trunc (Build_Context, Id_Utrunc, N, Drng.W); + N := Build_Trunc + (Build_Context, Id_Utrunc, N, Dtype.W); Set_Location (N, Loc); return Create_Value_Net (N, Dtype); when Value_Discrete => @@ -913,7 +888,7 @@ package body Synth.Expr is when others => raise Internal_Error; end case; - elsif Vrng.W < Drng.W then + elsif Vtype.W < Dtype.W then -- Extend. case Val.Kind is when Value_Discrete => @@ -921,12 +896,12 @@ package body Synth.Expr is when Value_Net | Value_Wire => N := Get_Net (Val); - if Vrng.Is_Signed then + if Vtype.Drange.Is_Signed then N := Build_Extend - (Build_Context, Id_Sextend, N, Drng.W); + (Build_Context, Id_Sextend, N, Dtype.W); else N := Build_Extend - (Build_Context, Id_Uextend, N, Drng.W); + (Build_Context, Id_Uextend, N, Dtype.W); end if; Set_Location (N, Loc); return Create_Value_Net (N, Dtype); @@ -2261,7 +2236,7 @@ package body Synth.Expr is begin return Create_Value_Net (Synth_Uresize (Get_Net (Subprg_Inst.Objects (1)), - Nat_Type.Drange.W, Expr), + Nat_Type.W, Expr), Nat_Type); end; when Iir_Predefined_Ieee_Numeric_Std_Resize_Uns_Nat => |