aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-07-26 08:17:49 +0200
committerTristan Gingold <tgingold@free.fr>2019-07-26 08:17:49 +0200
commit8ce1e4436be4207273b39ff6ba6946226eb91de2 (patch)
treef73baf375cc50900b3640537a3d34ff874ffd9d4 /src
parent2075f8cf5995bc83a8edc07456331b5b0f5b6be1 (diff)
downloadghdl-8ce1e4436be4207273b39ff6ba6946226eb91de2.tar.gz
ghdl-8ce1e4436be4207273b39ff6ba6946226eb91de2.tar.bz2
ghdl-8ce1e4436be4207273b39ff6ba6946226eb91de2.zip
synth: rework range.
Diffstat (limited to 'src')
-rw-r--r--src/synth/synth-context.adb6
-rw-r--r--src/synth/synth-expr.adb45
-rw-r--r--src/synth/synth-types.adb37
-rw-r--r--src/synth/synth-types.ads6
-rw-r--r--src/synth/synth-values.ads6
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;