aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-04-03 08:46:23 +0200
committerTristan Gingold <tgingold@free.fr>2020-04-06 20:10:55 +0200
commitbeb01818f52362329556f663dcb176747f8cbb89 (patch)
treedd215b972b59a6fccf9b9bf1217d52129e763253 /src/synth
parent84e332e02c1903b110d3141934184ed5a0906db4 (diff)
downloadghdl-beb01818f52362329556f663dcb176747f8cbb89.tar.gz
ghdl-beb01818f52362329556f663dcb176747f8cbb89.tar.bz2
ghdl-beb01818f52362329556f663dcb176747f8cbb89.zip
synth: add value_memory and use it to store objects value.
Diffstat (limited to 'src/synth')
-rw-r--r--src/synth/synth-aggr.adb433
-rw-r--r--src/synth/synth-aggr.ads30
-rw-r--r--src/synth/synth-context.adb102
-rw-r--r--src/synth/synth-decls.adb41
-rw-r--r--src/synth/synth-disp_vhdl.adb4
-rw-r--r--src/synth/synth-expr.adb829
-rw-r--r--src/synth/synth-expr.ads12
-rw-r--r--src/synth/synth-files_operations.adb19
-rw-r--r--src/synth/synth-heap.adb72
-rw-r--r--src/synth/synth-insts.adb67
-rw-r--r--src/synth/synth-oper.adb31
-rw-r--r--src/synth/synth-static_oper.adb295
-rw-r--r--src/synth/synth-static_proc.adb4
-rw-r--r--src/synth/synth-stmts.adb259
-rw-r--r--src/synth/synth-stmts.ads7
-rw-r--r--src/synth/synth-values.adb792
-rw-r--r--src/synth/synth-values.ads185
17 files changed, 1654 insertions, 1528 deletions
diff --git a/src/synth/synth-aggr.adb b/src/synth/synth-aggr.adb
new file mode 100644
index 000000000..25f32cacd
--- /dev/null
+++ b/src/synth/synth-aggr.adb
@@ -0,0 +1,433 @@
+-- Aggregates synthesis.
+-- Copyright (C) 2020 Tristan Gingold
+--
+-- This file is part of GHDL.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 2 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+-- MA 02110-1301, USA.
+
+with Types; use Types;
+
+with Netlists; use Netlists;
+with Netlists.Utils; use Netlists.Utils;
+
+with Vhdl.Errors; use Vhdl.Errors;
+
+with Synth.Errors; use Synth.Errors;
+with Synth.Expr; use Synth.Expr;
+with Synth.Stmts; use Synth.Stmts;
+with Synth.Decls; use Synth.Decls;
+
+package body Synth.Aggr is
+ type Stride_Array is array (Dim_Type range <>) of Nat32;
+
+ function Get_Index_Offset
+ (Index : Int64; Bounds : Bound_Type; Expr : Iir) return Uns32
+ is
+ Left : constant Int64 := Int64 (Bounds.Left);
+ Right : constant Int64 := Int64 (Bounds.Right);
+ begin
+ case Bounds.Dir is
+ when Iir_To =>
+ if Index >= Left and then Index <= Right then
+ -- to
+ return Uns32 (Index - Left);
+ end if;
+ when Iir_Downto =>
+ if Index <= Left and then Index >= Right then
+ -- downto
+ return Uns32 (Left - Index);
+ end if;
+ end case;
+ Error_Msg_Synth (+Expr, "index out of bounds");
+ return 0;
+ end Get_Index_Offset;
+
+ function Get_Index_Offset
+ (Index : Valtyp; Bounds : Bound_Type; Expr : Iir) return Uns32 is
+ begin
+ return Get_Index_Offset (Read_Discrete (Index), Bounds, Expr);
+ end Get_Index_Offset;
+
+ function Fill_Stride (Typ : Type_Acc) return Stride_Array is
+ begin
+ case Typ.Kind is
+ when Type_Vector =>
+ return (1 => 1);
+ when Type_Array =>
+ declare
+ Bnds : constant Bound_Array_Acc := Typ.Abounds;
+ Res : Stride_Array (1 .. Bnds.Ndim);
+ Stride : Nat32;
+ begin
+ Stride := 1;
+ for I in reverse 2 .. Bnds.Ndim loop
+ Res (Dim_Type (I)) := Stride;
+ Stride := Stride * Nat32 (Bnds.D (I).Len);
+ end loop;
+ Res (1) := Stride;
+ return Res;
+ end;
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Fill_Stride;
+
+ procedure Fill_Array_Aggregate (Syn_Inst : Synth_Instance_Acc;
+ Aggr : Node;
+ Res : Valtyp_Array_Acc;
+ Typ : Type_Acc;
+ First_Pos : Nat32;
+ Strides : Stride_Array;
+ Dim : Dim_Type;
+ Const_P : out Boolean)
+ is
+ Bound : constant Bound_Type := Get_Array_Bound (Typ, Dim);
+ El_Typ : constant Type_Acc := Get_Array_Element (Typ);
+ Stride : constant Nat32 := Strides (Dim);
+ Value : Node;
+ Assoc : Node;
+
+ procedure Set_Elem (Pos : Nat32)
+ is
+ Sub_Const : Boolean;
+ Val : Valtyp;
+ begin
+ if Dim = Strides'Last then
+ Val := Synth_Expression_With_Type (Syn_Inst, Value, El_Typ);
+ Val := Synth_Subtype_Conversion (Val, El_Typ, False, Value);
+ pragma Assert (Res (Pos) = No_Valtyp);
+ Res (Pos) := Val;
+ if Const_P and then not Is_Static (Val.Val) then
+ Const_P := False;
+ end if;
+ else
+ Fill_Array_Aggregate
+ (Syn_Inst, Value, Res, Typ, Pos, Strides, Dim + 1, Sub_Const);
+ if not Sub_Const then
+ Const_P := False;
+ end if;
+ end if;
+ end Set_Elem;
+
+ procedure Set_Vector (Pos : Nat32; Len : Nat32; Val : Valtyp) is
+ begin
+ pragma Assert (Dim = Strides'Last);
+ if Len = 0 then
+ return;
+ end if;
+ pragma Assert (Res (Pos) = No_Valtyp);
+ Res (Pos) := Val;
+
+ -- Mark following slots as busy so that 'others => x' won't fill
+ -- them.
+ for I in 2 .. Len loop
+ Res (Pos + I - 1).Typ := Val.Typ;
+ end loop;
+
+ if Const_P and then not Is_Static (Val.Val) then
+ Const_P := False;
+ end if;
+ end Set_Vector;
+
+ Pos : Nat32;
+ begin
+ Assoc := Get_Association_Choices_Chain (Aggr);
+ Pos := First_Pos;
+ Const_P := True;
+ while Is_Valid (Assoc) loop
+ Value := Get_Associated_Expr (Assoc);
+ loop
+ case Get_Kind (Assoc) is
+ when Iir_Kind_Choice_By_None =>
+ if Get_Element_Type_Flag (Assoc) then
+ if Pos >= First_Pos + Stride * Nat32 (Bound.Len) then
+ Error_Msg_Synth (+Assoc, "element out of array bound");
+ else
+ Set_Elem (Pos);
+ Pos := Pos + Stride;
+ end if;
+ else
+ declare
+ Val : Valtyp;
+ Val_Len : Uns32;
+ begin
+ Val := Synth_Expression_With_Basetype
+ (Syn_Inst, Value);
+ Val_Len := Get_Bound_Length (Val.Typ, 1);
+ pragma Assert (Stride = 1);
+ if Pos - First_Pos > Nat32 (Bound.Len - Val_Len) then
+ Error_Msg_Synth
+ (+Assoc, "element out of array bound");
+ else
+ Set_Vector (Pos, Nat32 (Val_Len), Val);
+ Pos := Pos + Nat32 (Val_Len);
+ end if;
+ end;
+ end if;
+ when Iir_Kind_Choice_By_Others =>
+ pragma Assert (Get_Element_Type_Flag (Assoc));
+ declare
+ Last_Pos : constant Nat32 :=
+ First_Pos + Nat32 (Bound.Len) * Stride;
+ begin
+ while Pos < Last_Pos loop
+ if Res (Pos) = No_Valtyp then
+ -- FIXME: the check is not correct if there is
+ -- an array.
+ Set_Elem (Pos);
+ end if;
+ Pos := Pos + Stride;
+ end loop;
+ end;
+ when Iir_Kind_Choice_By_Expression =>
+ pragma Assert (Get_Element_Type_Flag (Assoc));
+ declare
+ Ch : constant Node := Get_Choice_Expression (Assoc);
+ Idx : Valtyp;
+ Off : Nat32;
+ begin
+ Idx := Synth_Expression (Syn_Inst, Ch);
+ if not Is_Static (Idx.Val) then
+ Error_Msg_Synth (+Ch, "choice is not static");
+ else
+ Off := Nat32 (Get_Index_Offset (Idx, Bound, Ch));
+ Set_Elem (First_Pos + Off * Stride);
+ end if;
+ end;
+ when Iir_Kind_Choice_By_Range =>
+ declare
+ Ch : constant Node := Get_Choice_Range (Assoc);
+ Rng : Discrete_Range_Type;
+ Val : Valtyp;
+ Rng_Len : Width;
+ Off : Nat32;
+ begin
+ Synth_Discrete_Range (Syn_Inst, Ch, Rng);
+ if Get_Element_Type_Flag (Assoc) then
+ Val := Create_Value_Discrete
+ (Rng.Left,
+ Get_Subtype_Object (Syn_Inst,
+ Get_Base_Type (Get_Type (Ch))));
+ while In_Range (Rng, Read_Discrete (Val)) loop
+ Off := Nat32 (Get_Index_Offset (Val, Bound, Ch));
+ Set_Elem (First_Pos + Off * Stride);
+ Update_Index (Rng, Val);
+ end loop;
+ else
+ -- The direction must be the same.
+ if Rng.Dir /= Bound.Dir then
+ Error_Msg_Synth
+ (+Assoc, "direction of range does not match "
+ & "direction of array");
+ end if;
+ -- FIXME: can the expression be unbounded ?
+ Val := Synth_Expression_With_Basetype
+ (Syn_Inst, Value);
+ -- The length must match the range.
+ Rng_Len := Get_Range_Length (Rng);
+ if Get_Bound_Length (Val.Typ, 1) /= Rng_Len then
+ Error_Msg_Synth
+ (+Value, "length doesn't match range");
+ end if;
+ pragma Assert (Stride = 1);
+ Off := Nat32 (Get_Index_Offset (Rng.Left, Bound, Ch));
+ Set_Vector (First_Pos + Off, Nat32 (Rng_Len), Val);
+ end if;
+ end;
+ when others =>
+ Error_Msg_Synth
+ (+Assoc, "unhandled association form");
+ end case;
+ Assoc := Get_Chain (Assoc);
+ exit when Is_Null (Assoc);
+ exit when not Get_Same_Alternative_Flag (Assoc);
+ end loop;
+ end loop;
+ end Fill_Array_Aggregate;
+
+ procedure Fill_Record_Aggregate (Syn_Inst : Synth_Instance_Acc;
+ Aggr : Node;
+ Rec : Valtyp_Array_Acc;
+ Const_P : out Boolean)
+ is
+ El_List : constant Node_Flist :=
+ Get_Elements_Declaration_List (Get_Type (Aggr));
+ Value : Node;
+ Assoc : Node;
+ Pos : Nat32;
+
+ procedure Set_Elem (Pos : Nat32)
+ is
+ Val : Valtyp;
+ El_Type : Type_Acc;
+ begin
+ El_Type := Get_Subtype_Object
+ (Syn_Inst, Get_Type (Get_Nth_Element (El_List, Natural (Pos))));
+ Val := Synth_Expression_With_Type (Syn_Inst, Value, El_Type);
+ if Const_P and not Is_Static (Val.Val) then
+ Const_P := False;
+ end if;
+ Val := Synth_Subtype_Conversion (Val, El_Type, False, Value);
+ Rec (Nat32 (Pos + 1)) := Val;
+ end Set_Elem;
+ begin
+ Assoc := Get_Association_Choices_Chain (Aggr);
+ Pos := 0;
+ Const_P := True;
+ while Is_Valid (Assoc) loop
+ Value := Get_Associated_Expr (Assoc);
+ loop
+ case Get_Kind (Assoc) is
+ when Iir_Kind_Choice_By_None =>
+ Set_Elem (Pos);
+ Pos := Pos + 1;
+ when Iir_Kind_Choice_By_Others =>
+ for I in Rec'Range loop
+ if Rec (I) = No_Valtyp then
+ Set_Elem (I - 1);
+ end if;
+ end loop;
+ when Iir_Kind_Choice_By_Name =>
+ Pos := Nat32 (Get_Element_Position
+ (Get_Named_Entity
+ (Get_Choice_Name (Assoc))));
+ Set_Elem (Pos);
+ when others =>
+ Error_Msg_Synth
+ (+Assoc, "unhandled association form");
+ end case;
+ Assoc := Get_Chain (Assoc);
+ exit when Is_Null (Assoc);
+ exit when not Get_Same_Alternative_Flag (Assoc);
+ end loop;
+ end loop;
+ end Fill_Record_Aggregate;
+
+ function Valtyp_Array_To_Net (Tab : Valtyp_Array) return Net
+ is
+ Res : Net;
+ Arr : Net_Array_Acc;
+ Idx : Nat32;
+ begin
+ Arr := new Net_Array (Tab'Range);
+ Idx := 0;
+ for I in Arr'Range loop
+ if Tab (I).Val /= null then
+ Idx := Idx + 1;
+ Arr (Idx) := Get_Net (Tab (I));
+ end if;
+ end loop;
+ Concat_Array (Arr (1 .. Idx), Res);
+ Free_Net_Array (Arr);
+ return Res;
+ end Valtyp_Array_To_Net;
+
+ function Synth_Aggregate_Array (Syn_Inst : Synth_Instance_Acc;
+ Aggr : Node;
+ Aggr_Type : Type_Acc) return Valtyp
+ is
+ Strides : constant Stride_Array := Fill_Stride (Aggr_Type);
+ Flen : constant Iir_Index32 := Get_Array_Flat_Length (Aggr_Type);
+ Tab_Res : Valtyp_Array_Acc;
+ Const_P : Boolean;
+ Res : Valtyp;
+ begin
+ Tab_Res := new Valtyp_Array'(1 .. Nat32 (Flen) => No_Valtyp);
+
+ Fill_Array_Aggregate
+ (Syn_Inst, Aggr, Tab_Res, Aggr_Type, 1, Strides, 1, Const_P);
+
+ -- TODO: check all element types have the same bounds ?
+
+ if Const_P then
+ declare
+ Off : Size_Type;
+ begin
+ Res := Create_Value_Memory (Aggr_Type);
+ Off := 0;
+ for I in Tab_Res'Range loop
+ if Tab_Res (I).Val /= null then
+ -- There can be holes due to sub-arrays.
+ Write_Value (Res.Val.Mem + Off, Tab_Res (I));
+ Off := Off + Tab_Res (I).Typ.Sz;
+ end if;
+ end loop;
+ pragma Assert (Off = Aggr_Type.Sz);
+ end;
+ else
+ Res := Create_Value_Net
+ (Valtyp_Array_To_Net (Tab_Res.all), Aggr_Type);
+ end if;
+
+ Free_Valtyp_Array (Tab_Res);
+
+ return Res;
+ end Synth_Aggregate_Array;
+
+ function Synth_Aggregate_Record (Syn_Inst : Synth_Instance_Acc;
+ Aggr : Node;
+ Aggr_Type : Type_Acc) return Valtyp
+ is
+ Tab_Res : Valtyp_Array_Acc;
+ Res : Valtyp;
+ Const_P : Boolean;
+ begin
+ -- Allocate the result.
+ Tab_Res :=
+ new Valtyp_Array'(1 .. Nat32 (Aggr_Type.Rec.Len) => No_Valtyp);
+
+ Fill_Record_Aggregate (Syn_Inst, Aggr, Tab_Res, Const_P);
+
+ if Const_P then
+ Res := Create_Value_Memory (Aggr_Type);
+ for I in Aggr_Type.Rec.E'Range loop
+ Write_Value (Res.Val.Mem + Aggr_Type.Rec.E (I).Moff,
+ Tab_Res (Nat32 (I)));
+ end loop;
+ else
+ Res := Create_Value_Net
+ (Valtyp_Array_To_Net (Tab_Res.all), Aggr_Type);
+ end if;
+
+ Free_Valtyp_Array (Tab_Res);
+
+ return Res;
+ end Synth_Aggregate_Record;
+
+ -- Aggr_Type is the type from the context.
+ function Synth_Aggregate (Syn_Inst : Synth_Instance_Acc;
+ Aggr : Node;
+ Aggr_Type : Type_Acc) return Valtyp is
+ begin
+ case Aggr_Type.Kind is
+ when Type_Unbounded_Array | Type_Unbounded_Vector =>
+ declare
+ Res_Type : Type_Acc;
+ begin
+ Res_Type := Decls.Synth_Array_Subtype_Indication
+ (Syn_Inst, Get_Type (Aggr));
+ return Synth_Aggregate_Array (Syn_Inst, Aggr, Res_Type);
+ end;
+ when Type_Vector | Type_Array =>
+ return Synth_Aggregate_Array (Syn_Inst, Aggr, Aggr_Type);
+ when Type_Record =>
+ return Synth_Aggregate_Record (Syn_Inst, Aggr, Aggr_Type);
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Synth_Aggregate;
+
+end Synth.Aggr;
diff --git a/src/synth/synth-aggr.ads b/src/synth/synth-aggr.ads
new file mode 100644
index 000000000..5dd7e4bd7
--- /dev/null
+++ b/src/synth/synth-aggr.ads
@@ -0,0 +1,30 @@
+-- Aggregates synthesis.
+-- Copyright (C) 2020 Tristan Gingold
+--
+-- This file is part of GHDL.
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; either version 2 of the License, or
+-- (at your option) any later version.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+-- You should have received a copy of the GNU General Public License
+-- along with this program; if not, write to the Free Software
+-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+-- MA 02110-1301, USA.
+
+with Synth.Values; use Synth.Values;
+with Synth.Context; use Synth.Context;
+with Vhdl.Nodes; use Vhdl.Nodes;
+
+package Synth.Aggr is
+ -- Aggr_Type is the type from the context.
+ function Synth_Aggregate (Syn_Inst : Synth_Instance_Acc;
+ Aggr : Node;
+ Aggr_Type : Type_Acc) return Valtyp;
+end Synth.Aggr;
diff --git a/src/synth/synth-context.adb b/src/synth/synth-context.adb
index 9654ec02f..576be4987 100644
--- a/src/synth/synth-context.adb
+++ b/src/synth/synth-context.adb
@@ -21,7 +21,6 @@
with Ada.Unchecked_Deallocation;
with Types; use Types;
-with Types_Utils; use Types_Utils;
with Name_Table; use Name_Table;
with Vhdl.Errors; use Vhdl.Errors;
@@ -29,7 +28,6 @@ with Vhdl.Utils;
with Netlists.Builders; use Netlists.Builders;
with Netlists.Folds; use Netlists.Folds;
-with Netlists.Concats;
with Synth.Expr; use Synth.Expr;
with Netlists.Locations;
@@ -490,39 +488,29 @@ package body Synth.Context is
return Get_Current_Value (Build_Context, Val.Val.W);
when Value_Net =>
return Val.Val.N;
- when Value_Discrete =>
- case Val.Typ.Kind is
- when Type_Bit
- | Type_Logic =>
- declare
- V : Logvec_Array (0 .. 0) := (0 => (0, 0));
- Res : Net;
- begin
- Value2net (Val, 1, V, Res);
- return Res;
- end;
- when Type_Discrete =>
- if Val.Typ.W <= 64 then
- declare
- Sh : constant Natural := 64 - Natural (Val.Typ.W);
- V : Uns64;
- begin
- V := To_Uns64 (Val.Val.Scal);
- -- Keep only Val.Typ.W bits of the value.
- V := Shift_Right (Shift_Left (V, Sh), Sh);
- return Build2_Const_Uns
- (Build_Context, V, Val.Typ.W);
- end;
- else
- raise Internal_Error;
- end if;
- when others =>
- raise Internal_Error;
- end case;
- when Value_Const_Array
- | Value_Const_Record =>
+ when Value_Alias =>
declare
- W : constant Width := Get_Type_Width (Val.Typ);
+ Res : Net;
+ begin
+ if Val.Val.A_Obj.Kind = Value_Wire then
+ Res := Get_Current_Value (Build_Context, Val.Val.A_Obj.W);
+ return Build2_Extract
+ (Build_Context, Res, Val.Val.A_Off.Net_Off, Val.Typ.W);
+ else
+ pragma Assert (Val.Val.A_Off.Net_Off = 0);
+ return Get_Net ((Val.Typ, Val.Val.A_Obj));
+ end if;
+ end;
+ when Value_Const =>
+ if Val.Val.C_Net = No_Net then
+ Val.Val.C_Net := Get_Net ((Val.Typ, Val.Val.C_Val));
+ Locations.Set_Location (Get_Net_Parent (Val.Val.C_Net),
+ Get_Location (Val.Val.C_Loc));
+ end if;
+ return Val.Val.C_Net;
+ when Value_Memory =>
+ declare
+ W : constant Width := Val.Typ.W;
Nd : constant Digit_Index := Digit_Index ((W + 31) / 32);
Res : Net;
begin
@@ -544,52 +532,6 @@ package body Synth.Context is
end;
end if;
end;
- when Value_Array =>
- declare
- use Netlists.Concats;
- El_Typ : constant Type_Acc := Get_Array_Element (Val.Typ);
- C : Concat_Type;
- Res : Net;
- begin
- for I in reverse Val.Val.Arr.V'Range loop
- Append (C, Get_Net ((El_Typ, Val.Val.Arr.V (I))));
- end loop;
- Build (Build_Context, C, Res);
- return Res;
- end;
- when Value_Record =>
- declare
- use Netlists.Concats;
- C : Concat_Type;
- Res : Net;
- begin
- for I in Val.Typ.Rec.E'Range loop
- Append (C, Get_Net ((Val.Typ.Rec.E (I).Typ,
- Val.Val.Rec.V (I))));
- end loop;
- Build (Build_Context, C, Res);
- return Res;
- end;
- when Value_Alias =>
- declare
- Res : Net;
- begin
- if Val.Val.A_Obj.Kind = Value_Wire then
- Res := Get_Current_Value (Build_Context, Val.Val.A_Obj.W);
- return Build2_Extract (Build_Context, Res, Val.Val.A_Off,
- Val.Typ.W);
- else
- pragma Assert (Val.Val.A_Off = 0);
- return Get_Net ((Val.Typ, Val.Val.A_Obj));
- end if;
- end;
- when Value_Const =>
- if Val.Val.C_Net = No_Net then
- Val.Val.C_Net := Get_Net ((Val.Typ, Val.Val.C_Val));
- Locations.Set_Location (Get_Net_Parent (Val.Val.C_Net),
- Get_Location (Val.Val.C_Loc));
- end if;
- return Val.Val.C_Net;
when others =>
raise Internal_Error;
end case;
diff --git a/src/synth/synth-decls.adb b/src/synth/synth-decls.adb
index 2c32a7381..9c3ead57a 100644
--- a/src/synth/synth-decls.adb
+++ b/src/synth/synth-decls.adb
@@ -119,7 +119,6 @@ package body Synth.Decls is
Rec_Els : Rec_El_Array_Acc;
El : Node;
El_Typ : Type_Acc;
- Off : Uns32;
begin
if not Is_Fully_Constrained_Type (Def) then
return null;
@@ -127,16 +126,13 @@ package body Synth.Decls is
Rec_Els := Create_Rec_El_Array
(Iir_Index32 (Get_Nbr_Elements (El_List)));
- Off := 0;
for I in Flist_First .. Flist_Last (El_List) loop
El := Get_Nth_Element (El_List, I);
El_Typ := Get_Subtype_Object (Syn_Inst, Get_Type (El));
- Rec_Els.E (Iir_Index32 (I + 1)) := (Off => Off,
- Typ => El_Typ);
- Off := Off + Get_Type_Width (El_Typ);
+ Rec_Els.E (Iir_Index32 (I + 1)).Typ := El_Typ;
end loop;
- return Create_Record_Type (Rec_Els, Off);
+ return Create_Record_Type (Rec_Els);
end Synth_Record_Type_Definition;
function Synth_Access_Type_Definition
@@ -166,6 +162,20 @@ package body Synth.Decls is
return Typ;
end Synth_File_Type_Definition;
+ function Scalar_Size_To_Size (Def : Node) return Size_Type is
+ begin
+ case Get_Scalar_Size (Def) is
+ when Scalar_8 =>
+ return 1;
+ when Scalar_16 =>
+ return 2;
+ when Scalar_32 =>
+ return 4;
+ when Scalar_64 =>
+ return 8;
+ end case;
+ end Scalar_Size_To_Size;
+
procedure Synth_Type_Definition (Syn_Inst : Synth_Instance_Acc; Def : Node)
is
Typ : Type_Acc;
@@ -192,7 +202,8 @@ package body Synth.Decls is
Is_Signed => False,
Left => Int64 (Nbr_El - 1),
Right => 0);
- Typ := Create_Discrete_Type (Rng, W);
+ Typ := Create_Discrete_Type
+ (Rng, Scalar_Size_To_Size (Def), W);
end;
end if;
when Iir_Kind_Array_Type_Definition =>
@@ -231,7 +242,8 @@ package body Synth.Decls is
Rng := Synth_Discrete_Range_Expression
(L, R, Get_Direction (Cst));
W := Discrete_Range_Width (Rng);
- Typ := Create_Discrete_Type (Rng, W);
+ Typ := Create_Discrete_Type
+ (Rng, Scalar_Size_To_Size (Def), W);
end;
when Iir_Kind_Floating_Type_Definition =>
declare
@@ -366,7 +378,8 @@ package body Synth.Decls is
Rng := Synth_Discrete_Range_Constraint
(Syn_Inst, Get_Range_Constraint (Atype));
W := Discrete_Range_Width (Rng);
- return Create_Discrete_Type (Rng, W);
+ return
+ Create_Discrete_Type (Rng, Btype.Sz, W);
end if;
end;
when Iir_Kind_Floating_Subtype_Definition =>
@@ -719,8 +732,7 @@ package body Synth.Decls is
Error_Msg_Synth
(+Decl, "variable with access type is not synthesizable");
-- FIXME: use a poison value ?
- Create_Object (Syn_Inst, Decl,
- (Obj_Typ, Create_Value_Default (Obj_Typ)));
+ Create_Object (Syn_Inst, Decl, Create_Value_Default (Obj_Typ));
else
if Is_Valid (Def) then
Init := Synth_Expression_With_Type (Syn_Inst, Def, Obj_Typ);
@@ -729,7 +741,7 @@ package body Synth.Decls is
Init := Create_Value_Default (Obj_Typ);
end if;
if Get_Instance_Const (Syn_Inst) then
- Init.Val := Unshare (Init.Val, Current_Pool);
+ Init := Unshare (Init, Current_Pool);
Create_Object (Syn_Inst, Decl, Init);
else
Create_Wire_Object (Syn_Inst, Wire_Variable, Decl);
@@ -747,7 +759,7 @@ package body Synth.Decls is
(Syn_Inst : Synth_Instance_Acc; Decl : Node)
is
Atype : constant Node := Get_Declaration_Type (Decl);
- Off : Uns32;
+ Off : Value_Offsets;
Voff : Net;
Rdwd : Width;
Res : Valtyp;
@@ -770,7 +782,8 @@ package body Synth.Decls is
-- Object is a net if it is not writable. Extract the
-- bits for the alias.
Res := Create_Value_Net
- (Build2_Extract (Get_Build (Syn_Inst), Base.Val.N, Off, Typ.W),
+ (Build2_Extract (Get_Build (Syn_Inst),
+ Base.Val.N, Off.Net_Off, Typ.W),
Typ);
else
Res := Create_Value_Alias (Base.Val, Off, Typ);
diff --git a/src/synth/synth-disp_vhdl.adb b/src/synth/synth-disp_vhdl.adb
index 436ba938a..375f72e85 100644
--- a/src/synth/synth-disp_vhdl.adb
+++ b/src/synth/synth-disp_vhdl.adb
@@ -214,7 +214,7 @@ package body Synth.Disp_Vhdl is
Disp_In_Converter
(Mname,
Pfx & '.' & Name_Table.Image (Get_Identifier (El)),
- Off + Et.Off, Get_Type (El), Et.Typ, Rec_Full);
+ Off + Et.Boff, Get_Type (El), Et.Typ, Rec_Full);
end;
end loop;
end;
@@ -370,7 +370,7 @@ package body Synth.Disp_Vhdl is
Disp_Out_Converter
(Mname,
Pfx & '.' & Name_Table.Image (Get_Identifier (El)),
- Off + Et.Off, Get_Type (El), Et.Typ, Rec_Full);
+ Off + Et.Boff, Get_Type (El), Et.Typ, Rec_Full);
end;
end loop;
end;
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index cf4ef01ea..d5a32c327 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -34,6 +34,7 @@ with Vhdl.Annotations; use Vhdl.Annotations;
with Netlists.Gates; use Netlists.Gates;
with Netlists.Builders; use Netlists.Builders;
with Netlists.Folds; use Netlists.Folds;
+with Netlists.Utils; use Netlists.Utils;
with Synth.Errors; use Synth.Errors;
with Synth.Environment;
@@ -42,6 +43,7 @@ with Synth.Stmts; use Synth.Stmts;
with Synth.Oper; use Synth.Oper;
with Synth.Heap; use Synth.Heap;
with Synth.Debugger;
+with Synth.Aggr;
with Grt.Types;
with Grt.To_Strings;
@@ -53,30 +55,25 @@ package body Synth.Expr is
procedure Set_Location (N : Net; Loc : Node)
renames Synth.Source.Set_Location;
- function Get_Static_Discrete (V : Value_Acc) return Int64
+ function Get_Static_Discrete (V : Valtyp) return Int64
is
N : Net;
begin
- case V.Kind is
- when Value_Discrete =>
- return V.Scal;
+ case V.Val.Kind is
+ when Value_Memory =>
+ return Read_Discrete (V);
when Value_Const =>
- return V.C_Val.Scal;
+ return Read_Discrete ((V.Typ, V.Val.C_Val));
when Value_Net =>
- N := V.N;
+ N := V.Val.N;
when Value_Wire =>
- N := Synth.Environment.Get_Const_Wire (V.W);
+ N := Synth.Environment.Get_Const_Wire (V.Val.W);
when others =>
raise Internal_Error;
end case;
return Get_Net_Int64 (N);
end Get_Static_Discrete;
- function Get_Static_Discrete (V : Valtyp) return Int64 is
- begin
- return Get_Static_Discrete (V.Val);
- end Get_Static_Discrete;
-
function Is_Positive (V : Valtyp) return Boolean
is
N : Net;
@@ -84,14 +81,14 @@ package body Synth.Expr is
begin
pragma Assert (V.Typ.Kind = Type_Discrete);
case V.Val.Kind is
- when Value_Discrete =>
- return V.Val.Scal >= 0;
when Value_Const =>
- return V.Val.C_Val.Scal >= 0;
+ return Read_Discrete ((V.Typ, V.Val.C_Val)) >= 0;
when Value_Net =>
N := V.Val.N;
when Value_Wire =>
N := Get_Net (V);
+ when Value_Memory =>
+ return Read_Discrete (V) >= 0;
when others =>
raise Internal_Error;
end case;
@@ -179,91 +176,132 @@ package body Synth.Expr is
end loop;
end Uns2logvec;
- procedure Value2logvec (Val : Valtyp;
+ procedure Bit2logvec (Val : Uns32;
+ Vec : in out Logvec_Array;
+ Off : in out Uns32)
+ is
+ pragma Assert (Val <= 1);
+ Idx : constant Digit_Index := Digit_Index (Off / 32);
+ Pos : constant Natural := Natural (Off mod 32);
+ Va : Uns32;
+ begin
+ Va := Shift_Left (Val, Pos);
+ Vec (Idx).Val := Vec (Idx).Val or Va;
+ Vec (Idx).Zx := 0;
+ Off := Off + 1;
+ end Bit2logvec;
+
+ procedure Logic2logvec (Val : Int64;
+ Vec : in out Logvec_Array;
+ Off : in out Uns32;
+ Has_Zx : in out Boolean)
+ is
+ pragma Assert (Val <= 8);
+ Idx : constant Digit_Index := Digit_Index (Off / 32);
+ Pos : constant Natural := Natural (Off mod 32);
+ Va : Uns32;
+ Zx : Uns32;
+ begin
+ From_Std_Logic (Val, Va, Zx);
+ Has_Zx := Has_Zx or Zx /= 0;
+ Va := Shift_Left (Va, Pos);
+ Zx := Shift_Left (Zx, Pos);
+ Vec (Idx).Val := Vec (Idx).Val or Va;
+ Vec (Idx).Zx := Vec (Idx).Zx or Zx;
+ Off := Off + 1;
+ end Logic2logvec;
+
+ procedure Value2logvec (Mem : Memory_Ptr;
+ Typ : Type_Acc;
Vec : in out Logvec_Array;
Off : in out Uns32;
Has_Zx : in out Boolean) is
begin
- if Val.Val.Kind = Value_Const then
- Value2logvec ((Val.Typ, Val.Val.C_Val), Vec, Off, Has_Zx);
- return;
- end if;
-
- case Val.Typ.Kind is
+ case Typ.Kind is
when Type_Bit =>
+ Bit2logvec (Uns32 (Read_U8 (Mem)), Vec, Off);
+ when Type_Logic =>
+ Logic2logvec (Int64 (Read_U8 (Mem)), Vec, Off, Has_Zx);
+ when Type_Discrete =>
+ Uns2logvec (To_Uns64 (Read_Discrete (Mem, Typ)), Typ.W, Vec, Off);
+ when Type_Vector =>
declare
- Idx : constant Digit_Index := Digit_Index (Off / 32);
- Pos : constant Natural := Natural (Off mod 32);
- Va : Uns32;
+ Vlen : constant Iir_Index32 := Vec_Length (Typ);
begin
- Va := Uns32 (Val.Val.Scal);
- Va := Shift_Left (Va, Pos);
- Vec (Idx).Val := Vec (Idx).Val or Va;
- Vec (Idx).Zx := 0;
- Off := Off + 1;
+ case Typ.Vec_El.Kind is
+ when Type_Bit =>
+ -- TODO: optimize off mod 32 = 0.
+ for I in reverse 1 .. Vlen loop
+ Bit2logvec (Uns32 (Read_U8 (Mem + Size_Type (I - 1))),
+ Vec, Off);
+ end loop;
+ when Type_Logic =>
+ for I in reverse 1 .. Vlen loop
+ Logic2logvec
+ (Int64 (Read_U8 (Mem + Size_Type (I - 1))),
+ Vec, Off, Has_Zx);
+ end loop;
+ when others =>
+ raise Internal_Error;
+ end case;
end;
- when Type_Logic =>
+ when Type_Array =>
declare
- Idx : constant Digit_Index := Digit_Index (Off / 32);
- Pos : constant Natural := Natural (Off mod 32);
- Va : Uns32;
- Zx : Uns32;
+ Alen : constant Iir_Index32 := Get_Array_Flat_Length (Typ);
+ El_Typ : constant Type_Acc := Typ.Arr_El;
begin
- From_Std_Logic (Val.Val.Scal, Va, Zx);
- Has_Zx := Has_Zx or Zx /= 0;
- Va := Shift_Left (Va, Pos);
- Zx := Shift_Left (Zx, Pos);
- Vec (Idx).Val := Vec (Idx).Val or Va;
- Vec (Idx).Zx := Vec (Idx).Zx or Zx;
- Off := Off + 1;
+ for I in reverse 1 .. Alen loop
+ Value2logvec (Mem + Size_Type (I - 1) * El_Typ.Sz,
+ El_Typ, Vec, Off, Has_Zx);
+ end loop;
end;
- when Type_Discrete =>
- Uns2logvec (To_Uns64 (Val.Val.Scal), Val.Typ.W, Vec, Off);
- when Type_Vector =>
- -- TODO: optimize off mod 32 = 0.
- for I in reverse Val.Val.Arr.V'Range loop
- Value2logvec ((Val.Typ.Vec_El, Val.Val.Arr.V (I)),
- Vec, Off, Has_Zx);
- end loop;
- when Type_Array =>
- for I in reverse Val.Val.Arr.V'Range loop
- Value2logvec ((Val.Typ.Arr_El, Val.Val.Arr.V (I)),
- Vec, Off, Has_Zx);
- end loop;
when Type_Record =>
- for I in Val.Val.Rec.V'Range loop
- Value2logvec ((Val.Typ.Rec.E (I).Typ, Val.Val.Rec.V (I)),
+ for I in Typ.Rec.E'Range loop
+ Value2logvec (Mem + Typ.Rec.E (I).Moff, Typ.Rec.E (I).Typ,
Vec, Off, Has_Zx);
end loop;
when Type_Float =>
-- Fp64 is for sure 64 bits. Assume the endianness of floats is
-- the same as integers endianness.
- Uns2logvec (To_Uns64 (Val.Val.Fp), 64, Vec, Off);
+ Uns2logvec (To_Uns64 (Read_Fp64 (Mem)), 64, Vec, Off);
when others =>
raise Internal_Error;
end case;
end Value2logvec;
+ procedure Value2logvec (Val : Valtyp;
+ Vec : in out Logvec_Array;
+ Off : in out Uns32;
+ Has_Zx : in out Boolean) is
+ begin
+ if Val.Val.Kind = Value_Const then
+ Value2logvec (Val.Val.C_Val.Mem, Val.Typ, Vec, Off, Has_Zx);
+ return;
+ end if;
+
+ Value2logvec (Val.Val.Mem, Val.Typ, Vec, Off, Has_Zx);
+ end Value2logvec;
+
-- Resize for a discrete value.
function Synth_Resize (Val : Valtyp; W : Width; Loc : Node) return Net
is
Wn : constant Width := Val.Typ.W;
N : Net;
Res : Net;
+ V : Int64;
begin
- if Is_Static (Val.Val) then
- if Wn /= W then
- pragma Assert (Val.Val.Kind = Value_Discrete);
- if Val.Typ.Drange.Is_Signed then
- Res := Build2_Const_Int
- (Build_Context, Val.Val.Scal, W);
- else
- Res := Build2_Const_Uns
- (Build_Context, To_Uns64 (Val.Val.Scal), W);
- end if;
- Set_Location (Res, Loc);
- return Res;
+ if Is_Static (Val.Val)
+ and then Wn /= W
+ then
+ -- Optimization: resize directly.
+ V := Read_Discrete (Val);
+ if Val.Typ.Drange.Is_Signed then
+ Res := Build2_Const_Int (Build_Context, V, W);
+ else
+ Res := Build2_Const_Uns (Build_Context, To_Uns64 (V), W);
end if;
+ Set_Location (Res, Loc);
+ return Res;
end if;
N := Get_Net (Val);
@@ -283,349 +321,6 @@ package body Synth.Expr is
end if;
end Synth_Resize;
- function Get_Index_Offset
- (Index : Int64; Bounds : Bound_Type; Expr : Iir) return Uns32
- is
- Left : constant Int64 := Int64 (Bounds.Left);
- Right : constant Int64 := Int64 (Bounds.Right);
- begin
- case Bounds.Dir is
- when Iir_To =>
- if Index >= Left and then Index <= Right then
- -- to
- return Uns32 (Index - Left);
- end if;
- when Iir_Downto =>
- if Index <= Left and then Index >= Right then
- -- downto
- return Uns32 (Left - Index);
- end if;
- end case;
- Error_Msg_Synth (+Expr, "index out of bounds");
- return 0;
- end Get_Index_Offset;
-
- function Get_Index_Offset
- (Index : Value_Acc; Bounds : Bound_Type; Expr : Iir) return Uns32 is
- begin
- if Index.Kind = Value_Discrete then
- return Get_Index_Offset (Index.Scal, Bounds, Expr);
- else
- raise Internal_Error;
- end if;
- end Get_Index_Offset;
-
- function Get_Array_Bound (Typ : Type_Acc; Dim : Dim_Type)
- return Bound_Type is
- begin
- case Typ.Kind is
- when Type_Vector =>
- pragma Assert (Dim = 1);
- return Typ.Vbound;
- when Type_Array =>
- return Typ.Abounds.D (Dim);
- when others =>
- raise Internal_Error;
- end case;
- end Get_Array_Bound;
-
- function Get_Range_Length (Rng : Discrete_Range_Type) return Uns32
- is
- Len : Int64;
- begin
- case Rng.Dir is
- when Iir_To =>
- Len := Rng.Right - Rng.Left + 1;
- when Iir_Downto =>
- Len := Rng.Left - Rng.Right + 1;
- end case;
- if Len < 0 then
- return 0;
- else
- return Uns32 (Len);
- end if;
- end Get_Range_Length;
-
- type Stride_Array is array (Dim_Type range <>) of Iir_Index32;
-
- function Fill_Stride (Typ : Type_Acc) return Stride_Array is
- begin
- case Typ.Kind is
- when Type_Vector =>
- return (1 => 1);
- when Type_Array =>
- declare
- Bnds : constant Bound_Array_Acc := Typ.Abounds;
- Res : Stride_Array (1 .. Bnds.Len);
- Stride : Iir_Index32;
- begin
- Stride := 1;
- for I in reverse 2 .. Bnds.Len loop
- Res (Dim_Type (I)) := Stride;
- Stride := Stride * Iir_Index32 (Bnds.D (I).Len);
- end loop;
- Res (1) := Stride;
- return Res;
- end;
- when others =>
- raise Internal_Error;
- end case;
- end Fill_Stride;
-
- procedure Fill_Array_Aggregate (Syn_Inst : Synth_Instance_Acc;
- Aggr : Node;
- Res : Value_Array_Acc;
- Typ : Type_Acc;
- First_Pos : Iir_Index32;
- Strides : Stride_Array;
- Dim : Dim_Type;
- Const_P : out Boolean)
- is
- Bound : constant Bound_Type := Get_Array_Bound (Typ, Dim);
- El_Typ : constant Type_Acc := Get_Array_Element (Typ);
- Stride : constant Iir_Index32 := Strides (Dim);
- Value : Node;
- Assoc : Node;
-
- procedure Set_Elem (Pos : Iir_Index32)
- is
- Sub_Const : Boolean;
- Val : Valtyp;
- begin
- if Dim = Strides'Last then
- Val := Synth_Expression_With_Type (Syn_Inst, Value, El_Typ);
- pragma Assert (Res.V (Pos) = null);
- Res.V (Pos) := Val.Val;
- if Const_P and then not Is_Static (Val.Val) then
- Const_P := False;
- end if;
- else
- Fill_Array_Aggregate
- (Syn_Inst, Value, Res, Typ, Pos, Strides, Dim + 1, Sub_Const);
- if not Sub_Const then
- Const_P := False;
- end if;
- end if;
- end Set_Elem;
-
- procedure Set_Vector
- (Pos : Iir_Index32; Len : Iir_Index32; Val : Valtyp) is
- begin
- pragma Assert (Dim = Strides'Last);
- if Len = 0 then
- return;
- end if;
- -- FIXME: factorize with bit_extract ?
- case Val.Val.Kind is
- when Value_Array
- | Value_Const_Array =>
- declare
- E : Value_Acc;
- begin
- for I in 1 .. Len loop
- E := Val.Val.Arr.V (I);
- Res.V (Pos + I - 1) := E;
- end loop;
- Const_P := Const_P and then Val.Val.Kind = Value_Const_Array;
- end;
- when Value_Net
- | Value_Wire =>
- declare
- N : Net;
- E : Net;
- begin
- N := Get_Net (Val);
- for I in 1 .. Len loop
- E := Build_Extract (Build_Context, N,
- Uns32 (Len - I) * El_Typ.W, El_Typ.W);
- Res.V (Pos + I - 1) := Create_Value_Net (E, El_Typ).Val;
- end loop;
- Const_P := False;
- end;
- when others =>
- raise Internal_Error;
- end case;
- end Set_Vector;
-
- Pos : Iir_Index32;
- begin
- Assoc := Get_Association_Choices_Chain (Aggr);
- Pos := First_Pos;
- Const_P := True;
- while Is_Valid (Assoc) loop
- Value := Get_Associated_Expr (Assoc);
- loop
- case Get_Kind (Assoc) is
- when Iir_Kind_Choice_By_None =>
- if Get_Element_Type_Flag (Assoc) then
- if Pos >= First_Pos + Stride * Iir_Index32 (Bound.Len)
- then
- Error_Msg_Synth (+Assoc, "element out of array bound");
- else
- Set_Elem (Pos);
- Pos := Pos + Stride;
- end if;
- else
- declare
- Val : Valtyp;
- Val_Len : Uns32;
- begin
- Val := Synth_Expression_With_Basetype
- (Syn_Inst, Value);
- Val_Len := Get_Bound_Length (Val.Typ, 1);
- pragma Assert (Stride = 1);
- if Pos - First_Pos > Iir_Index32 (Bound.Len - Val_Len)
- then
- Error_Msg_Synth
- (+Assoc, "element out of array bound");
- else
- Set_Vector (Pos, Iir_Index32 (Val_Len), Val);
- Pos := Pos + Iir_Index32 (Val_Len);
- end if;
- end;
- end if;
- when Iir_Kind_Choice_By_Others =>
- pragma Assert (Get_Element_Type_Flag (Assoc));
- declare
- Last_Pos : constant Iir_Index32 :=
- First_Pos + Iir_Index32 (Bound.Len) * Stride;
- begin
- while Pos < Last_Pos loop
- if Res.V (Pos) = null then
- Set_Elem (Pos);
- end if;
- Pos := Pos + Stride;
- end loop;
- end;
- when Iir_Kind_Choice_By_Expression =>
- pragma Assert (Get_Element_Type_Flag (Assoc));
- declare
- Ch : constant Node := Get_Choice_Expression (Assoc);
- Idx : Valtyp;
- Off : Iir_Index32;
- begin
- Idx := Synth_Expression (Syn_Inst, Ch);
- if not Is_Static (Idx.Val) then
- Error_Msg_Synth (+Ch, "choice is not static");
- else
- Off := Iir_Index32
- (Get_Index_Offset (Idx.Val, Bound, Ch));
- Set_Elem (First_Pos + Off * Stride);
- end if;
- end;
- when Iir_Kind_Choice_By_Range =>
- declare
- Ch : constant Node := Get_Choice_Range (Assoc);
- Rng : Discrete_Range_Type;
- Val : Valtyp;
- Rng_Len : Width;
- Off : Iir_Index32;
- begin
- Synth_Discrete_Range (Syn_Inst, Ch, Rng);
- if Get_Element_Type_Flag (Assoc) then
- Val := Create_Value_Discrete
- (Rng.Left,
- Get_Subtype_Object (Syn_Inst,
- Get_Base_Type (Get_Type (Ch))));
- while In_Range (Rng, Val.Val.Scal) loop
- Off := Iir_Index32
- (Get_Index_Offset (Val.Val, Bound, Ch));
- Set_Elem (First_Pos + Off * Stride);
- Update_Index (Rng, Val.Val.Scal);
- end loop;
- else
- -- The direction must be the same.
- if Rng.Dir /= Bound.Dir then
- Error_Msg_Synth
- (+Assoc, "direction of range does not match "
- & "direction of array");
- end if;
- -- FIXME: can the expression be unbounded ?
- Val := Synth_Expression_With_Basetype
- (Syn_Inst, Value);
- -- The length must match the range.
- Rng_Len := Get_Range_Length (Rng);
- if Get_Bound_Length (Val.Typ, 1) /= Rng_Len then
- Error_Msg_Synth
- (+Value, "length doesn't match range");
- end if;
- pragma Assert (Stride = 1);
- Off := Iir_Index32
- (Get_Index_Offset (Rng.Left, Bound, Ch));
- Set_Vector (First_Pos + Off,
- Iir_Index32 (Rng_Len), Val);
- end if;
- end;
- when others =>
- Error_Msg_Synth
- (+Assoc, "unhandled association form");
- end case;
- Assoc := Get_Chain (Assoc);
- exit when Is_Null (Assoc);
- exit when not Get_Same_Alternative_Flag (Assoc);
- end loop;
- end loop;
- end Fill_Array_Aggregate;
-
- procedure Fill_Record_Aggregate (Syn_Inst : Synth_Instance_Acc;
- Aggr : Node;
- Rec : Value_Array_Acc;
- Const_P : out Boolean)
- is
- El_List : constant Node_Flist :=
- Get_Elements_Declaration_List (Get_Type (Aggr));
- Value : Node;
- Assoc : Node;
- Pos : Natural;
-
- procedure Set_Elem (Pos : Natural)
- is
- Val : Valtyp;
- El_Type : Type_Acc;
- begin
- El_Type := Get_Subtype_Object
- (Syn_Inst, Get_Type (Get_Nth_Element (El_List, Pos)));
- Val := Synth_Expression_With_Type (Syn_Inst, Value, El_Type);
- if Const_P and not Is_Static (Val.Val) then
- Const_P := False;
- end if;
- Val := Synth_Subtype_Conversion (Val, El_Type, False, Value);
- Rec.V (Iir_Index32 (Pos + 1)) := Val.Val;
- end Set_Elem;
- begin
- Assoc := Get_Association_Choices_Chain (Aggr);
- Pos := 0;
- Const_P := True;
- Rec.V := (others => null);
- while Is_Valid (Assoc) loop
- Value := Get_Associated_Expr (Assoc);
- loop
- case Get_Kind (Assoc) is
- when Iir_Kind_Choice_By_None =>
- Set_Elem (Pos);
- Pos := Pos + 1;
- when Iir_Kind_Choice_By_Others =>
- for I in Rec.V'Range loop
- if Rec.V (I) = null then
- Set_Elem (Natural (I - 1));
- end if;
- end loop;
- when Iir_Kind_Choice_By_Name =>
- Pos := Natural (Get_Element_Position
- (Get_Named_Entity
- (Get_Choice_Name (Assoc))));
- Set_Elem (Pos);
- when others =>
- Error_Msg_Synth
- (+Assoc, "unhandled association form");
- end case;
- Assoc := Get_Chain (Assoc);
- exit when Is_Null (Assoc);
- exit when not Get_Same_Alternative_Flag (Assoc);
- end loop;
- end loop;
- end Fill_Record_Aggregate;
-
procedure Concat_Array (Arr : in out Net_Array)
is
Last : Int32;
@@ -661,10 +356,10 @@ package body Synth.Expr is
end loop;
end Concat_Array;
- function Concat_Array (Arr : Net_Array_Acc) return Net is
+ procedure Concat_Array (Arr : in out Net_Array; N : out Net) is
begin
- Concat_Array (Arr.all);
- return Arr (Arr'First);
+ Concat_Array (Arr);
+ N := Arr (Arr'First);
end Concat_Array;
function Synth_Discrete_Range_Expression
@@ -680,6 +375,7 @@ package body Synth.Expr is
(Syn_Inst : Synth_Instance_Acc; Rng : Node) return Discrete_Range_Type
is
L, R : Valtyp;
+ Lval, Rval : Int64;
begin
L := Synth_Expression_With_Basetype (Syn_Inst, Get_Left_Limit (Rng));
R := Synth_Expression_With_Basetype (Syn_Inst, Get_Right_Limit (Rng));
@@ -691,10 +387,12 @@ package body Synth.Expr is
raise Internal_Error;
end if;
+ Lval := Read_Discrete (L);
+ Rval := Read_Discrete (R);
return (Dir => Get_Direction (Rng),
- Left => L.Val.Scal,
- Right => R.Val.Scal,
- Is_Signed => L.Val.Scal < 0 or R.Val.Scal < 0);
+ Left => Lval,
+ Right => Rval,
+ Is_Signed => Lval < 0 or Rval < 0);
end Synth_Discrete_Range_Expression;
function Synth_Float_Range_Expression
@@ -704,7 +402,7 @@ package body Synth.Expr is
begin
L := Synth_Expression (Syn_Inst, Get_Left_Limit (Rng));
R := Synth_Expression (Syn_Inst, Get_Right_Limit (Rng));
- return ((Get_Direction (Rng), L.Val.Fp, R.Val.Fp));
+ return (Get_Direction (Rng), Read_Fp64 (L), Read_Fp64 (R));
end Synth_Float_Range_Expression;
-- Return the type of EXPR without evaluating it.
@@ -727,13 +425,12 @@ package body Synth.Expr is
El_Typ : Type_Acc;
Res_Bnd : Bound_Type;
Sl_Voff : Net;
- Sl_Off : Uns32;
- Wd : Uns32;
+ Sl_Off : Value_Offsets;
begin
Pfx_Typ := Synth_Type_Of_Object (Syn_Inst, Get_Prefix (Expr));
Get_Onedimensional_Array_Bounds (Pfx_Typ, Pfx_Bnd, El_Typ);
- Synth_Slice_Suffix (Syn_Inst, Expr, Pfx_Bnd, El_Typ.W,
- Res_Bnd, Sl_Voff, Sl_Off, Wd);
+ Synth_Slice_Suffix (Syn_Inst, Expr, Pfx_Bnd, El_Typ,
+ Res_Bnd, Sl_Voff, Sl_Off);
if Sl_Voff /= No_Net then
raise Internal_Error;
@@ -765,7 +462,7 @@ package body Synth.Expr is
begin
-- Maybe do not dereference it if its type is known ?
Val := Synth_Expression (Syn_Inst, Get_Prefix (Expr));
- Res := Heap.Synth_Dereference (Val.Val.Acc);
+ Res := Heap.Synth_Dereference (Read_Access (Val));
return Res.Typ;
end;
@@ -894,75 +591,6 @@ package body Synth.Expr is
Len => Get_Range_Length (Rng));
end Synth_Bounds_From_Range;
- function Synth_Aggregate_Array (Syn_Inst : Synth_Instance_Acc;
- Aggr : Node;
- Aggr_Type : Type_Acc) return Valtyp
- is
- Strides : constant Stride_Array := Fill_Stride (Aggr_Type);
- Arr : Value_Array_Acc;
- Res : Valtyp;
- Const_P : Boolean;
- begin
- Arr := Create_Value_Array
- (Iir_Index32 (Get_Array_Flat_Length (Aggr_Type)));
-
- Fill_Array_Aggregate
- (Syn_Inst, Aggr, Arr, Aggr_Type, 1, Strides, 1, Const_P);
-
- if Const_P then
- Res := Create_Value_Const_Array (Aggr_Type, Arr);
- else
- Res := Create_Value_Array (Aggr_Type, Arr);
- end if;
-
- return Res;
- end Synth_Aggregate_Array;
-
- function Synth_Aggregate_Record (Syn_Inst : Synth_Instance_Acc;
- Aggr : Node;
- Aggr_Type : Type_Acc) return Valtyp
- is
- Arr : Value_Array_Acc;
- Res : Valtyp;
- Const_P : Boolean;
- begin
- -- Allocate the result.
- Arr := Create_Value_Array (Aggr_Type.Rec.Len);
-
- Fill_Record_Aggregate (Syn_Inst, Aggr, Arr, Const_P);
-
- if Const_P then
- Res := Create_Value_Const_Record (Aggr_Type, Arr);
- else
- Res := Create_Value_Record (Aggr_Type, Arr);
- end if;
-
- return Res;
- end Synth_Aggregate_Record;
-
- -- Aggr_Type is the type from the context.
- function Synth_Aggregate (Syn_Inst : Synth_Instance_Acc;
- Aggr : Node;
- Aggr_Type : Type_Acc) return Valtyp is
- begin
- case Aggr_Type.Kind is
- when Type_Unbounded_Array | Type_Unbounded_Vector =>
- declare
- Res_Type : Type_Acc;
- begin
- Res_Type := Decls.Synth_Array_Subtype_Indication
- (Syn_Inst, Get_Type (Aggr));
- return Synth_Aggregate_Array (Syn_Inst, Aggr, Res_Type);
- end;
- when Type_Vector | Type_Array =>
- return Synth_Aggregate_Array (Syn_Inst, Aggr, Aggr_Type);
- when Type_Record =>
- return Synth_Aggregate_Record (Syn_Inst, Aggr, Aggr_Type);
- when others =>
- raise Internal_Error;
- end case;
- end Synth_Aggregate;
-
function Synth_Simple_Aggregate (Syn_Inst : Synth_Instance_Acc;
Aggr : Node) return Valtyp
is
@@ -975,8 +603,8 @@ package body Synth.Expr is
Bnd : Bound_Type;
Bnds : Bound_Array_Acc;
Res_Type : Type_Acc;
- Arr : Value_Array_Acc;
Val : Valtyp;
+ Res : Valtyp;
begin
-- Allocate the result.
Bnd := Synth_Array_Bounds (Syn_Inst, Aggr_Type, 1);
@@ -990,26 +618,22 @@ package body Synth.Expr is
Res_Type := Create_Array_Type (Bnds, El_Typ);
end if;
- Arr := Create_Value_Array (Iir_Index32 (Last + 1));
+ Res := Create_Value_Memory (Res_Type);
for I in Flist_First .. Last loop
Val := Synth_Expression_With_Type
(Syn_Inst, Get_Nth_Element (Els, I), El_Typ);
pragma Assert (Is_Static (Val.Val));
- Arr.V (Iir_Index32 (I + 1)) := Val.Val;
+ Write_Value (Res.Val.Mem + Size_Type (I) * El_Typ.Sz, Val);
end loop;
- return Create_Value_Const_Array (Res_Type, Arr);
+ return Res;
end Synth_Simple_Aggregate;
-- Change the bounds of VAL.
function Reshape_Value (Val : Valtyp; Ntype : Type_Acc) return Valtyp is
begin
case Val.Val.Kind is
- when Value_Array =>
- return Create_Value_Array (Ntype, Val.Val.Arr);
- when Value_Const_Array =>
- return Create_Value_Const_Array (Ntype, Val.Val.Arr);
when Value_Wire =>
return Create_Value_Wire (Val.Val.W, Ntype);
when Value_Net =>
@@ -1018,6 +642,8 @@ package body Synth.Expr is
return Create_Value_Alias (Val.Val.A_Obj, Val.Val.A_Off, Ntype);
when Value_Const =>
return Reshape_Value ((Val.Typ, Val.Val.C_Val), Ntype);
+ when Value_Memory =>
+ return (Ntype, Val.Val);
when others =>
raise Internal_Error;
end case;
@@ -1059,11 +685,12 @@ package body Synth.Expr is
(Build_Context, N, Dtype.W, Get_Location (Loc));
end if;
return Create_Value_Net (N, Dtype);
- when Value_Discrete =>
- return Create_Value_Discrete (Vt.Val.Scal, Dtype);
when Value_Const =>
return Synth_Subtype_Conversion
((Vt.Typ, Vt.Val.C_Val), Dtype, Bounds, Loc);
+ when Value_Memory =>
+ return Create_Value_Discrete
+ (Read_Discrete (Vt), Dtype);
when others =>
raise Internal_Error;
end case;
@@ -1138,7 +765,7 @@ package body Synth.Expr is
end if;
declare
- Str : constant String := Value_To_String (V.Val);
+ Str : constant String := Value_To_String (V);
Res_N : Node;
Val : Int64;
begin
@@ -1169,7 +796,8 @@ package body Synth.Expr is
Str : String (1 .. 24);
Last : Natural;
begin
- Grt.To_Strings.To_String (Str, Last, Ghdl_F64 (Val.Val.Fp));
+ Grt.To_Strings.To_String
+ (Str, Last, Ghdl_F64 (Read_Fp64 (Val)));
return Str (Str'First .. Last);
end;
when Iir_Kind_Integer_Type_Definition
@@ -1178,7 +806,8 @@ package body Synth.Expr is
Str : String (1 .. 21);
First : Natural;
begin
- Grt.To_Strings.To_String (Str, First, Ghdl_I64 (Val.Val.Scal));
+ Grt.To_Strings.To_String
+ (Str, First, Ghdl_I64 (Read_Discrete (Val)));
return Str (First .. Str'Last);
end;
when Iir_Kind_Enumeration_Type_Definition
@@ -1189,7 +818,7 @@ package body Synth.Expr is
begin
return Name_Table.Image
(Get_Identifier
- (Get_Nth_Element (Lits, Natural (Val.Val.Scal))));
+ (Get_Nth_Element (Lits, Natural (Read_Discrete (Val)))));
end;
when Iir_Kind_Physical_Type_Definition
| Iir_Kind_Physical_Subtype_Definition =>
@@ -1199,7 +828,8 @@ package body Synth.Expr is
Id : constant Name_Id :=
Get_Identifier (Get_Primary_Unit (Get_Base_Type (Expr_Type)));
begin
- Grt.To_Strings.To_String (Str, First, Ghdl_I64 (Val.Val.Scal));
+ Grt.To_Strings.To_String
+ (Str, First, Ghdl_I64 (Read_Discrete (Val)));
return Str (First .. Str'Last) & ' ' & Name_Table.Image (Id);
end;
when others =>
@@ -1210,25 +840,21 @@ package body Synth.Expr is
function String_To_Valtyp (Str : String; Styp : Type_Acc) return Valtyp
is
Len : constant Natural := Str'Length;
- Etyp : constant Type_Acc := Styp.Uarr_El;
Bnd : Bound_Array_Acc;
Typ : Type_Acc;
- Dat : Value_Array_Acc;
- P : Iir_Index32;
+ Res : Valtyp;
begin
Bnd := Create_Bound_Array (1);
Bnd.D (1) := (Dir => Iir_To, Left => 1, Right => Int32 (Len),
Len => Width (Len));
Typ := Create_Array_Type (Bnd, Styp.Uarr_El);
- Dat := Create_Value_Array (Iir_Index32 (Len));
- P := Dat.V'First;
+ Res := Create_Value_Memory (Typ);
for I in Str'Range loop
- Dat.V (P) := Create_Value_Discrete (Int64 (Character'Pos (Str (I))),
- Etyp).Val;
- P := P + 1;
+ Write_U8 (Res.Val.Mem + Size_Type (I - Str'First),
+ Character'Pos (Str (I)));
end loop;
- return Create_Value_Const_Array (Typ, Dat);
+ return Res;
end String_To_Valtyp;
function Synth_Image_Attribute (Syn_Inst : Synth_Instance_Acc; Attr : Node)
@@ -1276,8 +902,11 @@ package body Synth.Expr is
declare
Typ : constant Type_Acc :=
Get_Subtype_Object (Syn_Inst, Get_Type (Name));
+ Res : Valtyp;
begin
- return Create_Value_Discrete (Int64 (Get_Enum_Pos (Name)), Typ);
+ Res := Create_Value_Memory (Typ);
+ Write_Discrete (Res, Int64 (Get_Enum_Pos (Name)));
+ return Res;
end;
when Iir_Kind_Unit_Declaration =>
declare
@@ -1293,7 +922,7 @@ package body Synth.Expr is
Val : Valtyp;
begin
Val := Synth_Expression (Syn_Inst, Get_Prefix (Name));
- return Heap.Synth_Dereference (Val.Val.Acc);
+ return Heap.Synth_Dereference (Read_Access (Val));
end;
when others =>
Error_Kind ("synth_name", Name);
@@ -1314,21 +943,27 @@ package body Synth.Expr is
-- SYN_INST and LOC are used in case of error.
function Index_To_Offset
(Syn_Inst : Synth_Instance_Acc; Bnd : Bound_Type; Idx : Int64; Loc : Node)
- return Uns32 is
+ return Value_Offsets
+ is
+ Res : Value_Offsets;
begin
if not In_Bounds (Bnd, Int32 (Idx)) then
Error_Msg_Synth (+Loc, "index not within bounds");
Synth.Debugger.Debug_Error (Syn_Inst, Loc);
- return 0;
+ return (0, 0);
end if;
-- The offset is from the LSB (bit 0). Bit 0 is the rightmost one.
case Bnd.Dir is
when Iir_To =>
- return Uns32 (Bnd.Right - Int32 (Idx));
+ Res.Net_Off := Uns32 (Bnd.Right - Int32 (Idx));
+ Res.Mem_Off := Size_Type (Int32 (Idx) - Bnd.Left);
when Iir_Downto =>
- return Uns32 (Int32 (Idx) - Bnd.Right);
+ Res.Net_Off := Uns32 (Int32 (Idx) - Bnd.Right);
+ Res.Mem_Off := Size_Type (Bnd.Left - Int32 (Idx));
end case;
+
+ return Res;
end Index_To_Offset;
function Dyn_Index_To_Offset
@@ -1392,7 +1027,7 @@ package body Synth.Expr is
when Type_Unbounded_Vector =>
Res := Create_Vector_Type (Bnd, Btyp.Uvec_El);
when Type_Array =>
- pragma Assert (Btyp.Abounds.Len = 1);
+ pragma Assert (Btyp.Abounds.Ndim = 1);
Bnds := Create_Bound_Array (1);
Bnds.D (1) := Bnd;
Res := Create_Array_Type (Bnds, Btyp.Arr_El);
@@ -1411,8 +1046,7 @@ package body Synth.Expr is
Name : Node;
Pfx_Type : Type_Acc;
Voff : out Net;
- Off : out Uns32;
- W : out Width)
+ Off : out Value_Offsets)
is
Indexes : constant Iir_Flist := Get_Index_List (Name);
El_Typ : constant Type_Acc := Get_Array_Element (Pfx_Type);
@@ -1421,16 +1055,16 @@ package body Synth.Expr is
Bnd : Bound_Type;
Stride : Uns32;
Ivoff : Net;
+ Idx_Off : Value_Offsets;
begin
- W := El_Typ.W;
Voff := No_Net;
- Off := 0;
+ Off := (0, 0);
for I in Flist_First .. Flist_Last (Indexes) loop
Idx_Expr := Get_Nth_Element (Indexes, I);
-- Compute stride. This is O(n**2), but for small n.
- Stride := W;
+ Stride := 1;
for J in I + 1 .. Flist_Last (Indexes) loop
Bnd := Get_Array_Bound (Pfx_Type, Dim_Type (J + 1));
Stride := Stride * Bnd.Len;
@@ -1442,13 +1076,16 @@ package body Synth.Expr is
Bnd := Get_Array_Bound (Pfx_Type, Dim_Type (I + 1));
- if Idx_Val.Val.Kind = Value_Discrete then
- Off := Off
- + (Index_To_Offset (Syn_Inst, Bnd, Idx_Val.Val.Scal, Name)
- * Stride);
+ if Is_Static (Idx_Val.Val) then
+ Idx_Off := Index_To_Offset (Syn_Inst, Bnd,
+ Read_Discrete (Idx_Val), Name);
+ Off.Net_Off := Off.Net_Off + Idx_Off.Net_Off * Stride * El_Typ.W;
+ Off.Mem_Off := Off.Mem_Off
+ + Idx_Off.Mem_Off * Size_Type (Stride) * El_Typ.Sz;
else
Ivoff := Dyn_Index_To_Offset (Bnd, Idx_Val, Name);
- Ivoff := Build_Memidx (Get_Build (Syn_Inst), Ivoff, W, Bnd.Len - 1,
+ Ivoff := Build_Memidx (Get_Build (Syn_Inst), Ivoff, El_Typ.W,
+ Bnd.Len - 1,
Width (Clog2 (Uns64 (Stride * Bnd.Len))));
Set_Location (Ivoff, Idx_Expr);
@@ -1619,18 +1256,16 @@ package body Synth.Expr is
Pfx_Bnd : Bound_Type;
L, R : Int64;
Dir : Iir_Direction;
- El_Wd : Width;
+ El_Typ : Type_Acc;
Res_Bnd : out Bound_Type;
- Off : out Uns32;
- Wd : out Width)
+ Off : out Value_Offsets)
is
Is_Null : Boolean;
Len : Uns32;
begin
if Pfx_Bnd.Dir /= Dir then
Error_Msg_Synth (+Name, "direction mismatch in slice");
- Off := 0;
- Wd := 0;
+ Off := (0, 0);
if Dir = Iir_To then
Res_Bnd := (Dir => Iir_To, Left => 1, Right => 0, Len => 0);
else
@@ -1648,42 +1283,41 @@ package body Synth.Expr is
end case;
if Is_Null then
Len := 0;
- Off := 0;
+ Off := (0, 0);
else
if not In_Bounds (Pfx_Bnd, Int32 (L))
or else not In_Bounds (Pfx_Bnd, Int32 (R))
then
Error_Msg_Synth (+Name, "index not within bounds");
Synth.Debugger.Debug_Error (Syn_Inst, Expr);
- Wd := 0;
- Off := 0;
+ Off := (0, 0);
return;
end if;
case Pfx_Bnd.Dir is
when Iir_To =>
Len := Uns32 (R - L + 1);
- Off := Uns32 (Pfx_Bnd.Right - Int32 (R)) * El_Wd;
+ Off.Net_Off := Uns32 (Pfx_Bnd.Right - Int32 (R)) * El_Typ.W;
+ Off.Mem_Off := Size_Type (Int32 (L) - Pfx_Bnd.Left) * El_Typ.Sz;
when Iir_Downto =>
Len := Uns32 (L - R + 1);
- Off := Uns32 (Int32 (R) - Pfx_Bnd.Right) * El_Wd;
+ Off.Net_Off := Uns32 (Int32 (R) - Pfx_Bnd.Right) * El_Typ.W;
+ Off.Mem_Off := Size_Type (Pfx_Bnd.Left - Int32 (L)) * El_Typ.Sz;
end case;
end if;
Res_Bnd := (Dir => Pfx_Bnd.Dir,
Len => Len,
Left => Int32 (L),
Right => Int32 (R));
- Wd := Len * El_Wd;
end Synth_Slice_Const_Suffix;
procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc;
Name : Node;
Pfx_Bnd : Bound_Type;
- El_Wd : Width;
+ El_Typ : Type_Acc;
Res_Bnd : out Bound_Type;
Inp : out Net;
- Off : out Uns32;
- Wd : out Width)
+ Off : out Value_Offsets)
is
Expr : constant Node := Get_Suffix (Name);
Left, Right : Valtyp;
@@ -1692,7 +1326,7 @@ package body Synth.Expr is
Max : Uns32;
Inp_W : Width;
begin
- Off := 0;
+ Off := (0, 0);
case Get_Kind (Expr) is
when Iir_Kind_Range_Expression =>
@@ -1710,7 +1344,7 @@ package body Synth.Expr is
Synth_Slice_Const_Suffix (Syn_Inst, Expr,
Name, Pfx_Bnd,
Rng.Left, Rng.Right, Rng.Dir,
- El_Wd, Res_Bnd, Off, Wd);
+ El_Typ, Res_Bnd, Off);
return;
end;
when others =>
@@ -1722,16 +1356,15 @@ package body Synth.Expr is
Inp := No_Net;
Synth_Slice_Const_Suffix (Syn_Inst, Expr,
Name, Pfx_Bnd,
- Get_Static_Discrete (Left.Val),
- Get_Static_Discrete (Right.Val),
+ Get_Static_Discrete (Left),
+ Get_Static_Discrete (Right),
Dir,
- El_Wd, Res_Bnd, Off, Wd);
+ El_Typ, Res_Bnd, Off);
else
if Pfx_Bnd.Dir /= Dir then
Error_Msg_Synth (+Name, "direction mismatch in slice");
Inp := No_Net;
- Off := 0;
- Wd := 0;
+ Off := (0, 0);
if Dir = Iir_To then
Res_Bnd := (Dir => Iir_To, Left => 1, Right => 0, Len => 0);
else
@@ -1748,7 +1381,8 @@ package body Synth.Expr is
end if;
Synth_Extract_Dyn_Suffix
(Get_Build (Syn_Inst), Name,
- Pfx_Bnd, Get_Net (Left), Get_Net (Right), Inp, Step, Off, Wd);
+ Pfx_Bnd, Get_Net (Left), Get_Net (Right), Inp, Step, Off.Net_Off,
+ Res_Bnd.Len);
Inp_W := Get_Width (Inp);
-- FIXME: convert range to offset.
-- Extract max from the range.
@@ -1756,16 +1390,15 @@ package body Synth.Expr is
-- len=8 wd=4 step=1 => max=4
-- max so that max*step+wd <= len - off
-- max <= (len - off - wd) / step
- Max := (Pfx_Bnd.Len - Off - Wd) / Step;
+ Max := (Pfx_Bnd.Len - Off.Net_Off - Res_Bnd.Len) / Step;
if Clog2 (Uns64 (Max)) > Natural (Inp_W) then
-- The width of Inp limits the max.
Max := 2**Natural (Inp_W) - 1;
end if;
Inp := Build_Memidx
(Get_Build (Syn_Inst),
- Inp, Step * El_Wd, Max,
- Inp_W + Width (Clog2 (Uns64 (Step * El_Wd))));
- Wd := Wd * El_Wd;
+ Inp, Step * El_Typ.W, Max,
+ Inp_W + Width (Clog2 (Uns64 (Step * El_Typ.W))));
end if;
end Synth_Slice_Suffix;
@@ -1886,14 +1519,16 @@ package body Synth.Expr is
-- Int to int.
return Val;
elsif Val.Typ.Kind = Type_Float then
- return Create_Value_Discrete (Int64 (Val.Val.Fp), Conv_Typ);
+ return Create_Value_Discrete
+ (Int64 (Read_Fp64 (Val)), Conv_Typ);
else
Error_Msg_Synth (+Conv, "unhandled type conversion (to int)");
return No_Valtyp;
end if;
when Iir_Kind_Floating_Subtype_Definition =>
if Is_Static (Val.Val) then
- return Create_Value_Float (Fp64 (Val.Val.Scal), Conv_Typ);
+ return Create_Value_Float
+ (Fp64 (Read_Discrete (Val)), Conv_Typ);
else
Error_Msg_Synth (+Conv, "unhandled type conversion (to float)");
return No_Valtyp;
@@ -1946,7 +1581,6 @@ package body Synth.Expr is
Bnds : Bound_Array_Acc;
Res_Type : Type_Acc;
Res : Valtyp;
- Arr : Value_Array_Acc;
Pos : Nat8;
begin
case Str_Typ.Kind is
@@ -1969,15 +1603,18 @@ package body Synth.Expr is
Bnds.D (1) := Bounds;
Res_Type := Create_Array_Type (Bnds, El_Type);
end if;
- Arr := Create_Value_Array (Iir_Index32 (Bounds.Len));
+ Res := Create_Value_Memory (Res_Type);
- for I in Arr.V'Range loop
+ -- Only U8 are handled.
+ pragma Assert (El_Type.Sz = 1);
+
+ -- From left to right.
+ for I in 1 .. Bounds.Len loop
-- FIXME: use literal from type ??
Pos := Str_Table.Element_String8 (Id, Pos32 (I));
- Arr.V (I) := Create_Value_Discrete (Int64 (Pos), El_Type).Val;
+ Write_U8 (Res.Val.Mem + Size_Type (I - 1), Nat8'Pos (Pos));
end loop;
- Res := Create_Value_Const_Array (Res_Type, Arr);
return Res;
end Synth_String_Literal;
@@ -2026,7 +1663,7 @@ package body Synth.Expr is
return No_Valtyp;
end if;
if Is_Static_Val (Left.Val)
- and then Get_Static_Discrete (Left.Val) = Val
+ and then Get_Static_Discrete (Left) = Val
then
return Create_Value_Discrete (Val, Boolean_Type);
end if;
@@ -2041,7 +1678,7 @@ package body Synth.Expr is
-- Return a static value if both operands are static.
-- Note: we know the value of left if it is not constant.
if Is_Static_Val (Left.Val) and then Is_Static_Val (Right.Val) then
- Val := Get_Static_Discrete (Right.Val);
+ Val := Get_Static_Discrete (Right);
return Create_Value_Discrete (Val, Boolean_Type);
end if;
@@ -2052,9 +1689,7 @@ package body Synth.Expr is
function Synth_Expression_With_Type
(Syn_Inst : Synth_Instance_Acc; Expr : Node; Expr_Type : Type_Acc)
- return Valtyp
- is
- Res : Valtyp;
+ return Valtyp is
begin
case Get_Kind (Expr) is
when Iir_Kinds_Dyadic_Operator =>
@@ -2135,7 +1770,8 @@ package body Synth.Expr is
declare
Base : Valtyp;
Typ : Type_Acc;
- Off : Uns32;
+ Off : Value_Offsets;
+ Res : Valtyp;
Voff : Net;
Rdwd : Width;
@@ -2143,10 +1779,13 @@ package body Synth.Expr is
Synth_Assignment_Prefix
(Syn_Inst, Expr, Base, Typ, Off, Voff, Rdwd);
if Voff = No_Net and then Is_Static (Base.Val) then
- pragma Assert (Off = 0);
- return Base;
+ Res := Create_Value_Memory (Typ);
+ Copy_Memory
+ (Res.Val.Mem, Base.Val.Mem + Off.Mem_Off, Typ.Sz);
+ return Res;
end if;
- return Synth_Read_Memory (Syn_Inst, Base, Typ, Off, Voff, Expr);
+ return Synth_Read_Memory
+ (Syn_Inst, Base, Typ, Off.Net_Off, Voff, Expr);
end;
when Iir_Kind_Selected_Element =>
declare
@@ -2155,16 +1794,22 @@ package body Synth.Expr is
Pfx : constant Node := Get_Prefix (Expr);
Res_Typ : Type_Acc;
N : Net;
+ Val : Valtyp;
+ Res : Valtyp;
begin
- Res := Synth_Expression (Syn_Inst, Pfx);
- Strip_Const (Res);
- Res_Typ := Res.Typ.Rec.E (Idx + 1).Typ;
- if Res.Val.Kind = Value_Const_Record then
- return (Res_Typ, Res.Val.Rec.V (Idx + 1));
+ Val := Synth_Expression (Syn_Inst, Pfx);
+ Strip_Const (Val);
+ Res_Typ := Val.Typ.Rec.E (Idx + 1).Typ;
+ if Is_Static (Val.Val) then
+ Res := Create_Value_Memory (Res_Typ);
+ Copy_Memory
+ (Res.Val.Mem, Val.Val.Mem + Val.Typ.Rec.E (Idx + 1).Moff,
+ Res_Typ.Sz);
+ return Res;
else
N := Build_Extract
- (Build_Context, Get_Net (Res),
- Res.Typ.Rec.E (Idx + 1).Off, Get_Type_Width (Res_Typ));
+ (Build_Context, Get_Net (Val),
+ Val.Typ.Rec.E (Idx + 1).Boff, Get_Type_Width (Res_Typ));
Set_Location (N, Expr);
return Create_Value_Net (N, Res_Typ);
end if;
@@ -2173,7 +1818,13 @@ package body Synth.Expr is
return Synth_Expression_With_Type
(Syn_Inst, Get_Named_Entity (Expr), Expr_Type);
when Iir_Kind_Integer_Literal =>
- return Create_Value_Discrete (Get_Value (Expr), Expr_Type);
+ declare
+ Res : Valtyp;
+ begin
+ Res := Create_Value_Memory (Expr_Type);
+ Write_Discrete (Res, Get_Value (Expr));
+ return Res;
+ end;
when Iir_Kind_Floating_Point_Literal =>
return Create_Value_Float (Get_Fp_Value (Expr), Expr_Type);
when Iir_Kind_Physical_Int_Literal
@@ -2204,7 +1855,7 @@ package body Synth.Expr is
end case;
end;
when Iir_Kind_Aggregate =>
- return Synth_Aggregate (Syn_Inst, Expr, Expr_Type);
+ return Synth.Aggr.Synth_Aggregate (Syn_Inst, Expr, Expr_Type);
when Iir_Kind_Simple_Aggregate =>
return Synth_Simple_Aggregate (Syn_Inst, Expr);
when Iir_Kind_Left_Array_Attribute =>
@@ -2278,7 +1929,7 @@ package body Synth.Expr is
when Iir_Kind_Image_Attribute =>
return Synth_Image_Attribute (Syn_Inst, Expr);
when Iir_Kind_Null_Literal =>
- return Create_Value_Access (Expr_Type, Null_Heap_Index);
+ return Create_Value_Access (Null_Heap_Index, Expr_Type);
when Iir_Kind_Allocator_By_Subtype =>
declare
T : Type_Acc;
@@ -2287,7 +1938,7 @@ package body Synth.Expr is
T := Synth.Decls.Synth_Subtype_Indication
(Syn_Inst, Get_Subtype_Indication (Expr));
Acc := Allocate_By_Type (T);
- return Create_Value_Access (Expr_Type, Acc);
+ return Create_Value_Access (Acc, Expr_Type);
end;
when Iir_Kind_Allocator_By_Expression =>
declare
@@ -2297,7 +1948,7 @@ package body Synth.Expr is
V := Synth_Expression_With_Type
(Syn_Inst, Get_Expression (Expr), Expr_Type.Acc_Acc);
Acc := Allocate_By_Value (V);
- return Create_Value_Access (Expr_Type, Acc);
+ return Create_Value_Access (Acc, Expr_Type);
end;
when Iir_Kind_Overflow_Literal =>
declare
diff --git a/src/synth/synth-expr.ads b/src/synth/synth-expr.ads
index 84544eadf..3c47bebfa 100644
--- a/src/synth/synth-expr.ads
+++ b/src/synth/synth-expr.ads
@@ -23,7 +23,6 @@ with Ada.Unchecked_Deallocation;
with Types; use Types;
with Netlists; use Netlists;
-with Netlists.Utils; use Netlists.Utils;
with Synth.Source;
with Synth.Values; use Synth.Values;
@@ -39,7 +38,6 @@ package Synth.Expr is
return Valtyp;
-- For a static value V, return the value.
- function Get_Static_Discrete (V : Value_Acc) return Int64;
function Get_Static_Discrete (V : Valtyp) return Int64;
-- Return True only if discrete value V is known to be positive or 0.
@@ -66,7 +64,7 @@ package Synth.Expr is
function Synth_Clock_Edge
(Syn_Inst : Synth_Instance_Acc; Left, Right : Node) return Net;
- function Concat_Array (Arr : Net_Array_Acc) return Net;
+ procedure Concat_Array (Arr : in out Net_Array; N : out Net);
function Synth_Expression_With_Type
(Syn_Inst : Synth_Instance_Acc; Expr : Node; Expr_Type : Type_Acc)
@@ -101,11 +99,10 @@ package Synth.Expr is
procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc;
Name : Node;
Pfx_Bnd : Bound_Type;
- El_Wd : Width;
+ El_Typ : Type_Acc;
Res_Bnd : out Bound_Type;
Inp : out Net;
- Off : out Uns32;
- Wd : out Width);
+ Off : out Value_Offsets);
-- If VOFF is No_Net then OFF is valid, if VOFF is not No_Net then
-- OFF is 0.
@@ -113,8 +110,7 @@ package Synth.Expr is
Name : Node;
Pfx_Type : Type_Acc;
Voff : out Net;
- Off : out Uns32;
- W : out Width);
+ Off : out Value_Offsets);
-- Return the type of EXPR (an object) without evaluating it (except when
-- needed, like bounds of a slice).
diff --git a/src/synth/synth-files_operations.adb b/src/synth/synth-files_operations.adb
index d840035be..525adec54 100644
--- a/src/synth/synth-files_operations.adb
+++ b/src/synth/synth-files_operations.adb
@@ -47,16 +47,17 @@ package body Synth.Files_Operations is
procedure Convert_String (Val : Valtyp; Res : out String)
is
Vtyp : constant Type_Acc := Val.Typ;
+ Vlen : constant Uns32 := Vtyp.Abounds.D (1).Len;
begin
pragma Assert (Vtyp.Kind = Type_Array);
pragma Assert (Vtyp.Arr_El.Kind = Type_Discrete);
pragma Assert (Vtyp.Arr_El.W in 7 .. 8); -- Could be 7 in vhdl87
- pragma Assert (Vtyp.Abounds.Len = 1);
+ pragma Assert (Vtyp.Abounds.Ndim = 1);
pragma Assert (Vtyp.Abounds.D (1).Len = Res'Length);
- for I in Val.Val.Arr.V'Range loop
+ for I in 1 .. Vlen loop
Res (Res'First + Natural (I - 1)) :=
- Character'Val (Val.Val.Arr.V (I).Scal);
+ Character'Val (Read_U8 (Val.Val.Mem + Size_Type (I - 1)));
end loop;
end Convert_String;
@@ -69,7 +70,7 @@ package body Synth.Files_Operations is
Name : constant Valtyp := Strip_Alias_Const (Val);
pragma Unreferenced (Val);
begin
- Len := Natural (Name.Val.Arr.Len);
+ Len := Natural (Name.Typ.Abounds.D (1).Len);
if Len >= Res'Length - 1 then
Status := Op_Filename_Error;
@@ -125,7 +126,7 @@ package body Synth.Files_Operations is
if Open_Kind /= Null_Node then
Mode := Synth_Expression (Syn_Inst, Open_Kind);
- File_Mode := Ghdl_I32 (Mode.Val.Scal);
+ File_Mode := Ghdl_I32 (Read_Discrete (Mode));
else
case Get_Mode (Decl) is
when Iir_In_Mode =>
@@ -196,7 +197,7 @@ package body Synth.Files_Operations is
begin
Convert_File_Name (File_Name, C_Name, C_Name_Len, Status);
if Status = Op_Ok then
- File_Mode := Ghdl_I32 (Open_Kind.Val.Scal);
+ File_Mode := Ghdl_I32 (Read_Discrete (Open_Kind));
if Get_Text_File_Flag (Get_Type (Inters)) then
Ghdl_Text_File_Open
(F, File_Mode, To_Ghdl_C_String (C_Name'Address), Status);
@@ -250,7 +251,7 @@ package body Synth.Files_Operations is
Str : constant Valtyp := Get_Value (Syn_Inst, Param2);
Param3 : constant Node := Get_Chain (Param2);
Param_Len : constant Valtyp := Get_Value (Syn_Inst, Param3);
- Buf : String (1 .. Natural (Str.Val.Arr.Len));
+ Buf : String (1 .. Natural (Str.Typ.Abounds.D (1).Len));
Len : Std_Integer;
Status : Op_Status;
begin
@@ -262,10 +263,10 @@ package body Synth.Files_Operations is
end if;
for I in 1 .. Natural (Len) loop
- Str.Val.Arr.V (Iir_Index32 (I)).Scal := Character'Pos (Buf (I));
+ Write_U8 (Str.Val.Mem + Size_Type (I - 1), Character'Pos (Buf (I)));
end loop;
- Param_Len.Val.Scal := Int64 (Len);
+ Write_Discrete (Param_Len, Int64 (Len));
end Synth_Untruncated_Text_Read;
end Synth.Files_Operations;
diff --git a/src/synth/synth-heap.adb b/src/synth/synth-heap.adb
index 76935a93c..75d0f7c82 100644
--- a/src/synth/synth-heap.adb
+++ b/src/synth/synth-heap.adb
@@ -21,7 +21,6 @@
with Types; use Types;
with Tables;
-with Vhdl.Nodes; use Vhdl.Nodes;
package body Synth.Heap is
@@ -31,32 +30,24 @@ package body Synth.Heap is
Table_Low_Bound => 1,
Table_Initial => 16);
- function Allocate_By_Type (T : Type_Acc) return Value_Acc is
+ function Alloc_Mem (Sz : Size_Type) return Memory_Ptr;
+ pragma Import (C, Alloc_Mem, "malloc");
+
+ function Allocate_Memory (T : Type_Acc) return Value_Acc
+ is
+ M : Memory_Ptr;
+ begin
+ M := Alloc_Mem (T.Sz);
+ return new Value_Type'(Kind => Value_Memory, Mem => M);
+ end Allocate_Memory;
+
+ function Allocate_By_Type (T : Type_Acc) return Value_Acc
+ is
+ Res : Value_Acc;
begin
- case T.Kind is
- when Type_Bit
- | Type_Logic =>
- return new Value_Type'
- (Kind => Value_Discrete, Scal => 0);
- when Type_Discrete =>
- return new Value_Type'
- (Kind => Value_Discrete, Scal => T.Drange.Left);
- when Type_Array =>
- declare
- Len : constant Uns32 := Get_Array_Flat_Length (T);
- El_Typ : constant Type_Acc := Get_Array_Element (T);
- Arr : Value_Array_Acc;
- begin
- Arr := new Value_Array_Type (Iir_Index32 (Len));
- for I in Arr.V'Range loop
- Arr.V (I) := Allocate_By_Type (El_Typ);
- end loop;
- return new Value_Type'
- (Kind => Value_Const_Array, Arr => Arr);
- end;
- when others =>
- raise Internal_Error;
- end case;
+ Res := Allocate_Memory (T);
+ Write_Value_Default (Res.Mem, T);
+ return Res;
end Allocate_By_Type;
function Allocate_By_Type (T : Type_Acc) return Heap_Index is
@@ -66,30 +57,13 @@ package body Synth.Heap is
return Heap_Table.Last;
end Allocate_By_Type;
- function Allocate_By_Value (V : Valtyp) return Value_Acc is
+ function Allocate_By_Value (V : Valtyp) return Value_Acc
+ is
+ Res : Value_Acc;
begin
- case V.Val.Kind is
- when Value_Net
- | Value_Wire =>
- raise Internal_Error;
- when Value_Discrete =>
- return new Value_Type'(Kind => Value_Discrete, Scal => V.Val.Scal);
- when Value_Array
- | Value_Const_Array =>
- declare
- El_Typ : constant Type_Acc := Get_Array_Element (V.Typ);
- Arr : Value_Array_Acc;
- begin
- Arr := new Value_Array_Type (V.Val.Arr.Len);
- for I in Arr.V'Range loop
- Arr.V (I) := Allocate_By_Value
- ((El_Typ, V.Val.Arr.V (I)));
- end loop;
- return new Value_Type'(Kind => Value_Const_Array, Arr => Arr);
- end;
- when others =>
- raise Internal_Error;
- end case;
+ Res := Allocate_Memory (V.Typ);
+ Write_Value (Res.Mem, V);
+ return Res;
end Allocate_By_Value;
function Allocate_By_Value (V : Valtyp) return Heap_Index is
diff --git a/src/synth/synth-insts.adb b/src/synth/synth-insts.adb
index 93d601a5f..85693b11f 100644
--- a/src/synth/synth-insts.adb
+++ b/src/synth/synth-insts.adb
@@ -118,8 +118,8 @@ package body Synth.Insts is
end if;
Inter := Get_Generic_Chain (Params.Decl);
while Inter /= Null_Node loop
- if not Is_Equal (Get_Value (Obj.Syn_Inst, Inter).Val,
- Get_Value (Params.Syn_Inst, Inter).Val)
+ if not Is_Equal (Get_Value (Obj.Syn_Inst, Inter),
+ Get_Value (Params.Syn_Inst, Inter))
then
return False;
end if;
@@ -156,6 +156,17 @@ package body Synth.Insts is
GNAT.SHA1.Update (C, S);
end Hash_Uns64;
+ procedure Hash_Memory (C : in out GNAT.SHA1.Context;
+ M : Memory_Ptr;
+ Typ : Type_Acc)
+ is
+ S : String (1 .. Natural (Typ.Sz));
+ for S'Address use M (0)'Address;
+ pragma Import (Ada, S);
+ begin
+ GNAT.SHA1.Update (C, S);
+ end Hash_Memory;
+
procedure Hash_Bound (C : in out GNAT.SHA1.Context; B : Bound_Type) is
begin
Hash_Uns64 (C, Iir_Direction'Pos (B.Dir));
@@ -182,37 +193,17 @@ package body Synth.Insts is
Typ : Type_Acc) is
begin
case Val.Kind is
- when Value_Discrete =>
- Hash_Uns64 (C, To_Uns64 (Val.Scal));
- when Value_Float =>
- Hash_Uns64 (C, To_Uns64 (Val.Fp));
- when Value_Const_Array =>
- declare
- El_Typ : constant Type_Acc := Get_Array_Element (Typ);
- begin
- -- Bounds.
- Hash_Bounds (C, Typ);
- -- Values.
- for I in Val.Arr.V'Range loop
- Hash_Const (C, Val.Arr.V (I), El_Typ);
- end loop;
- end;
- when Value_Const_Record =>
- for I in Val.Rec.V'Range loop
- Hash_Const (C, Val.Rec.V (I), Typ.Rec.E (I).Typ);
- end loop;
+ when Value_Memory =>
+ Hash_Memory (C, Val.Mem, Typ);
when Value_Const =>
Hash_Const (C, Val.C_Val, Typ);
when Value_Alias =>
- if Val.A_Off /= 0 then
+ if Val.A_Off /= (0, 0) then
raise Internal_Error;
end if;
Hash_Const (C, Val.A_Obj, Typ);
when Value_Net
| Value_Wire
- | Value_Array
- | Value_Record
- | Value_Access
| Value_File =>
raise Internal_Error;
end case;
@@ -274,11 +265,12 @@ package body Synth.Insts is
Gen_Decl := Generics;
while Gen_Decl /= Null_Node loop
Gen := Get_Value (Params.Syn_Inst, Gen_Decl);
- case Gen.Val.Kind is
- when Value_Discrete =>
+ Strip_Const (Gen);
+ case Gen.Typ.Kind is
+ when Type_Discrete =>
declare
S : constant String :=
- Uns64'Image (To_Uns64 (Gen.Val.Scal));
+ Uns64'Image (To_Uns64 (Read_Discrete (Gen)));
begin
if Len + S'Length > Str_Len then
Has_Hash := True;
@@ -555,23 +547,21 @@ package body Synth.Insts is
begin
Synth_Individual_Prefix
(Syn_Inst, Inter_Inst, Get_Prefix (Formal), Off, Typ);
- Off := Off + Typ.Rec.E (Idx + 1).Off;
+ Off := Off + Typ.Rec.E (Idx + 1).Boff;
Typ := Typ.Rec.E (Idx + 1).Typ;
end;
when Iir_Kind_Indexed_Name =>
declare
Voff : Net;
- Arr_Off : Uns32;
- W : Width;
+ Arr_Off : Value_Offsets;
begin
Synth_Individual_Prefix
(Syn_Inst, Inter_Inst, Get_Prefix (Formal), Off, Typ);
- Synth_Indexed_Name
- (Syn_Inst, Formal, Typ, Voff, Arr_Off, W);
+ Synth_Indexed_Name (Syn_Inst, Formal, Typ, Voff, Arr_Off);
if Voff /= No_Net then
raise Internal_Error;
end if;
- Off := Off + Arr_Off;
+ Off := Off + Arr_Off.Net_Off;
Typ := Get_Array_Element (Typ);
end;
when Iir_Kind_Slice_Name =>
@@ -580,19 +570,18 @@ package body Synth.Insts is
El_Typ : Type_Acc;
Res_Bnd : Bound_Type;
Sl_Voff : Net;
- Sl_Off : Uns32;
- Wd : Uns32;
+ Sl_Off : Value_Offsets;
begin
Synth_Individual_Prefix
(Syn_Inst, Inter_Inst, Get_Prefix (Formal), Off, Typ);
Get_Onedimensional_Array_Bounds (Typ, Pfx_Bnd, El_Typ);
- Synth_Slice_Suffix (Syn_Inst, Formal, Pfx_Bnd, El_Typ.W,
- Res_Bnd, Sl_Voff, Sl_Off, Wd);
+ Synth_Slice_Suffix (Syn_Inst, Formal, Pfx_Bnd, El_Typ,
+ Res_Bnd, Sl_Voff, Sl_Off);
if Sl_Voff /= No_Net then
raise Internal_Error;
end if;
- Off := Off + Sl_Off;
+ Off := Off + Sl_Off.Net_Off;
Typ := Create_Onedimensional_Array_Subtype (Typ, Res_Bnd);
end;
when others =>
diff --git a/src/synth/synth-oper.adb b/src/synth/synth-oper.adb
index e9f93fb0e..2f2dc6dcc 100644
--- a/src/synth/synth-oper.adb
+++ b/src/synth/synth-oper.adb
@@ -54,12 +54,12 @@ package body Synth.Oper is
Res : Net;
begin
if Is_Static (Val.Val) and then Val.Typ.Kind = Type_Discrete then
- if Val.Typ.Drange.Is_Signed and then Val.Val.Scal < 0 then
+ if Val.Typ.Drange.Is_Signed and then Read_Discrete (Val) < 0 then
-- TODO.
raise Internal_Error;
else
Res := Build2_Const_Uns
- (Build_Context, To_Uns64 (Val.Val.Scal), W);
+ (Build_Context, To_Uns64 (Read_Discrete (Val)), W);
end if;
Set_Location (Res, Loc);
return Res;
@@ -73,7 +73,7 @@ package body Synth.Oper is
begin
if Is_Static (Val.Val) and then Val.Typ.Kind = Type_Discrete then
if Val.Typ.Drange.Is_Signed then
- Res := Build2_Const_Int (Build_Context, Val.Val.Scal, W);
+ Res := Build2_Const_Int (Build_Context, Read_Discrete (Val), W);
else
-- TODO.
raise Internal_Error;
@@ -94,10 +94,11 @@ package body Synth.Oper is
begin
if Is_Static (Expr.Val) then
return Create_Value_Discrete
- (Boolean'Pos (Cst.Val.Scal = Expr.Val.Scal), Boolean_Type);
+ (Boolean'Pos (Read_Discrete (Cst) = Read_Discrete (Expr)),
+ Boolean_Type);
end if;
- To_Logic (Cst.Val.Scal, Cst.Typ, Val, Zx);
+ To_Logic (Read_Discrete (Cst), Cst.Typ, Val, Zx);
if Zx /= 0 then
-- Equal unknown -> return X
N := Build_Const_UL32 (Build_Context, 0, 1, 1);
@@ -197,8 +198,8 @@ package body Synth.Oper is
Boff := 0;
Woff := 0;
- for I in reverse Cst.Val.Arr.V'Range loop
- case Cst.Val.Arr.V (I).Scal is
+ for I in reverse 1 .. Vec_Length (Cst.Typ) loop
+ case Read_U8 (Cst.Val.Mem + Size_Type (I - 1)) is
when Std_Logic_0_Pos
| Std_Logic_L_Pos =>
B := 0;
@@ -604,7 +605,7 @@ package body Synth.Oper is
N : Net;
begin
if Is_Static_Val (Right.Val) then
- Amt := Get_Static_Discrete (Right.Val);
+ Amt := Get_Static_Discrete (Right);
if Amt < 0 then
raise Internal_Error;
end if;
@@ -1057,7 +1058,7 @@ package body Synth.Oper is
when Iir_Predefined_Ieee_Numeric_Std_Lt_Uns_Nat
| Iir_Predefined_Ieee_Numeric_Std_Match_Lt_Uns_Nat =>
-- "<" (Unsigned, Natural)
- if Is_Static (Right.Val) and then Right.Val.Scal = 0 then
+ if Is_Static (Right.Val) and then Read_Discrete (Right) = 0 then
-- Always false.
return Create_Value_Discrete (0, Expr_Typ);
end if;
@@ -1241,7 +1242,7 @@ package body Synth.Oper is
use Mutils;
Etype : constant Type_Acc :=
Get_Subtype_Object (Syn_Inst, Expr_Type);
- R : constant Int64 := Get_Static_Discrete (Right.Val);
+ R : constant Int64 := Get_Static_Discrete (Right);
Log_R : Natural;
N : Net;
begin
@@ -1427,15 +1428,17 @@ package body Synth.Oper is
function Synth_Conv_Vector (Is_Signed : Boolean) return Valtyp
is
Arg : constant Valtyp := Get_Value (Subprg_Inst, Param1);
- Size_Vt : constant Valtyp := Get_Value (Subprg_Inst, Param2);
+ Size_Vt : Valtyp;
Size : Width;
Arg_Net : Net;
begin
+ Size_Vt := Get_Value (Subprg_Inst, Param2);
+ Strip_Const (Size_Vt);
if not Is_Static (Size_Vt.Val) then
Error_Msg_Synth (+Expr, "size parameter must be constant");
return No_Valtyp;
end if;
- Size := Uns32 (Strip_Const (Size_Vt.Val).Scal);
+ Size := Uns32 (Read_Discrete (Size_Vt));
Arg_Net := Get_Net (Arg);
Arg_Net := Build2_Resize (Ctxt, Arg_Net, Size, Is_Signed,
Get_Location (Expr));
@@ -1518,7 +1521,7 @@ package body Synth.Oper is
Error_Msg_Synth (+Expr, "size must be constant");
return No_Valtyp;
end if;
- W := Uns32 (R.Val.Scal);
+ W := Uns32 (Read_Discrete (R));
return Create_Value_Net
(Synth_Uresize (Get_Net (L), W, Expr),
Create_Vec_Type_By_Length (W, Logic_Type));
@@ -1531,7 +1534,7 @@ package body Synth.Oper is
Error_Msg_Synth (+Expr, "size must be constant");
return No_Valtyp;
end if;
- W := Uns32 (R.Val.Scal);
+ W := Uns32 (Read_Discrete (R));
return Create_Value_Net
(Build2_Sresize (Ctxt, Get_Net (L), W, Get_Location (Expr)),
Create_Vec_Type_By_Length (W, Logic_Type));
diff --git a/src/synth/synth-static_oper.adb b/src/synth/synth-static_oper.adb
index 641289492..2cf4c1b98 100644
--- a/src/synth/synth-static_oper.adb
+++ b/src/synth/synth-static_oper.adb
@@ -21,6 +21,8 @@
with Types; use Types;
with Types_Utils; use Types_Utils;
+with Grt.Types;
+
with Vhdl.Utils; use Vhdl.Utils;
with Vhdl.Ieee.Std_Logic_1164; use Vhdl.Ieee.Std_Logic_1164;
@@ -48,7 +50,7 @@ package body Synth.Static_Oper is
type Static_Arr_Type (Kind : Static_Arr_Kind) is record
case Kind is
when Sarr_Value =>
- Arr : Value_Array_Acc;
+ Arr : Memory_Ptr;
when Sarr_Net =>
N : Net;
end case;
@@ -60,9 +62,9 @@ package body Synth.Static_Oper is
begin
case V.Val.Kind is
when Value_Const =>
- return (Kind => Sarr_Value, Arr => V.Val.C_Val.Arr);
- when Value_Const_Array =>
- return (Kind => Sarr_Value, Arr => V.Val.Arr);
+ return (Kind => Sarr_Value, Arr => V.Val.C_Val.Mem);
+ when Value_Memory =>
+ return (Kind => Sarr_Value, Arr => V.Val.Mem);
when Value_Net =>
N := V.Val.N;
when Value_Wire =>
@@ -94,7 +96,7 @@ package body Synth.Static_Oper is
begin
case Sarr.Kind is
when Sarr_Value =>
- return Std_Ulogic'Val (Sarr.Arr.V (Iir_Index32 (Off + 1)).Scal);
+ return Std_Ulogic'Val (Read_U8 (Sarr.Arr + Size_Type (Off)));
when Sarr_Net =>
declare
Va : Uns32;
@@ -303,15 +305,15 @@ package body Synth.Static_Oper is
is
Larr : constant Static_Arr_Type := Get_Static_Array (Left);
Rarr : constant Static_Arr_Type := Get_Static_Array (Right);
- Arr : Value_Array_Acc;
+ Res : Valtyp;
begin
if Left.Typ.W /= Right.Typ.W then
Error_Msg_Synth (+Loc, "length of operands mismatch");
return No_Valtyp;
end if;
- Arr := Create_Value_Array (Iir_Index32 (Left.Typ.W));
- for I in Arr.V'Range loop
+ Res := Create_Value_Memory (Create_Res_Bound (Left.Typ));
+ for I in 1 .. Vec_Length (Res.Typ) loop
declare
Ls : constant Std_Ulogic :=
Get_Static_Std_Logic (Larr, Uns32 (I - 1));
@@ -319,11 +321,11 @@ package body Synth.Static_Oper is
Get_Static_Std_Logic (Rarr, Uns32 (I - 1));
V : constant Std_Ulogic := Op (Ls, Rs);
begin
- Arr.V (I) := Create_Value_Discrete (Std_Ulogic'Pos (V));
+ Write_U8 (Res.Val.Mem + Size_Type (I - 1), Std_Ulogic'Pos (V));
end;
end loop;
- return Create_Value_Const_Array (Create_Res_Bound (Left.Typ), Arr);
+ return Res;
end Synth_Vector_Dyadic;
procedure To_Std_Logic_Vector
@@ -333,8 +335,9 @@ package body Synth.Static_Oper is
begin
case Sarr.Kind is
when Sarr_Value =>
- for I in Val.Val.Arr.V'Range loop
- Arr (Natural (I)) := Std_Ulogic'Val (Val.Val.Arr.V (I).Scal);
+ for I in 1 .. Vec_Length (Val.Typ) loop
+ Arr (Natural (I)) :=
+ Std_Ulogic'Val (Read_U8 (Val.Val.Mem + Size_Type (I - 1)));
end loop;
when Sarr_Net =>
for I in Arr'Range loop
@@ -348,22 +351,21 @@ package body Synth.Static_Oper is
is
pragma Assert (Vec'First = 1);
Res_Typ : Type_Acc;
- Arr : Value_Array_Acc;
+ Res : Valtyp;
begin
Res_Typ := Create_Vec_Type_By_Length (Uns32 (Vec'Last), El_Typ);
- Arr := Create_Value_Array (Iir_Index32 (Vec'Last));
- for I in Vec'Range loop
- Arr.V (Iir_Index32 (I)) :=
- Create_Value_Discrete (Std_Ulogic'Pos (Vec (I)));
+ Res := Create_Value_Memory (Res_Typ);
+ for I in 1 .. Vec'Last loop
+ Write_U8 (Res.Val.Mem + Size_Type (I - 1), Std_Ulogic'Pos (Vec (I)));
end loop;
- return Create_Value_Const_Array (Res_Typ, Arr);
+ return Res;
end To_Valtyp;
function Synth_Add_Uns_Uns (L, R : Valtyp; Loc : Syn_Src) return Valtyp
is
pragma Unreferenced (Loc);
- L_Arr : Std_Logic_Vector (1 .. Natural (L.Val.Arr.Len));
- R_Arr : Std_Logic_Vector (1 .. Natural (R.Val.Arr.Len));
+ L_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (L.Typ)));
+ R_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (R.Typ)));
begin
To_Std_Logic_Vector (L, L_Arr);
To_Std_Logic_Vector (R, R_Arr);
@@ -377,8 +379,8 @@ package body Synth.Static_Oper is
function Synth_Add_Sgn_Int (L, R : Valtyp; Loc : Syn_Src) return Valtyp
is
pragma Unreferenced (Loc);
- L_Arr : Std_Logic_Vector (1 .. Natural (L.Val.Arr.Len));
- R_Val : constant Int64 := R.Val.Scal;
+ L_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (L.Typ)));
+ R_Val : constant Int64 := Read_Discrete (R);
begin
To_Std_Logic_Vector (L, L_Arr);
declare
@@ -392,7 +394,7 @@ package body Synth.Static_Oper is
is
pragma Unreferenced (Loc);
L_Arr : Std_Logic_Vector (1 .. Natural (L.Typ.W));
- R_Val : constant Uns64 := Uns64 (R.Val.Scal);
+ R_Val : constant Uns64 := Uns64 (Read_Discrete (R));
begin
To_Std_Logic_Vector (L, L_Arr);
declare
@@ -405,8 +407,8 @@ package body Synth.Static_Oper is
function Synth_Sub_Uns_Uns (L, R : Valtyp; Loc : Syn_Src) return Valtyp
is
pragma Unreferenced (Loc);
- L_Arr : Std_Logic_Vector (1 .. Natural (L.Val.Arr.Len));
- R_Arr : Std_Logic_Vector (1 .. Natural (R.Val.Arr.Len));
+ L_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (L.Typ)));
+ R_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (R.Typ)));
begin
To_Std_Logic_Vector (L, L_Arr);
To_Std_Logic_Vector (R, R_Arr);
@@ -420,8 +422,8 @@ package body Synth.Static_Oper is
function Synth_Sub_Uns_Nat (L, R : Valtyp; Loc : Syn_Src) return Valtyp
is
pragma Unreferenced (Loc);
- L_Arr : Std_Logic_Vector (1 .. Natural (L.Val.Arr.Len));
- R_Val : constant Uns64 := Uns64 (R.Val.Scal);
+ L_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (L.Typ)));
+ R_Val : constant Uns64 := Uns64 (Read_Discrete (R));
begin
To_Std_Logic_Vector (L, L_Arr);
declare
@@ -434,8 +436,8 @@ package body Synth.Static_Oper is
function Synth_Mul_Uns_Uns (L, R : Valtyp; Loc : Syn_Src) return Valtyp
is
pragma Unreferenced (Loc);
- L_Arr : Std_Logic_Vector (1 .. Natural (L.Val.Arr.Len));
- R_Arr : Std_Logic_Vector (1 .. Natural (R.Val.Arr.Len));
+ L_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (L.Typ)));
+ R_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (R.Typ)));
begin
To_Std_Logic_Vector (L, L_Arr);
To_Std_Logic_Vector (R, R_Arr);
@@ -449,8 +451,8 @@ package body Synth.Static_Oper is
function Synth_Mul_Nat_Uns (L, R : Valtyp; Loc : Syn_Src) return Valtyp
is
pragma Unreferenced (Loc);
- R_Arr : Std_Logic_Vector (1 .. Natural (R.Val.Arr.Len));
- L_Val : constant Uns64 := Uns64 (L.Val.Scal);
+ R_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (R.Typ)));
+ L_Val : constant Uns64 := Uns64 (Read_Discrete (L));
begin
To_Std_Logic_Vector (R, R_Arr);
declare
@@ -463,8 +465,8 @@ package body Synth.Static_Oper is
function Synth_Mul_Sgn_Sgn (L, R : Valtyp; Loc : Syn_Src) return Valtyp
is
pragma Unreferenced (Loc);
- L_Arr : Std_Logic_Vector (1 .. Natural (L.Val.Arr.Len));
- R_Arr : Std_Logic_Vector (1 .. Natural (R.Val.Arr.Len));
+ L_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (L.Typ)));
+ R_Arr : Std_Logic_Vector (1 .. Natural (Vec_Length (R.Typ)));
begin
To_Std_Logic_Vector (L, L_Arr);
To_Std_Logic_Vector (R, R_Arr);
@@ -480,7 +482,7 @@ package body Synth.Static_Oper is
Right : Boolean;
Arith : Boolean) return Valtyp
is
- Len : constant Uns32 := Uns32 (Val.Val.Arr.Len);
+ Len : constant Uns32 := Uns32 (Vec_Length (Val.Typ));
Arr : Std_Logic_Vector (1 .. Natural (Len));
Pad : Std_Ulogic;
begin
@@ -577,10 +579,11 @@ package body Synth.Static_Oper is
Res_Typ);
when Iir_Predefined_Integer_Rem =>
return Create_Value_Discrete
- (Left.Val.Scal rem Right.Val.Scal, Res_Typ);
+ (Read_Discrete (Left) rem Read_Discrete (Right), Res_Typ);
when Iir_Predefined_Integer_Exp =>
return Create_Value_Discrete
- (Left.Val.Scal ** Natural (Right.Val.Scal), Res_Typ);
+ (Read_Discrete (Left) ** Natural (Read_Discrete (Right)),
+ Res_Typ);
when Iir_Predefined_Physical_Minimum
| Iir_Predefined_Integer_Minimum =>
return Create_Value_Discrete
@@ -596,19 +599,23 @@ package body Synth.Static_Oper is
when Iir_Predefined_Integer_Less_Equal
| Iir_Predefined_Physical_Less_Equal =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Scal <= Right.Val.Scal), Boolean_Type);
+ (Boolean'Pos (Read_Discrete (Left) <= Read_Discrete (Right)),
+ Boolean_Type);
when Iir_Predefined_Integer_Less
| Iir_Predefined_Physical_Less =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Scal < Right.Val.Scal), Boolean_Type);
+ (Boolean'Pos (Read_Discrete (Left) < Read_Discrete (Right)),
+ Boolean_Type);
when Iir_Predefined_Integer_Greater_Equal
| Iir_Predefined_Physical_Greater_Equal =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Scal >= Right.Val.Scal), Boolean_Type);
+ (Boolean'Pos (Read_Discrete (Left) >= Read_Discrete (Right)),
+ Boolean_Type);
when Iir_Predefined_Integer_Greater
| Iir_Predefined_Physical_Greater =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Scal > Right.Val.Scal), Boolean_Type);
+ (Boolean'Pos (Read_Discrete (Left) > Read_Discrete (Right)),
+ Boolean_Type);
when Iir_Predefined_Integer_Equality
| Iir_Predefined_Physical_Equality =>
return Create_Value_Discrete
@@ -623,44 +630,57 @@ package body Synth.Static_Oper is
when Iir_Predefined_Physical_Real_Mul =>
return Create_Value_Discrete
- (Int64 (Fp64 (Left.Val.Scal) * Right.Val.Fp), Res_Typ);
+ (Int64 (Fp64 (Read_Discrete (Left)) * Read_Fp64 (Right)),
+ Res_Typ);
when Iir_Predefined_Real_Physical_Mul =>
return Create_Value_Discrete
- (Int64 (Left.Val.Fp * Fp64 (Right.Val.Scal)), Res_Typ);
+ (Int64 (Read_Fp64 (Left) * Fp64 (Read_Discrete (Right))),
+ Res_Typ);
when Iir_Predefined_Physical_Real_Div =>
return Create_Value_Discrete
- (Int64 (Fp64 (Left.Val.Scal) / Right.Val.Fp), Res_Typ);
+ (Int64 (Fp64 (Read_Discrete (Left)) / Read_Fp64 (Right)),
+ Res_Typ);
when Iir_Predefined_Floating_Less =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Fp < Right.Val.Fp), Boolean_Type);
+ (Boolean'Pos (Read_Fp64 (Left) < Read_Fp64 (Right)),
+ Boolean_Type);
when Iir_Predefined_Floating_Less_Equal =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Fp <= Right.Val.Fp), Boolean_Type);
+ (Boolean'Pos (Read_Fp64 (Left) <= Read_Fp64 (Right)),
+ Boolean_Type);
when Iir_Predefined_Floating_Equality =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Fp = Right.Val.Fp), Boolean_Type);
+ (Boolean'Pos (Read_Fp64 (Left) = Read_Fp64 (Right)),
+ Boolean_Type);
when Iir_Predefined_Floating_Inequality =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Fp /= Right.Val.Fp), Boolean_Type);
+ (Boolean'Pos (Read_Fp64 (Left) /= Read_Fp64 (Right)),
+ Boolean_Type);
when Iir_Predefined_Floating_Greater =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Fp > Right.Val.Fp), Boolean_Type);
+ (Boolean'Pos (Read_Fp64 (Left) > Read_Fp64 (Right)),
+ Boolean_Type);
when Iir_Predefined_Floating_Greater_Equal =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Fp >= Right.Val.Fp), Boolean_Type);
+ (Boolean'Pos (Read_Fp64 (Left) >= Read_Fp64 (Right)),
+ Boolean_Type);
when Iir_Predefined_Floating_Plus =>
- return Create_Value_Float (Left.Val.Fp + Right.Val.Fp, Res_Typ);
+ return Create_Value_Float (Read_Fp64 (Left) + Read_Fp64 (Right),
+ Res_Typ);
when Iir_Predefined_Floating_Minus =>
- return Create_Value_Float (Left.Val.Fp - Right.Val.Fp, Res_Typ);
+ return Create_Value_Float (Read_Fp64 (Left) - Read_Fp64 (Right),
+ Res_Typ);
when Iir_Predefined_Floating_Mul =>
- return Create_Value_Float (Left.Val.Fp * Right.Val.Fp, Res_Typ);
+ return Create_Value_Float (Read_Fp64 (Left) * Read_Fp64 (Right),
+ Res_Typ);
when Iir_Predefined_Floating_Div =>
- return Create_Value_Float (Left.Val.Fp / Right.Val.Fp, Res_Typ);
+ return Create_Value_Float (Read_Fp64 (Left) / Read_Fp64 (Right),
+ Res_Typ);
when Iir_Predefined_Floating_Exp =>
return Create_Value_Float
- (Left.Val.Fp ** Natural (Right.Val.Scal), Res_Typ);
+ (Read_Fp64 (Left) ** Natural (Read_Discrete (Right)), Res_Typ);
when Iir_Predefined_Array_Array_Concat =>
declare
@@ -674,78 +694,79 @@ package body Synth.Static_Oper is
R : constant Valtyp := Strip_Alias_Const (Right);
Bnd : Bound_Type;
Res_Typ : Type_Acc;
- Arr : Value_Array_Acc;
+ Res : Valtyp;
begin
Bnd := Oper.Create_Bounds_From_Length
(Syn_Inst, Get_Index_Type (Get_Type (Expr), 0),
L_Len + R_Len);
Res_Typ := Create_Onedimensional_Array_Subtype
(Ret_Typ, Bnd);
- Arr := Create_Value_Array (L_Len + R_Len);
- for I in 1 .. L_Len loop
- Arr.V (I) := L.Val.Arr.V (I);
- end loop;
- for I in 1 .. R_Len loop
- Arr.V (L_Len + I) := R.Val.Arr.V (I);
- end loop;
- return Create_Value_Const_Array (Res_Typ, Arr);
+ Res := Create_Value_Memory (Res_Typ);
+ if L.Typ.Sz > 0 then
+ Copy_Memory (Res.Val.Mem, L.Val.Mem, L.Typ.Sz);
+ end if;
+ if R.Typ.Sz > 0 then
+ Copy_Memory (Res.Val.Mem + L.Typ.Sz, R.Val.Mem, R.Typ.Sz);
+ end if;
+ return Res;
end;
when Iir_Predefined_Element_Array_Concat =>
declare
Ret_Typ : constant Type_Acc :=
Get_Subtype_Object (Syn_Inst, Get_Return_Type (Imp));
+ Rlen : constant Iir_Index32 :=
+ Get_Array_Flat_Length (Right.Typ);
Bnd : Bound_Type;
Res_Typ : Type_Acc;
- Arr : Value_Array_Acc;
+ Res : Valtyp;
begin
Bnd := Oper.Create_Bounds_From_Length
- (Syn_Inst, Get_Index_Type (Get_Type (Expr), 0),
- 1 + Right.Val.Arr.Len);
+ (Syn_Inst, Get_Index_Type (Get_Type (Expr), 0), 1 + Rlen);
Res_Typ := Create_Onedimensional_Array_Subtype
(Ret_Typ, Bnd);
- Arr := Create_Value_Array (1 + Right.Val.Arr.Len);
- Arr.V (1) := Left.Val;
- for I in Right.Val.Arr.V'Range loop
- Arr.V (1 + I) := Right.Val.Arr.V (I);
- end loop;
- return Create_Value_Const_Array (Res_Typ, Arr);
+ Res := Create_Value_Memory (Res_Typ);
+ Copy_Memory (Res.Val.Mem, Left.Val.Mem, Left.Typ.Sz);
+ Copy_Memory (Res.Val.Mem + Left.Typ.Sz,
+ Right.Val.Mem, Right.Typ.Sz);
+ return Res;
end;
when Iir_Predefined_Array_Element_Concat =>
declare
Ret_Typ : constant Type_Acc :=
Get_Subtype_Object (Syn_Inst, Get_Return_Type (Imp));
+ Llen : constant Iir_Index32 := Get_Array_Flat_Length (Left.Typ);
Bnd : Bound_Type;
Res_Typ : Type_Acc;
- Arr : Value_Array_Acc;
+ Res : Valtyp;
begin
Bnd := Oper.Create_Bounds_From_Length
- (Syn_Inst, Get_Index_Type (Get_Type (Expr), 0),
- Left.Val.Arr.Len + 1);
+ (Syn_Inst, Get_Index_Type (Get_Type (Expr), 0), Llen + 1);
Res_Typ := Create_Onedimensional_Array_Subtype
(Ret_Typ, Bnd);
- Arr := Create_Value_Array (Left.Val.Arr.Len + 1);
- for I in Left.Val.Arr.V'Range loop
- Arr.V (I) := Left.Val.Arr.V (I);
- end loop;
- Arr.V (Left.Val.Arr.Len + 1) := Right.Val;
- return Create_Value_Const_Array (Res_Typ, Arr);
+ Res := Create_Value_Memory (Res_Typ);
+ Copy_Memory (Res.Val.Mem, Left.Val.Mem, Left.Typ.Sz);
+ Copy_Memory (Res.Val.Mem + Left.Typ.Sz,
+ Right.Val.Mem, Right.Typ.Sz);
+ return Res;
end;
when Iir_Predefined_Array_Equality
| Iir_Predefined_Record_Equality =>
return Create_Value_Discrete
- (Boolean'Pos (Is_Equal (Left.Val, Right.Val)), Boolean_Type);
+ (Boolean'Pos (Is_Equal (Left, Right)), Boolean_Type);
when Iir_Predefined_Array_Inequality
| Iir_Predefined_Record_Inequality =>
return Create_Value_Discrete
- (Boolean'Pos (not Is_Equal (Left.Val, Right.Val)), Boolean_Type);
+ (Boolean'Pos (not Is_Equal (Left, Right)), Boolean_Type);
when Iir_Predefined_Access_Equality =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Acc = Right.Val.Acc), Boolean_Type);
+ (Boolean'Pos (Read_Access (Left) = Read_Access (Right)),
+ Boolean_Type);
when Iir_Predefined_Access_Inequality =>
return Create_Value_Discrete
- (Boolean'Pos (Left.Val.Acc /= Right.Val.Acc), Boolean_Type);
+ (Boolean'Pos (Read_Access (Left) /= Read_Access (Right)),
+ Boolean_Type);
when Iir_Predefined_Ieee_1164_Vector_And
| Iir_Predefined_Ieee_Numeric_Std_And_Uns_Uns
@@ -909,18 +930,20 @@ package body Synth.Static_Oper is
function Synth_Vector_Monadic
(Vec : Valtyp; Op : Table_1d) return Valtyp
is
- Arr : Value_Array_Acc;
+ Len : constant Iir_Index32 := Vec_Length (Vec.Typ);
+ Res : Valtyp;
begin
- Arr := Create_Value_Array (Vec.Val.Arr.Len);
- for I in Arr.V'Range loop
+ Res := Create_Value_Memory (Create_Res_Bound (Vec.Typ));
+ for I in 1 .. Len loop
declare
- V : constant Std_Ulogic := Std_Ulogic'Val (Vec.Val.Arr.V (I).Scal);
+ V : constant Std_Ulogic := Std_Ulogic'Val
+ (Read_U8 (Vec.Val.Mem + Size_Type (I - 1)));
begin
- Arr.V (I) := Create_Value_Discrete (Std_Ulogic'Pos (Op (V)));
+ Write_U8 (Res.Val.Mem + Size_Type (I - 1),
+ Std_Ulogic'Pos (Op (V)));
end;
end loop;
-
- return Create_Value_Const_Array (Create_Res_Bound (Vec.Typ), Arr);
+ return Res;
end Synth_Vector_Monadic;
function Synth_Vector_Reduce
@@ -930,10 +953,10 @@ package body Synth.Static_Oper is
Res : Std_Ulogic;
begin
Res := Init;
- for I in Vec.Val.Arr.V'Range loop
+ for I in 1 .. Vec_Length (Vec.Typ) loop
declare
V : constant Std_Ulogic :=
- Std_Ulogic'Val (Vec.Val.Arr.V (I).Scal);
+ Std_Ulogic'Val (Read_U8 (Vec.Val.Mem + Size_Type (I - 1)));
begin
Res := Op (Res, V);
end;
@@ -953,30 +976,30 @@ package body Synth.Static_Oper is
Get_Interface_Declaration_Chain (Imp);
Oper_Type : constant Node := Get_Type (Inter_Chain);
Oper_Typ : constant Type_Acc := Get_Subtype_Object (Syn_Inst, Oper_Type);
- -- Res_Typ : constant Type_Acc :=
- -- Get_Subtype_Object (Syn_Inst, Get_Type (Expr));
begin
case Def is
when Iir_Predefined_Boolean_Not
| Iir_Predefined_Bit_Not =>
- return Create_Value_Discrete (1 - Operand.Val.Scal, Oper_Typ);
+ return Create_Value_Discrete
+ (1 - Read_Discrete (Operand), Oper_Typ);
when Iir_Predefined_Integer_Negation
| Iir_Predefined_Physical_Negation =>
- return Create_Value_Discrete (-Operand.Val.Scal, Oper_Typ);
+ return Create_Value_Discrete (-Read_Discrete (Operand), Oper_Typ);
when Iir_Predefined_Integer_Absolute
| Iir_Predefined_Physical_Absolute =>
- return Create_Value_Discrete (abs Operand.Val.Scal, Oper_Typ);
+ return Create_Value_Discrete
+ (abs Read_Discrete(Operand), Oper_Typ);
when Iir_Predefined_Integer_Identity
| Iir_Predefined_Physical_Identity =>
return Operand;
when Iir_Predefined_Floating_Negation =>
- return Create_Value_Float (-Operand.Val.Fp, Oper_Typ);
+ return Create_Value_Float (-Read_Fp64 (Operand), Oper_Typ);
when Iir_Predefined_Floating_Identity =>
return Operand;
when Iir_Predefined_Floating_Absolute =>
- return Create_Value_Float (abs Operand.Val.Fp, Oper_Typ);
+ return Create_Value_Float (abs Read_Fp64 (Operand), Oper_Typ);
when Iir_Predefined_Ieee_1164_Condition_Operator =>
-- Constant std_logic: need to convert.
@@ -984,14 +1007,15 @@ package body Synth.Static_Oper is
Val : Uns32;
Zx : Uns32;
begin
- From_Std_Logic (Operand.Val.Scal, Val, Zx);
+ From_Std_Logic (Read_Discrete (Operand), Val, Zx);
return Create_Value_Discrete
(Boolean'Pos (Val = 1 and Zx = 0), Boolean_Type);
end;
when Iir_Predefined_Ieee_Numeric_Std_Neg_Sgn =>
declare
- Op_Arr : Std_Logic_Vector (1 .. Natural (Operand.Val.Arr.Len));
+ Op_Arr : Std_Logic_Vector
+ (1 .. Natural (Vec_Length (Operand.Typ)));
begin
To_Std_Logic_Vector (Operand, Op_Arr);
declare
@@ -1028,27 +1052,29 @@ package body Synth.Static_Oper is
is
Len : constant Iir_Index32 := Iir_Index32 (Sz);
El_Type : constant Type_Acc := Get_Array_Element (Res_Type);
- Arr : Value_Array_Acc;
+ Res : Valtyp;
Bnd : Type_Acc;
B : Uns64;
begin
- Arr := Create_Value_Array (Len);
+ Bnd := Create_Vec_Type_By_Length (Width (Len), El_Type);
+ Res := Create_Value_Memory (Bnd);
for I in 1 .. Len loop
B := Shift_Right_Arithmetic (Arg, Natural (I - 1)) and 1;
- Arr.V (Len - I + 1) := Create_Value_Discrete
- (Std_Logic_0_Pos + Int64 (B));
+ Write_U8 (Res.Val.Mem + Size_Type (Len - I),
+ Uns64'Pos (Std_Logic_0_Pos + B));
end loop;
- Bnd := Create_Vec_Type_By_Length (Width (Len), El_Type);
- return Create_Value_Const_Array (Bnd, Arr);
+ return Res;
end Eval_To_Vector;
function Eval_Unsigned_To_Integer (Arg : Valtyp; Loc : Node) return Int64
is
Res : Uns64;
+ V : Std_Ulogic;
begin
Res := 0;
- for I in Arg.Val.Arr.V'Range loop
- case To_X01 (Std_Ulogic'Val (Arg.Val.Arr.V (I).Scal)) is
+ for I in 1 .. Vec_Length (Arg.Typ) loop
+ V := Std_Ulogic'Val (Read_U8 (Arg.Val.Mem + Size_Type (I - 1)));
+ case To_X01 (V) is
when '0' =>
Res := Res * 2;
when '1' =>
@@ -1065,15 +1091,18 @@ package body Synth.Static_Oper is
function Eval_Signed_To_Integer (Arg : Valtyp; Loc : Node) return Int64
is
+ Len : constant Iir_Index32 := Vec_Length (Arg.Typ);
Res : Uns64;
+ E : Std_Ulogic;
begin
- if Arg.Val.Arr.Len = 0 then
+ if Len = 0 then
Warning_Msg_Synth
(+Loc, "numeric_std.to_integer: null detected, returning 0");
return 0;
end if;
- case To_X01 (Std_Ulogic'Val (Arg.Val.Arr.V (1).Scal)) is
+ E := Std_Ulogic'Val (Read_U8 (Arg.Val.Mem));
+ case To_X01 (E) is
when '0' =>
Res := 0;
when '1' =>
@@ -1082,8 +1111,9 @@ package body Synth.Static_Oper is
Warning_Msg_Synth (+Loc, "metavalue detected, returning 0");
return 0;
end case;
- for I in 2 .. Arg.Val.Arr.Len loop
- case To_X01 (Std_Ulogic'Val (Arg.Val.Arr.V (I).Scal)) is
+ for I in 2 .. Len loop
+ E := Std_Ulogic'Val (Read_U8 (Arg.Val.Mem + Size_Type (I - 1)));
+ case To_X01 (E) is
when '0' =>
Res := Res * 2;
when '1' =>
@@ -1138,11 +1168,13 @@ package body Synth.Static_Oper is
when Iir_Predefined_Ieee_Numeric_Std_Touns_Nat_Nat_Uns
| Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Unsigned_Int =>
return Eval_To_Vector
- (Uns64 (Param1.Val.Scal), Param2.Val.Scal, Res_Typ);
+ (Uns64 (Read_Discrete (Param1)), Read_Discrete (Param2),
+ Res_Typ);
when Iir_Predefined_Ieee_Numeric_Std_Tosgn_Int_Nat_Sgn
| Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Vector_Int =>
return Eval_To_Vector
- (To_Uns64 (Param1.Val.Scal), Param2.Val.Scal, Res_Typ);
+ (To_Uns64 (Read_Discrete (Param1)), Read_Discrete (Param2),
+ Res_Typ);
when Iir_Predefined_Ieee_Numeric_Std_Toint_Uns_Nat
| Iir_Predefined_Ieee_Std_Logic_Arith_Conv_Integer_Uns
| Iir_Predefined_Ieee_Std_Logic_Unsigned_Conv_Integer =>
@@ -1156,58 +1188,59 @@ package body Synth.Static_Oper is
when Iir_Predefined_Ieee_1164_To_Stdlogicvector_Bv =>
declare
+ use Grt.Types;
El_Type : constant Type_Acc := Get_Array_Element (Res_Typ);
- Arr : Value_Array_Acc;
+ Res : Valtyp;
Bnd : Type_Acc;
- B : Int64;
+ B : Ghdl_U8;
begin
- Arr := Create_Value_Array (Param1.Val.Arr.Len);
- for I in Param1.Val.Arr.V'Range loop
- if Param1.Val.Arr.V (I).Scal = 0 then
+ Bnd := Create_Vec_Type_By_Length
+ (Uns32 (Vec_Length (Param1.Typ)), El_Type);
+ Res := Create_Value_Memory (Bnd);
+ for I in 1 .. Vec_Length (Param1.Typ) loop
+ if Read_U8 (Param1.Val.Mem + Size_Type (I - 1)) = 0 then
B := Std_Logic_0_Pos;
else
B := Std_Logic_1_Pos;
end if;
- Arr.V (I) := Create_Value_Discrete (B);
+ Write_U8 (Res.Val.Mem + Size_Type (I - 1), B);
end loop;
- Bnd := Create_Vec_Type_By_Length
- (Width (Param1.Val.Arr.Len), El_Type);
- return Create_Value_Const_Array (Bnd, Arr);
+ return Res;
end;
when Iir_Predefined_Ieee_Math_Real_Log2 =>
declare
function Log2 (Arg : Fp64) return Fp64;
pragma Import (C, Log2);
begin
- return Create_Value_Float (Log2 (Param1.Val.Fp), Res_Typ);
+ return Create_Value_Float (Log2 (Read_Fp64 (Param1)), Res_Typ);
end;
when Iir_Predefined_Ieee_Math_Real_Ceil =>
declare
function Ceil (Arg : Fp64) return Fp64;
pragma Import (C, Ceil);
begin
- return Create_Value_Float (Ceil (Param1.Val.Fp), Res_Typ);
+ return Create_Value_Float (Ceil (Read_Fp64 (Param1)), Res_Typ);
end;
when Iir_Predefined_Ieee_Math_Real_Round =>
declare
function Round (Arg : Fp64) return Fp64;
pragma Import (C, Round);
begin
- return Create_Value_Float (Round (Param1.Val.Fp), Res_Typ);
+ return Create_Value_Float (Round (Read_Fp64 (Param1)), Res_Typ);
end;
when Iir_Predefined_Ieee_Math_Real_Sin =>
declare
function Sin (Arg : Fp64) return Fp64;
pragma Import (C, Sin);
begin
- return Create_Value_Float (Sin (Param1.Val.Fp), Res_Typ);
+ return Create_Value_Float (Sin (Read_Fp64 (Param1)), Res_Typ);
end;
when Iir_Predefined_Ieee_Math_Real_Cos =>
declare
function Cos (Arg : Fp64) return Fp64;
pragma Import (C, Cos);
begin
- return Create_Value_Float (Cos (Param1.Val.Fp), Res_Typ);
+ return Create_Value_Float (Cos (Read_Fp64 (Param1)), Res_Typ);
end;
when others =>
Error_Msg_Synth
diff --git a/src/synth/synth-static_proc.adb b/src/synth/synth-static_proc.adb
index be0475b4a..60388607b 100644
--- a/src/synth/synth-static_proc.adb
+++ b/src/synth/synth-static_proc.adb
@@ -32,8 +32,8 @@ package body Synth.Static_Proc is
Inter : constant Node := Get_Interface_Declaration_Chain (Imp);
Param : constant Valtyp := Get_Value (Syn_Inst, Inter);
begin
- Synth.Heap.Synth_Deallocate (Param.Val.Acc);
- Param.Val.Acc := Null_Heap_Index;
+ Synth.Heap.Synth_Deallocate (Read_Access (Param));
+ Write_Access (Param.Val.Mem, Null_Heap_Index);
end Synth_Deallocate;
procedure Synth_Static_Procedure (Syn_Inst : Synth_Instance_Acc;
diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb
index e2da5d317..952b19289 100644
--- a/src/synth/synth-stmts.adb
+++ b/src/synth/synth-stmts.adb
@@ -111,15 +111,15 @@ package body Synth.Stmts is
Pfx : Node;
Dest_Base : out Valtyp;
Dest_Typ : out Type_Acc;
- Dest_Off : out Uns32;
+ Dest_Off : out Value_Offsets;
Dest_Voff : out Net;
Dest_Rdwd : out Width) is
begin
case Get_Kind (Pfx) is
when Iir_Kind_Simple_Name =>
Synth_Assignment_Prefix (Syn_Inst, Get_Named_Entity (Pfx),
- Dest_Base, Dest_Typ, Dest_Off,
- Dest_Voff, Dest_Rdwd);
+ Dest_Base, Dest_Typ,
+ Dest_Off, Dest_Voff, Dest_Rdwd);
when Iir_Kind_Interface_Signal_Declaration
| Iir_Kind_Variable_Declaration
| Iir_Kind_Interface_Variable_Declaration
@@ -143,20 +143,19 @@ package body Synth.Stmts is
Dest_Off := Targ.Val.A_Off;
else
Dest_Base := Targ;
- Dest_Off := 0;
+ Dest_Off := (0, 0);
end if;
end;
when Iir_Kind_Function_Call =>
Dest_Base := Synth_Expression (Syn_Inst, Pfx);
Dest_Typ := Dest_Base.Typ;
- Dest_Off := 0;
+ Dest_Off := (0, 0);
Dest_Voff := No_Net;
Dest_Rdwd := 0;
when Iir_Kind_Indexed_Name =>
declare
Voff : Net;
- Off : Uns32;
- W : Width;
+ Off : Value_Offsets;
Dest_W : Width;
begin
Synth_Assignment_Prefix
@@ -164,12 +163,14 @@ package body Synth.Stmts is
Dest_Base, Dest_Typ, Dest_Off, Dest_Voff, Dest_Rdwd);
Strip_Const (Dest_Base);
Dest_W := Dest_Base.Typ.W;
- Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Typ, Voff, Off, W);
+ Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Typ, Voff, Off);
Dest_Typ := Get_Array_Element (Dest_Typ);
+ Dest_Off.Net_Off := Dest_Off.Net_Off + Off.Net_Off;
+ Dest_Off.Mem_Off := Dest_Off.Mem_Off + Off.Mem_Off;
+
if Voff /= No_Net then
- Dest_Off := Dest_Off + Off;
if Dest_Voff = No_Net then
Dest_Voff := Voff;
Dest_Rdwd := Dest_W;
@@ -177,23 +178,6 @@ package body Synth.Stmts is
Dest_Voff := Build_Addidx
(Get_Build (Syn_Inst), Dest_Voff, Voff);
end if;
- else
- Dest_Off := Dest_Off + Off;
-
- if Dest_Voff = No_Net then
- -- For constant objects, directly return the indexed
- -- object.
- if Dest_Base.Val.Kind
- in Value_Array .. Value_Const_Array
- then
- pragma Assert (Dest_Off = Off);
- Dest_Base.Val := Dest_Base.Val.Arr.V
- (Iir_Index32 ((Dest_W - Dest_Off) / W));
- Dest_Base.Typ := Dest_Typ;
- Dest_Off := 0;
- Dest_W := W;
- end if;
- end if;
end if;
end;
@@ -201,26 +185,16 @@ package body Synth.Stmts is
declare
Idx : constant Iir_Index32 :=
Get_Element_Position (Get_Named_Entity (Pfx));
- El_Typ : Type_Acc;
begin
Synth_Assignment_Prefix
(Syn_Inst, Get_Prefix (Pfx),
Dest_Base, Dest_Typ, Dest_Off, Dest_Voff, Dest_Rdwd);
- if Dest_Off /= 0 and then Dest_Voff /= No_Net then
- -- TODO.
- raise Internal_Error;
- end if;
- El_Typ := Dest_Typ.Rec.E (Idx + 1).Typ;
- Strip_Const (Dest_Base);
- if Dest_Base.Val.Kind = Value_Const_Record then
- -- Return the selected element.
- pragma Assert (Dest_Off = 0);
- Dest_Base.Val := Dest_Base.Val.Rec.V (Idx + 1);
- Dest_Base.Typ := El_Typ;
- else
- Dest_Off := Dest_Off + Dest_Typ.Rec.E (Idx + 1).Off;
- end if;
- Dest_Typ := El_Typ;
+ Dest_Off.Net_Off :=
+ Dest_Off.Net_Off + Dest_Typ.Rec.E (Idx + 1).Boff;
+ Dest_Off.Mem_Off :=
+ Dest_Off.Mem_Off + Dest_Typ.Rec.E (Idx + 1).Moff;
+
+ Dest_Typ := Dest_Typ.Rec.E (Idx + 1).Typ;
end;
when Iir_Kind_Slice_Name =>
@@ -229,8 +203,7 @@ package body Synth.Stmts is
El_Typ : Type_Acc;
Res_Bnd : Bound_Type;
Sl_Voff : Net;
- Sl_Off : Uns32;
- Wd : Uns32;
+ Sl_Off : Value_Offsets;
begin
Synth_Assignment_Prefix
(Syn_Inst, Get_Prefix (Pfx),
@@ -238,12 +211,14 @@ package body Synth.Stmts is
Strip_Const (Dest_Base);
Get_Onedimensional_Array_Bounds (Dest_Typ, Pfx_Bnd, El_Typ);
- Synth_Slice_Suffix (Syn_Inst, Pfx, Pfx_Bnd, El_Typ.W,
- Res_Bnd, Sl_Voff, Sl_Off, Wd);
+ Synth_Slice_Suffix (Syn_Inst, Pfx, Pfx_Bnd, El_Typ,
+ Res_Bnd, Sl_Voff, Sl_Off);
+
+ Dest_Off.Net_Off := Dest_Off.Net_Off + Sl_Off.Net_Off;
+ Dest_Off.Mem_Off := Dest_Off.Mem_Off + Sl_Off.Mem_Off;
if Sl_Voff /= No_Net then
-- Variable slice.
- Dest_Off := Dest_Off + Sl_Off;
if Dest_Voff /= No_Net then
Dest_Voff := Build_Addidx
(Get_Build (Syn_Inst), Dest_Voff, Sl_Voff);
@@ -251,46 +226,11 @@ package body Synth.Stmts is
Dest_Rdwd := Dest_Base.Typ.W;
Dest_Voff := Sl_Voff;
end if;
- Dest_Typ := Create_Slice_Type (Wd, El_Typ);
+ Dest_Typ := Create_Slice_Type (Res_Bnd.Len, El_Typ);
else
-- Fixed slice.
Dest_Typ := Create_Onedimensional_Array_Subtype
(Dest_Typ, Res_Bnd);
- if Dest_Voff /= No_Net then
- -- Slice of a memory.
- Dest_Off := Dest_Off + Sl_Off;
- else
- if Dest_Base.Val.Kind in Value_Array .. Value_Const_Array
- then
- declare
- Arr : Value_Array_Acc;
- Off : Iir_Index32;
- begin
- pragma Assert (Dest_Off = 0);
- Arr := Create_Value_Array
- (Iir_Index32 (Res_Bnd.Len));
- case Pfx_Bnd.Dir is
- when Iir_To =>
- Off := Iir_Index32
- (Res_Bnd.Left - Pfx_Bnd.Left);
- when Iir_Downto =>
- Off := Iir_Index32
- (Pfx_Bnd.Left - Res_Bnd.Left);
- end case;
- Arr.V := Dest_Base.Val.Arr.V
- (Off + 1 .. Off + Iir_Index32 (Res_Bnd.Len));
- if Dest_Base.Val.Kind = Value_Array then
- Dest_Base.Val := Create_Value_Array (Arr);
- else
- Dest_Base.Val := Create_Value_Const_Array (Arr);
- end if;
- Dest_Base.Typ := Dest_Typ;
- end;
- else
- -- Slice of a vector.
- Dest_Off := Dest_Off + Sl_Off;
- end if;
- end if;
end if;
end;
@@ -299,10 +239,10 @@ package body Synth.Stmts is
Synth_Assignment_Prefix
(Syn_Inst, Get_Prefix (Pfx),
Dest_Base, Dest_Typ, Dest_Off, Dest_Voff, Dest_Rdwd);
- if Dest_Off /= 0 and then Dest_Voff /= No_Net then
+ if Dest_Off /= (0, 0) and then Dest_Voff /= No_Net then
raise Internal_Error;
end if;
- Dest_Base := Heap.Synth_Dereference (Dest_Base.Val.Acc);
+ Dest_Base := Heap.Synth_Dereference (Read_Access (Dest_Base));
Dest_Typ := Dest_Base.Typ;
when others =>
@@ -320,8 +260,8 @@ package body Synth.Stmts is
case Kind is
when Target_Simple =>
-- For a simple target, the destination is known.
- Obj : Value_Acc;
- Off : Uns32;
+ Obj : Valtyp;
+ Off : Value_Offsets;
when Target_Aggregate =>
-- For an aggregate: the type is computed and the details will
-- be handled at the assignment.
@@ -377,7 +317,7 @@ package body Synth.Stmts is
declare
Base : Valtyp;
Typ : Type_Acc;
- Off : Uns32;
+ Off : Value_Offsets;
Voff : Net;
Rdwd : Width;
@@ -388,16 +328,16 @@ package body Synth.Stmts is
-- FIXME: check index.
return Target_Info'(Kind => Target_Simple,
Targ_Type => Typ,
- Obj => Base.Val,
+ Obj => Base,
Off => Off);
else
return Target_Info'(Kind => Target_Memory,
Targ_Type => Typ,
Mem_Obj => Base,
Mem_Mwidth => Rdwd,
- Mem_Moff => 0,
+ Mem_Moff => 0, -- Uns32 (Off.Mem_Off),
Mem_Voff => Voff,
- Mem_Doff => Off);
+ Mem_Doff => Off.Net_Off);
end if;
end;
when others =>
@@ -405,33 +345,6 @@ package body Synth.Stmts is
end case;
end Synth_Target;
- procedure Assign_Value (Targ : Value_Acc; Val : Value_Acc; Loc : Node) is
- begin
- case Targ.Kind is
- when Value_Discrete =>
- Targ.Scal := Val.Scal;
- when Value_Access =>
- Targ.Acc := Val.Acc;
- when Value_Const_Array
- | Value_Array =>
- declare
- Len : constant Iir_Index32 := Val.Arr.Len;
- begin
- for I in 1 .. Len loop
- Assign_Value (Targ.Arr.V (Targ.Arr.Len - Len + I),
- Val.Arr.V (I), Loc);
- end loop;
- end;
- when Value_Const_Record
- | Value_Record =>
- for I in Targ.Rec.V'Range loop
- Assign_Value (Targ.Rec.V (I), Val.Rec.V (I), Loc);
- end loop;
- when others =>
- raise Internal_Error;
- end case;
- end Assign_Value;
-
procedure Synth_Assignment (Syn_Inst : Synth_Instance_Acc;
Target : Target_Info;
Val : Valtyp;
@@ -446,15 +359,6 @@ package body Synth.Stmts is
El_Typ : constant Type_Acc := Get_Array_Element (Val.Typ);
begin
case Val.Val.Kind is
- when Value_Array
- | Value_Const_Array =>
- if Typ /= El_Typ then
- -- Sub-array (vhdl 2008) not yet supported.
- raise Internal_Error;
- end if;
- pragma Assert (Val.Typ.Vbound.Len >= Off);
- return (El_Typ,
- Val.Val.Arr.V (Iir_Index32 (Val.Typ.Vbound.Len - Off)));
when Value_Net
| Value_Wire =>
declare
@@ -515,17 +419,23 @@ package body Synth.Stmts is
Synth_Assignment_Aggregate
(Syn_Inst, Target.Aggr, Target.Targ_Type, Val, Loc);
when Target_Simple =>
- if Target.Obj.Kind = Value_Wire then
- Synth_Assign (Target.Obj.W, Target.Targ_Type,
- Val, Target.Off, Loc);
+ if Target.Obj.Val.Kind = Value_Wire then
+ Synth_Assign (Target.Obj.Val.W, Target.Targ_Type,
+ Val, Target.Off.Net_Off, Loc);
else
if not Is_Static (Val.Val) then
-- Maybe the error message is too cryptic ?
Error_Msg_Synth
(+Loc, "cannot assign a net to a static value");
else
- pragma Assert (Target.Off = 0);
- Assign_Value (Target.Obj, Strip_Const (Val.Val), Loc);
+ declare
+ V : Valtyp;
+ begin
+ V := Val;
+ Strip_Const (V);
+ Copy_Memory (Target.Obj.Val.Mem + Target.Off.Mem_Off,
+ V.Val.Mem, V.Typ.Sz);
+ end;
end if;
end if;
when Target_Memory =>
@@ -588,9 +498,8 @@ package body Synth.Stmts is
begin
case Targ.Kind is
when Target_Simple =>
- N := Build2_Extract (Get_Build (Syn_Inst),
- Get_Net ((Targ.Targ_Type, Targ.Obj)),
- Targ.Off, Targ.Targ_Type.W);
+ N := Build2_Extract (Get_Build (Syn_Inst), Get_Net (Targ.Obj),
+ Targ.Off.Net_Off, Targ.Targ_Type.W);
return Create_Value_Net (N, Targ.Targ_Type);
when Target_Aggregate =>
raise Internal_Error;
@@ -736,12 +645,12 @@ package body Synth.Stmts is
end if;
if Is_Static (Cond_Val.Val) then
Strip_Const (Cond_Val);
- if Cond_Val.Val.Scal = 1 then
+ if Read_Discrete (Cond_Val) = 1 then
-- True.
Synth_Sequential_Statements
(C, Get_Sequential_Statement_Chain (Stmt));
else
- pragma Assert (Cond_Val.Val.Scal = 0);
+ pragma Assert (Read_Discrete (Cond_Val) = 0);
if Is_Valid (Els) then
-- Else part
if Is_Null (Get_Condition (Els)) then
@@ -1101,7 +1010,7 @@ package body Synth.Stmts is
end Synth_Case_Statement_Dynamic;
procedure Synth_Case_Statement_Static_Array
- (C : in out Seq_Context; Stmt : Node; Sel : Value_Acc)
+ (C : in out Seq_Context; Stmt : Node; Sel : Valtyp)
is
Choices : constant Node := Get_Case_Statement_Alternative_Chain (Stmt);
Choice : Node;
@@ -1122,7 +1031,7 @@ package body Synth.Stmts is
when Iir_Kind_Choice_By_Expression =>
Sel_Expr := Get_Choice_Expression (Choice);
Sel_Val := Synth_Expression_With_Basetype (C.Inst, Sel_Expr);
- if Is_Equal (Sel_Val.Val, Sel) then
+ if Is_Equal (Sel_Val, Sel) then
Synth_Sequential_Statements (C, Stmts);
exit;
end if;
@@ -1200,10 +1109,11 @@ package body Synth.Stmts is
when Type_Bit
| Type_Logic
| Type_Discrete =>
- Synth_Case_Statement_Static_Scalar (C, Stmt, Sel.Val.Scal);
+ Synth_Case_Statement_Static_Scalar (C, Stmt,
+ Read_Discrete (Sel));
when Type_Vector
| Type_Array =>
- Synth_Case_Statement_Static_Array (C, Stmt, Sel.Val);
+ Synth_Case_Statement_Static_Array (C, Stmt, Sel);
when others =>
raise Internal_Error;
end case;
@@ -1581,12 +1491,12 @@ package body Synth.Stmts is
Nbr_Inout := Nbr_Inout + 1;
Infos (Nbr_Inout) := Info;
if Info.Kind = Target_Simple
- and then Is_Static (Info.Obj)
+ and then Is_Static (Info.Obj.Val)
then
- if Info.Off /= 0 then
- raise Internal_Error;
- end if;
- Val := (Info.Targ_Type, Info.Obj);
+ Val := Create_Value_Memory (Info.Targ_Type);
+ Copy_Memory (Val.Val.Mem,
+ Info.Obj.Val.Mem + Info.Off.Mem_Off,
+ Info.Targ_Type.Sz);
else
Val := Synth_Read (Caller_Inst, Info, Assoc);
end if;
@@ -1596,9 +1506,9 @@ package body Synth.Stmts is
raise Internal_Error;
end if;
Val := Create_Value_Alias
- (Info.Obj, Info.Off, Info.Targ_Type);
+ (Info.Obj.Val, Info.Off, Info.Targ_Type);
when Iir_Kind_Interface_File_Declaration =>
- Val := (Info.Targ_Type, Info.Obj);
+ Val := Info.Obj;
when Iir_Kind_Interface_Quantity_Declaration =>
raise Internal_Error;
end case;
@@ -1625,7 +1535,7 @@ package body Synth.Stmts is
-- Arguments are passed by copy.
if Is_Static (Val.Val) or else Get_Mode (Inter) = Iir_In_Mode
then
- Val.Val := Unshare (Val.Val, Current_Pool);
+ Val := Unshare (Val, Current_Pool);
else
-- Will be changed to a wire.
null;
@@ -2020,14 +1930,18 @@ package body Synth.Stmts is
end case;
end In_Range;
- procedure Update_Index (Rng : Discrete_Range_Type; Idx : in out Int64) is
+ procedure Update_Index (Rng : Discrete_Range_Type; V : in out Valtyp)
+ is
+ T : Int64;
begin
+ T := Read_Discrete (V);
case Rng.Dir is
when Iir_To =>
- Idx := Idx + 1;
+ T := T + 1;
when Iir_Downto =>
- Idx := Idx - 1;
+ T := T - 1;
end case;
+ Write_Discrete (V, T);
end Update_Index;
procedure Loop_Control_Init (C : Seq_Context; Stmt : Node)
@@ -2159,7 +2073,7 @@ package body Synth.Stmts is
Cond_Val := Synth_Expression (C.Inst, Cond);
Static_Cond := Is_Static_Val (Cond_Val.Val);
if Static_Cond then
- if Get_Static_Discrete (Cond_Val.Val) = 0 then
+ if Get_Static_Discrete (Cond_Val) = 0 then
-- Not executed.
return;
end if;
@@ -2215,7 +2129,7 @@ package body Synth.Stmts is
if Cond /= Null_Node then
Cond_Val := Synth_Expression (C.Inst, Cond);
pragma Assert (Is_Static_Val (Cond_Val.Val));
- if Get_Static_Discrete (Cond_Val.Val) = 0 then
+ if Get_Static_Discrete (Cond_Val) = 0 then
-- Not executed.
return;
end if;
@@ -2297,10 +2211,10 @@ package body Synth.Stmts is
Init_For_Loop_Statement (C, Stmt, Val);
- while In_Range (Val.Typ.Drange, Val.Val.Scal) loop
+ while In_Range (Val.Typ.Drange, Read_Discrete (Val)) loop
Synth_Sequential_Statements (C, Stmts);
- Update_Index (Val.Typ.Drange, Val.Val.Scal);
+ Update_Index (Val.Typ.Drange, Val);
Loop_Control_Update (C);
-- Constant exit.
@@ -2331,11 +2245,11 @@ package body Synth.Stmts is
Init_For_Loop_Statement (C, Stmt, Val);
- while In_Range (Val.Typ.Drange, Val.Val.Scal) loop
+ while In_Range (Val.Typ.Drange, Read_Discrete (Val)) loop
Synth_Sequential_Statements (C, Stmts);
C.S_En := True;
- Update_Index (Val.Typ.Drange, Val.Val.Scal);
+ Update_Index (Val.Typ.Drange, Val);
exit when Lc.S_Exit or Lc.S_Quit or C.Nbr_Ret > 0;
end loop;
@@ -2373,7 +2287,7 @@ package body Synth.Stmts is
Error_Msg_Synth (+Cond, "loop condition must be static");
exit;
end if;
- exit when Val.Val.Scal = 0;
+ exit when Read_Discrete (Val) = 0;
end if;
Synth_Sequential_Statements (C, Stmts);
@@ -2421,7 +2335,7 @@ package body Synth.Stmts is
if Cond /= Null_Node then
Val := Synth_Expression_With_Type (C.Inst, Cond, Boolean_Type);
pragma Assert (Is_Static (Val.Val));
- exit when Val.Val.Scal = 0;
+ exit when Read_Discrete (Val) = 0;
end if;
Synth_Sequential_Statements (C, Stmts);
@@ -2527,7 +2441,7 @@ package body Synth.Stmts is
Sev_V := 2;
end if;
else
- Sev_V := Natural (Sev.Val.Scal);
+ Sev_V := Natural (Read_Discrete (Sev));
end if;
case Sev_V is
when 0 =>
@@ -2543,7 +2457,7 @@ package body Synth.Stmts is
end case;
Put_Err ("): ");
- Put_Line_Err (Value_To_String (Rep.Val));
+ Put_Line_Err (Value_To_String (Rep));
end Synth_Static_Report;
procedure Synth_Static_Report_Statement
@@ -2564,7 +2478,7 @@ package body Synth.Stmts is
end if;
pragma Assert (Is_Static (Cond.Val));
Strip_Const (Cond);
- if Cond.Val.Scal = 1 then
+ if Read_Discrete (Cond) = 1 then
return;
end if;
Synth_Static_Report (C, Stmt);
@@ -2814,7 +2728,7 @@ package body Synth.Stmts is
return;
end if;
if Is_Static (Val.Val) then
- if Val.Val.Scal /= 1 then
+ if Read_Discrete (Val) /= 1 then
Error_Msg_Synth (+Stmt, "assertion failure");
end if;
return;
@@ -2962,7 +2876,7 @@ package body Synth.Stmts is
D_Arr (Nbr_States - 1) := Build_Const_UB32 (Build_Context, 0, 1);
end if;
- Res := Concat_Array (D_Arr);
+ Concat_Array (D_Arr.all, Res);
Free_Net_Array (D_Arr);
return Res;
@@ -3166,12 +3080,11 @@ package body Synth.Stmts is
if Icond /= Null_Node then
Cond := Synth_Expression (Syn_Inst, Icond);
Strip_Const (Cond);
- pragma Assert (Cond.Val.Kind = Value_Discrete);
else
-- It is the else generate.
Cond := No_Valtyp;
end if;
- if Cond = No_Valtyp or else Cond.Val.Scal = 1 then
+ if Cond = No_Valtyp or else Read_Discrete (Cond) = 1 then
Bod := Get_Generate_Statement_Body (Gen);
Apply_Block_Configuration
(Get_Generate_Block_Configuration (Bod), Bod);
@@ -3206,7 +3119,7 @@ package body Synth.Stmts is
Name := New_Sname_User (Get_Identifier (Stmt), Get_Sname (Syn_Inst));
- while In_Range (It_Rng.Drange, Val.Val.Scal) loop
+ while In_Range (It_Rng.Drange, Read_Discrete (Val)) loop
-- Find and apply the config block.
declare
Spec : Node;
@@ -3229,10 +3142,10 @@ package body Synth.Stmts is
end;
-- FIXME: get position ?
- Lname := New_Sname_Version (Uns32 (Val.Val.Scal), Name);
+ Lname := New_Sname_Version (Uns32 (Read_Discrete (Val)), Name);
Synth_Generate_Statement_Body (Syn_Inst, Bod, Lname, Iterator, Val);
- Update_Index (It_Rng.Drange, Val.Val.Scal);
+ Update_Index (It_Rng.Drange, Val);
end loop;
end Synth_For_Generate_Statement;
@@ -3343,12 +3256,12 @@ package body Synth.Stmts is
-- The value must be true
V := Synth_Expression_With_Type
(Syn_Inst, Get_Expression (Spec), Boolean_Type);
- if V.Val.Scal /= 1 then
+ if Read_Discrete (V) /= 1 then
return;
end if;
declare
- Off : Uns32;
+ Off : Value_Offsets;
Voff : Net;
Wd : Width;
N : Net;
@@ -3356,7 +3269,7 @@ package body Synth.Stmts is
Typ : Type_Acc;
begin
Synth_Assignment_Prefix (Syn_Inst, Sig, Base, Typ, Off, Voff, Wd);
- pragma Assert (Off = 0);
+ pragma Assert (Off = (0, 0));
pragma Assert (Voff = No_Net);
pragma Assert (Base.Val.Kind = Value_Wire);
pragma Assert (Base.Typ = Typ);
diff --git a/src/synth/synth-stmts.ads b/src/synth/synth-stmts.ads
index 6bd796c70..dbe0d03b1 100644
--- a/src/synth/synth-stmts.ads
+++ b/src/synth/synth-stmts.ads
@@ -37,14 +37,15 @@ package Synth.Stmts is
-- DEST_BASE is the base object. Can be the result, a net or an array
-- larger than the result.
-- DEST_TYP is the type of the result.
- -- DEST_OFF/DEST_VOFF is the offset in the base. DEST_OFF is used when
+ -- DEST_NET_OFF/DEST_MEM_OFF/DEST_VOFF are the offsets in the base.
+ -- DEST_NET_OFF is used when
-- the base is a net, while DEST_VOFF is set when the offset is dynamic.
-- DEST_RDWD is the width of what is extracted from the base.
procedure Synth_Assignment_Prefix (Syn_Inst : Synth_Instance_Acc;
Pfx : Node;
Dest_Base : out Valtyp;
Dest_Typ : out Type_Acc;
- Dest_Off : out Uns32;
+ Dest_Off : out Value_Offsets;
Dest_Voff : out Net;
Dest_Rdwd : out Width);
@@ -78,7 +79,7 @@ package Synth.Stmts is
-- For iterators.
function In_Range (Rng : Discrete_Range_Type; V : Int64) return Boolean;
- procedure Update_Index (Rng : Discrete_Range_Type; Idx : in out Int64);
+ procedure Update_Index (Rng : Discrete_Range_Type; V : in out Valtyp);
private
-- There are 2 execution mode:
diff --git a/src/synth/synth-values.adb b/src/synth/synth-values.adb
index 079d5638d..e0d56174b 100644
--- a/src/synth/synth-values.adb
+++ b/src/synth/synth-values.adb
@@ -20,6 +20,8 @@
with Ada.Unchecked_Conversion;
with System;
+with System.Storage_Elements;
+
with Mutils; use Mutils;
with Netlists.Utils;
@@ -36,26 +38,21 @@ package body Synth.Values is
function To_Value_Acc is new Ada.Unchecked_Conversion
(System.Address, Value_Acc);
- function To_Value_Array_Acc is new Ada.Unchecked_Conversion
- (System.Address, Values.Value_Array_Acc);
+
+ function "+" (L, R : Value_Offsets) return Value_Offsets is
+ begin
+ return (L.Net_Off + R.Net_Off, L.Mem_Off + R.Mem_Off);
+ end "+";
function Is_Static (Val : Value_Acc) return Boolean is
begin
case Val.Kind is
- when Value_Discrete
- | Value_Float =>
+ when Value_Memory =>
return True;
when Value_Net
| Value_Wire =>
return False;
- when Value_Const_Array
- | Value_Const_Record =>
- return True;
- when Value_Array
- | Value_Record =>
- return False;
- when Value_Access
- | Value_File =>
+ when Value_File =>
return True;
when Value_Alias =>
return Is_Static (Val.A_Obj);
@@ -67,21 +64,13 @@ package body Synth.Values is
function Is_Static_Val (Val : Value_Acc) return Boolean is
begin
case Val.Kind is
- when Value_Discrete
- | Value_Float =>
+ when Value_Memory =>
return True;
when Value_Net =>
return Netlists.Utils.Is_Const_Net (Val.N);
when Value_Wire =>
return Is_Const_Wire (Val.W);
- when Value_Const_Array
- | Value_Const_Record =>
- return True;
- when Value_Array
- | Value_Record =>
- return False;
- when Value_Access
- | Value_File =>
+ when Value_File =>
return True;
when Value_Const =>
return True;
@@ -120,7 +109,7 @@ package body Synth.Values is
when Value_Const =>
Res := Res.C_Val;
when Value_Alias =>
- if Res.A_Off /= 0 then
+ if Res.A_Off /= (0, 0) then
raise Internal_Error;
end if;
Res := Res.A_Obj;
@@ -135,12 +124,11 @@ package body Synth.Values is
return (V.Typ, Strip_Alias_Const (V.Val));
end Strip_Alias_Const;
- function Is_Equal (L, R : Value_Acc) return Boolean
+ function Is_Equal (L, R : Valtyp) return Boolean
is
- L1 : constant Value_Acc := Strip_Alias_Const (L);
- R1 : constant Value_Acc := Strip_Alias_Const (R);
+ L1 : constant Value_Acc := Strip_Alias_Const (L.Val);
+ R1 : constant Value_Acc := Strip_Alias_Const (R.Val);
begin
- pragma Unreferenced (L, R);
if L1.Kind /= R1.Kind then
return False;
end if;
@@ -149,22 +137,20 @@ package body Synth.Values is
end if;
case L1.Kind is
- when Value_Discrete =>
- return L1.Scal = R1.Scal;
- when Value_Float =>
- return L1.Fp = R1.Fp;
- when Value_Const_Array =>
- if L1.Arr.Len /= R1.Arr.Len then
+ when Value_Const =>
+ raise Internal_Error;
+ when Value_Memory =>
+ pragma Assert (R1.Kind = Value_Memory);
+ if L.Typ.Sz /= R.Typ.Sz then
return False;
end if;
- for I in L1.Arr.V'Range loop
- if not Is_Equal (L1.Arr.V (I), R1.Arr.V (I)) then
+ -- FIXME: not correct for records, not correct for floats!
+ for I in 1 .. L.Typ.Sz loop
+ if L1.Mem (I - 1) /= R1.Mem (I - 1) then
return False;
end if;
end loop;
return True;
- when Value_Const =>
- raise Internal_Error;
when others =>
-- TODO.
raise Internal_Error;
@@ -198,7 +184,7 @@ package body Synth.Values is
when Type_Slice =>
return Are_Types_Equal (L.Slice_El, R.Slice_El);
when Type_Array =>
- if L.Abounds.Len /= R.Abounds.Len then
+ if L.Abounds.Ndim /= R.Abounds.Ndim then
return False;
end if;
for I in L.Abounds.D'Range loop
@@ -270,6 +256,8 @@ package body Synth.Values is
begin
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Bit,
Is_Synth => True,
+ Al => 0,
+ Sz => 1,
W => 1)));
end Create_Bit_Type;
@@ -280,17 +268,32 @@ package body Synth.Values is
begin
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Logic,
Is_Synth => True,
+ Al => 0,
+ Sz => 1,
W => 1)));
end Create_Logic_Type;
- function Create_Discrete_Type (Rng : Discrete_Range_Type; W : Width)
+ function Create_Discrete_Type (Rng : Discrete_Range_Type;
+ Sz : Size_Type;
+ W : Width)
return Type_Acc
is
subtype Discrete_Type_Type is Type_Type (Type_Discrete);
function Alloc is new Areapools.Alloc_On_Pool_Addr (Discrete_Type_Type);
+ Al : Palign_Type;
begin
+ if Sz <= 1 then
+ Al := 0;
+ elsif Sz <= 4 then
+ Al := 2;
+ else
+ pragma Assert (Sz <= 8);
+ Al := 3;
+ end if;
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Discrete,
Is_Synth => True,
+ Al => Al,
+ Sz => Sz,
W => W,
Drange => Rng)));
end Create_Discrete_Type;
@@ -302,6 +305,8 @@ package body Synth.Values is
begin
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Float,
Is_Synth => True,
+ Al => 3,
+ Sz => 8,
W => 64,
Frange => Rng)));
end Create_Float_Type;
@@ -312,22 +317,29 @@ package body Synth.Values is
subtype Vector_Type_Type is Type_Type (Type_Vector);
function Alloc is new Areapools.Alloc_On_Pool_Addr (Vector_Type_Type);
begin
- return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Vector,
- Is_Synth => True,
- W => Bnd.Len,
- Vbound => Bnd,
- Vec_El => El_Type)));
+ return To_Type_Acc
+ (Alloc (Current_Pool, (Kind => Type_Vector,
+ Is_Synth => True,
+ Al => El_Type.Al,
+ Sz => El_Type.Sz * Size_Type (Bnd.Len),
+ W => Bnd.Len,
+ Vbound => Bnd,
+ Vec_El => El_Type)));
end Create_Vector_Type;
- function Create_Slice_Type (W : Width; El_Type : Type_Acc) return Type_Acc
+ function Create_Slice_Type (Len : Uns32; El_Type : Type_Acc)
+ return Type_Acc
is
subtype Slice_Type_Type is Type_Type (Type_Slice);
function Alloc is new Areapools.Alloc_On_Pool_Addr (Slice_Type_Type);
begin
- return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Slice,
- Is_Synth => El_Type.Is_Synth,
- W => W,
- Slice_El => El_Type)));
+ return To_Type_Acc (Alloc (Current_Pool,
+ (Kind => Type_Slice,
+ Is_Synth => El_Type.Is_Synth,
+ Al => El_Type.Al,
+ Sz => Size_Type (Len) * El_Type.Sz,
+ W => Len * El_Type.W,
+ Slice_El => El_Type)));
end Create_Slice_Type;
function Create_Vec_Type_By_Length (Len : Width; El : Type_Acc)
@@ -372,17 +384,20 @@ package body Synth.Values is
is
subtype Array_Type_Type is Type_Type (Type_Array);
function Alloc is new Areapools.Alloc_On_Pool_Addr (Array_Type_Type);
- W : Width;
+ L : Uns32;
begin
- W := El_Type.W;
+ L := 1;
for I in Bnd.D'Range loop
- W := W * Bnd.D (I).Len;
+ L := L * Bnd.D (I).Len;
end loop;
- return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Array,
- Is_Synth => El_Type.Is_Synth,
- W => W,
- Abounds => Bnd,
- Arr_El => El_Type)));
+ return To_Type_Acc (Alloc (Current_Pool,
+ (Kind => Type_Array,
+ Is_Synth => El_Type.Is_Synth,
+ Al => El_Type.Al,
+ Sz => El_Type.Sz * Size_Type (L),
+ W => El_Type.W * L,
+ Abounds => Bnd,
+ Arr_El => El_Type)));
end Create_Array_Type;
function Create_Unbounded_Array (Ndim : Dim_Type; El_Type : Type_Acc)
@@ -393,6 +408,8 @@ package body Synth.Values is
begin
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Unbounded_Array,
Is_Synth => El_Type.Is_Synth,
+ Al => El_Type.Al,
+ Sz => 0,
W => 0,
Uarr_Ndim => Ndim,
Uarr_El => El_Type)));
@@ -405,6 +422,8 @@ package body Synth.Values is
begin
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Unbounded_Vector,
Is_Synth => El_Type.Is_Synth,
+ Al => El_Type.Al,
+ Sz => 0,
W => 0,
Uvec_El => El_Type)));
end Create_Unbounded_Vector;
@@ -441,6 +460,23 @@ package body Synth.Values is
end case;
end Get_Array_Bound;
+ function Get_Range_Length (Rng : Discrete_Range_Type) return Uns32
+ is
+ Len : Int64;
+ begin
+ case Rng.Dir is
+ when Iir_To =>
+ Len := Rng.Right - Rng.Left + 1;
+ when Iir_Downto =>
+ Len := Rng.Left - Rng.Right + 1;
+ end case;
+ if Len < 0 then
+ return 0;
+ else
+ return Uns32 (Len);
+ end if;
+ end Get_Range_Length;
+
function Create_Rec_El_Array (Nels : Iir_Index32) return Rec_El_Array_Acc
is
use System;
@@ -468,22 +504,50 @@ package body Synth.Values is
return To_Rec_El_Array_Acc (Res);
end Create_Rec_El_Array;
- function Create_Record_Type (Els : Rec_El_Array_Acc; W : Width)
+ function Align (Off : Size_Type; Al : Palign_Type) return Size_Type
+ is
+ Mask : constant Size_Type := 2 ** Natural (Al) - 1;
+ begin
+ return (Off + Mask) and not Mask;
+ end Align;
+
+ function Create_Record_Type (Els : Rec_El_Array_Acc)
return Type_Acc
is
subtype Record_Type_Type is Type_Type (Type_Record);
function Alloc is new Areapools.Alloc_On_Pool_Addr (Record_Type_Type);
Is_Synth : Boolean;
+ W : Width;
+ Al : Palign_Type;
+ Sz : Size_Type;
begin
+ -- Layout the record.
Is_Synth := True;
+ Al := 0;
+ Sz := 0;
+ W := 0;
for I in Els.E'Range loop
- if not Els.E (I).Typ.Is_Synth then
- Is_Synth := False;
- exit;
- end if;
+ declare
+ E : Rec_El_Type renames Els.E (I);
+ begin
+ -- For nets.
+ E.Boff := W;
+ Is_Synth := Is_Synth and E.Typ.Is_Synth;
+ W := W + E.Typ.W;
+
+ -- For memory.
+ Al := Palign_Type'Max (Al, E.Typ.Al);
+ Sz := Align (Sz, E.Typ.Al);
+ E.Moff := Sz;
+ Sz := Sz + E.Typ.Sz;
+ end;
end loop;
+ Sz := Align (Sz, Al);
+
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Record,
Is_Synth => Is_Synth,
+ Al => Al,
+ Sz => Sz,
W => W,
Rec => Els)));
end Create_Record_Type;
@@ -495,6 +559,8 @@ package body Synth.Values is
begin
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_Access,
Is_Synth => False,
+ Al => 2,
+ Sz => 4,
W => 32,
Acc_Acc => Acc_Type)));
end Create_Access_Type;
@@ -506,6 +572,8 @@ package body Synth.Values is
begin
return To_Type_Acc (Alloc (Current_Pool, (Kind => Type_File,
Is_Synth => False,
+ Al => 2,
+ Sz => 4,
W => 32,
File_Typ => File_Type)));
end Create_File_Type;
@@ -543,54 +611,23 @@ package body Synth.Values is
return (Ntype, Create_Value_Net (N));
end Create_Value_Net;
- function Create_Value_Discrete (Val : Int64) return Value_Acc
- is
- subtype Value_Type_Discrete is Value_Type (Value_Discrete);
- function Alloc is new Areapools.Alloc_On_Pool_Addr (Value_Type_Discrete);
- begin
- return To_Value_Acc (Alloc (Current_Pool,
- (Kind => Value_Discrete, Scal => Val)));
- end Create_Value_Discrete;
-
- function Create_Value_Discrete (Val : Int64; Vtype : Type_Acc) return Valtyp
- is
- pragma Assert (Vtype /= null);
- begin
- return (Vtype, Create_Value_Discrete (Val));
- end Create_Value_Discrete;
-
- function Create_Value_Float (Val : Fp64) return Value_Acc
- is
- subtype Value_Type_Float is Value_Type (Value_Float);
- function Alloc is new Areapools.Alloc_On_Pool_Addr (Value_Type_Float);
- begin
- return To_Value_Acc (Alloc (Current_Pool,
- (Kind => Value_Float, Fp => Val)));
- end Create_Value_Float;
-
- function Create_Value_Float (Val : Fp64; Vtype : Type_Acc) return Valtyp
+ function Create_Value_Memory (Vtype : Type_Acc) return Valtyp
is
- pragma Assert (Vtype /= null);
- begin
- return (Vtype, Create_Value_Float (Val));
- end Create_Value_Float;
-
- function Create_Value_Access (Acc : Heap_Index) return Value_Acc
- is
- subtype Value_Type_Access is Value_Type (Value_Access);
- function Alloc is new Areapools.Alloc_On_Pool_Addr (Value_Type_Access);
- begin
- return To_Value_Acc (Alloc (Current_Pool,
- (Kind => Value_Access, Acc => Acc)));
- end Create_Value_Access;
-
- function Create_Value_Access (Vtype : Type_Acc; Acc : Heap_Index)
- return Valtyp
- is
- pragma Assert (Vtype /= null);
- begin
- return (Vtype, Create_Value_Access (Acc));
- end Create_Value_Access;
+ subtype Value_Type_Memory is Value_Type (Value_Memory);
+ function Alloc is new Areapools.Alloc_On_Pool_Addr (Value_Type_Memory);
+ function To_Memory_Ptr is new Ada.Unchecked_Conversion
+ (System.Address, Memory_Ptr);
+ V : Value_Acc;
+ M : System.Address;
+ begin
+ Areapools.Allocate (Current_Pool.all, M,
+ Vtype.Sz, Size_Type (2 ** Natural (Vtype.Al)));
+ V := To_Value_Acc
+ (Alloc (Current_Pool, Value_Type_Memory'(Kind => Value_Memory,
+ Mem => To_Memory_Ptr (M))));
+
+ return (Vtype, V);
+ end Create_Value_Memory;
function Create_Value_File (File : File_Index) return Value_Acc
is
@@ -609,79 +646,16 @@ package body Synth.Values is
return (Vtype, Create_Value_File (File));
end Create_Value_File;
- function Create_Value_Array (Len : Iir_Index32) return Value_Array_Acc
- is
- use System;
- subtype Data_Type is Values.Value_Array_Type (Len);
- Res : Address;
- begin
- -- Manually allocate the array to handle large arrays without
- -- creating a large temporary value.
- Areapools.Allocate
- (Current_Pool.all, Res,
- Data_Type'Size / Storage_Unit, Data_Type'Alignment);
-
- declare
- -- Discard the warnings for no pragma Import as we really want
- -- to use the default initialization.
- pragma Warnings (Off);
- Addr1 : constant Address := Res;
- Init : Data_Type;
- for Init'Address use Addr1;
- pragma Warnings (On);
- begin
- null;
- end;
-
- return To_Value_Array_Acc (Res);
- end Create_Value_Array;
-
- function Create_Value_Array (Arr : Value_Array_Acc) return Value_Acc
- is
- subtype Value_Type_Array is Value_Type (Value_Array);
- function Alloc is new Areapools.Alloc_On_Pool_Addr (Value_Type_Array);
-
- Res : Value_Acc;
+ function Vec_Length (Typ : Type_Acc) return Iir_Index32 is
begin
- Res := To_Value_Acc (Alloc (Current_Pool,
- (Kind => Value_Array, Arr => Arr)));
- return Res;
- end Create_Value_Array;
+ return Iir_Index32 (Typ.Vbound.Len);
+ end Vec_Length;
- function Create_Value_Array (Bounds : Type_Acc; Arr : Value_Array_Acc)
- return Valtyp
- is
- pragma Assert (Bounds /= null);
- begin
- return (Bounds, Create_Value_Array (Arr));
- end Create_Value_Array;
-
- function Create_Value_Const_Array (Arr : Value_Array_Acc) return Value_Acc
- is
- subtype Value_Type_Const_Array is Value_Type (Value_Const_Array);
- function Alloc is
- new Areapools.Alloc_On_Pool_Addr (Value_Type_Const_Array);
-
- Res : Value_Acc;
- begin
- Res := To_Value_Acc (Alloc (Current_Pool,
- (Kind => Value_Const_Array, Arr => Arr)));
- return Res;
- end Create_Value_Const_Array;
-
- function Create_Value_Const_Array (Bounds : Type_Acc; Arr : Value_Array_Acc)
- return Valtyp
- is
- pragma Assert (Bounds /= null);
- begin
- return (Bounds, Create_Value_Const_Array (Arr));
- end Create_Value_Const_Array;
-
- function Get_Array_Flat_Length (Typ : Type_Acc) return Width is
+ function Get_Array_Flat_Length (Typ : Type_Acc) return Iir_Index32 is
begin
case Typ.Kind is
when Type_Vector =>
- return Typ.Vbound.Len;
+ return Iir_Index32 (Typ.Vbound.Len);
when Type_Array =>
declare
Len : Width;
@@ -690,91 +664,26 @@ package body Synth.Values is
for I in Typ.Abounds.D'Range loop
Len := Len * Typ.Abounds.D (I).Len;
end loop;
- return Len;
+ return Iir_Index32 (Len);
end;
when others =>
raise Internal_Error;
end case;
end Get_Array_Flat_Length;
- procedure Create_Array_Data (Arr : Valtyp)
- is
- Len : Width;
- begin
- case Arr.Typ.Kind is
- when Type_Array =>
- Len := Get_Array_Flat_Length (Arr.Typ);
- when Type_Vector =>
- Len := Arr.Typ.Vbound.Len;
- when others =>
- raise Internal_Error;
- end case;
-
- Arr.Val.Arr := Create_Value_Array (Iir_Index32 (Len));
- end Create_Array_Data;
-
- function Create_Value_Array (Bounds : Type_Acc) return Value_Acc
- is
- Res : Value_Acc;
- begin
- Res := Create_Value_Array (Value_Array_Acc'(null));
- Create_Array_Data ((Bounds, Res));
- return Res;
- end Create_Value_Array;
-
- function Create_Value_Record (Els : Value_Array_Acc) return Value_Acc
- is
- subtype Value_Type_Record is Value_Type (Value_Record);
- function Alloc is new Areapools.Alloc_On_Pool_Addr (Value_Type_Record);
- begin
- return To_Value_Acc (Alloc (Current_Pool,
- (Kind => Value_Record,
- Rec => Els)));
- end Create_Value_Record;
-
- function Create_Value_Record (Typ : Type_Acc; Els : Value_Array_Acc)
- return Valtyp
- is
- pragma Assert (Typ /= null);
- begin
- return (Typ, Create_Value_Record (Els));
- end Create_Value_Record;
-
- function Create_Value_Const_Record (Els : Value_Array_Acc) return Value_Acc
- is
- subtype Value_Type_Const_Record is Value_Type (Value_Const_Record);
- function Alloc is
- new Areapools.Alloc_On_Pool_Addr (Value_Type_Const_Record);
- begin
- return To_Value_Acc (Alloc (Current_Pool,
- (Kind => Value_Const_Record, Rec => Els)));
- end Create_Value_Const_Record;
-
- function Create_Value_Const_Record (Typ : Type_Acc; Els : Value_Array_Acc)
- return Valtyp
+ function Create_Value_Alias
+ (Obj : Value_Acc; Off : Value_Offsets; Typ : Type_Acc) return Valtyp
is
pragma Assert (Typ /= null);
- begin
- return (Typ, Create_Value_Const_Record (Els));
- end Create_Value_Const_Record;
-
- function Create_Value_Alias (Obj : Value_Acc; Off : Uns32) return Value_Acc
- is
subtype Value_Type_Alias is Value_Type (Value_Alias);
function Alloc is new Areapools.Alloc_On_Pool_Addr (Value_Type_Alias);
+ Val : Value_Acc;
begin
- return To_Value_Acc (Alloc (Current_Pool,
+ Val := To_Value_Acc (Alloc (Current_Pool,
(Kind => Value_Alias,
A_Obj => Obj,
A_Off => Off)));
- end Create_Value_Alias;
-
- function Create_Value_Alias (Obj : Value_Acc; Off : Uns32; Typ : Type_Acc)
- return Valtyp
- is
- pragma Assert (Typ /= null);
- begin
- return (Typ, Create_Value_Alias (Obj, Off));
+ return (Typ, Val);
end Create_Value_Alias;
function Create_Value_Const (Val : Value_Acc; Loc : Syn_Src)
@@ -797,70 +706,45 @@ package body Synth.Values is
return (Val.Typ, Create_Value_Const (Val.Val, Loc));
end Create_Value_Const;
- procedure Strip_Const (Val : in out Value_Acc) is
- begin
- if Val.Kind = Value_Const then
- Val := Val.C_Val;
- end if;
- end Strip_Const;
-
- function Strip_Const (Val : Value_Acc) return Value_Acc is
+ procedure Strip_Const (Vt : in out Valtyp) is
begin
- if Val.Kind = Value_Const then
- return Val.C_Val;
- else
- return Val;
+ if Vt.Val.Kind = Value_Const then
+ Vt.Val := Vt.Val.C_Val;
end if;
end Strip_Const;
- procedure Strip_Const (Vt : in out Valtyp) is
+ procedure Copy_Memory (Dest : Memory_Ptr; Src : Memory_Ptr; Sz : Size_Type)
+ is
begin
- Vt.Val := Strip_Const (Vt.Val);
- end Strip_Const;
-
- function Copy (Src : Value_Acc) return Value_Acc;
+ for I in 1 .. Sz loop
+ Dest (I - 1) := Src (I - 1);
+ end loop;
+ end Copy_Memory;
- function Copy_Array (Arr : Value_Array_Acc) return Value_Array_Acc
+ procedure Write_Value (Dest : Memory_Ptr; Vt : Valtyp)
is
- Res : Value_Array_Acc;
+ Mt : Memtyp;
begin
- Res := Create_Value_Array (Arr.Len);
- for I in Res.V'Range loop
- Res.V (I) := Copy (Arr.V (I));
- end loop;
- return Res;
- end Copy_Array;
+ Mt := Get_Memtyp (Vt);
+ Copy_Memory (Dest, Mt.Mem, Mt.Typ.Sz);
+ end Write_Value;
- function Copy (Src : Value_Acc) return Value_Acc
+ function Copy (Src : Valtyp) return Valtyp
is
- Res : Value_Acc;
- Arr : Value_Array_Acc;
+ Res : Valtyp;
begin
- case Src.Kind is
+ case Src.Val.Kind is
+ when Value_Memory =>
+ Res := Create_Value_Memory (Src.Typ);
+ for I in 1 .. Src.Typ.Sz loop
+ Res.Val.Mem (I - 1) := Src.Val.Mem (I - 1);
+ end loop;
when Value_Net =>
- Res := Create_Value_Net (Src.N);
+ Res := Create_Value_Net (Src.Val.N, Src.Typ);
when Value_Wire =>
- Res := Create_Value_Wire (Src.W);
- when Value_Discrete =>
- Res := Create_Value_Discrete (Src.Scal);
- when Value_Float =>
- Res := Create_Value_Float (Src.Fp);
- when Value_Array =>
- Arr := Copy_Array (Src.Arr);
- Res := Create_Value_Array (Arr);
- when Value_Const_Array =>
- Arr := Copy_Array (Src.Arr);
- Res := Create_Value_Const_Array (Arr);
- when Value_Record =>
- Arr := Copy_Array (Src.Rec);
- Res := Create_Value_Record (Arr);
- when Value_Const_Record =>
- Arr := Copy_Array (Src.Rec);
- Res := Create_Value_Const_Record (Arr);
- when Value_Access =>
- Res := Create_Value_Access (Src.Acc);
+ Res := Create_Value_Wire (Src.Val.W, Src.Typ);
when Value_File =>
- Res := Create_Value_File (Src.File);
+ Res := Create_Value_File (Src.Typ, Src.Val.File);
when Value_Const =>
raise Internal_Error;
when Value_Alias =>
@@ -869,11 +753,10 @@ package body Synth.Values is
return Res;
end Copy;
- function Unshare (Src : Value_Acc; Pool : Areapool_Acc)
- return Value_Acc
+ function Unshare (Src : Valtyp; Pool : Areapool_Acc) return Valtyp
is
Prev_Pool : constant Areapool_Acc := Current_Pool;
- Res : Value_Acc;
+ Res : Valtyp;
begin
Current_Pool := Pool;
Res := Copy (Src);
@@ -939,27 +822,240 @@ package body Synth.Values is
end case;
end Is_Matching_Bounds;
- function Create_Value_Default (Typ : Type_Acc) return Value_Acc is
+ type Ghdl_U8_Ptr is access all Ghdl_U8;
+ function To_U8_Ptr is
+ new Ada.Unchecked_Conversion (Memory_Ptr, Ghdl_U8_Ptr);
+
+ procedure Write_U8 (Mem : Memory_Ptr; Val : Ghdl_U8) is
+ begin
+ To_U8_Ptr (Mem).all := Val;
+ end Write_U8;
+
+ function Read_U8 (Mem : Memory_Ptr) return Ghdl_U8 is
+ begin
+ return To_U8_Ptr (Mem).all;
+ end Read_U8;
+
+ type Ghdl_I32_Ptr is access all Ghdl_I32;
+ function To_I32_Ptr is
+ new Ada.Unchecked_Conversion (Memory_Ptr, Ghdl_I32_Ptr);
+
+ procedure Write_I32 (Mem : Memory_Ptr; Val : Ghdl_I32) is
+ begin
+ To_I32_Ptr (Mem).all := Val;
+ end Write_I32;
+
+ function Read_I32 (Mem : Memory_Ptr) return Ghdl_I32 is
+ begin
+ return To_I32_Ptr (Mem).all;
+ end Read_I32;
+
+ type Ghdl_U32_Ptr is access all Ghdl_U32;
+ function To_U32_Ptr is
+ new Ada.Unchecked_Conversion (Memory_Ptr, Ghdl_U32_Ptr);
+
+ procedure Write_U32 (Mem : Memory_Ptr; Val : Ghdl_U32) is
+ begin
+ To_U32_Ptr (Mem).all := Val;
+ end Write_U32;
+
+ function Read_U32 (Mem : Memory_Ptr) return Ghdl_U32 is
+ begin
+ return To_U32_Ptr (Mem).all;
+ end Read_U32;
+
+ type Ghdl_I64_Ptr is access all Ghdl_I64;
+ function To_I64_Ptr is
+ new Ada.Unchecked_Conversion (Memory_Ptr, Ghdl_I64_Ptr);
+
+ procedure Write_I64 (Mem : Memory_Ptr; Val : Ghdl_I64) is
+ begin
+ To_I64_Ptr (Mem).all := Val;
+ end Write_I64;
+
+ function Read_I64 (Mem : Memory_Ptr) return Ghdl_I64 is
+ begin
+ return To_I64_Ptr (Mem).all;
+ end Read_I64;
+
+ type Fp64_Ptr is access all Fp64;
+ function To_Fp64_Ptr is
+ new Ada.Unchecked_Conversion (Memory_Ptr, Fp64_Ptr);
+
+ procedure Write_Fp64 (Mem : Memory_Ptr; Val : Fp64) is
+ begin
+ To_Fp64_Ptr (Mem).all := Val;
+ end Write_Fp64;
+
+ function Read_Fp64 (Mem : Memory_Ptr) return Fp64 is
+ begin
+ return To_Fp64_Ptr (Mem).all;
+ end Read_Fp64;
+
+ type Heap_Index_Ptr is access all Heap_Index;
+ function To_Heap_Index_Ptr is
+ new Ada.Unchecked_Conversion (Memory_Ptr, Heap_Index_Ptr);
+
+ procedure Write_Access (Mem : Memory_Ptr; Val : Heap_Index) is
+ begin
+ To_Heap_Index_Ptr (Mem).all := Val;
+ end Write_Access;
+
+ function Read_Access (Mem : Memory_Ptr) return Heap_Index is
+ begin
+ return To_Heap_Index_Ptr (Mem).all;
+ end Read_Access;
+
+ function "+" (Base : Memory_Ptr; Off : Size_Type) return Memory_Ptr
+ is
+ use System.Storage_Elements;
+
+ function To_Address is new Ada.Unchecked_Conversion
+ (Memory_Ptr, System.Address);
+ function To_Memory_Ptr is new Ada.Unchecked_Conversion
+ (System.Address, Memory_Ptr);
+ begin
+ return To_Memory_Ptr (To_Address (Base) + Storage_Offset (Off));
+ end "+";
+
+ procedure Write_Discrete (Mem : Memory_Ptr; Typ : Type_Acc; Val : Int64) is
+ begin
+ case Typ.Sz is
+ when 1 =>
+ Write_U8 (Mem, Ghdl_U8 (Val));
+ when 4 =>
+ Write_I32 (Mem, Ghdl_I32 (Val));
+ when 8 =>
+ Write_I64 (Mem, Ghdl_I64 (Val));
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Write_Discrete;
+
+ procedure Write_Discrete (Vt : Valtyp; Val : Int64) is
+ begin
+ Write_Discrete (Vt.Val.Mem, Vt.Typ, Val);
+ end Write_Discrete;
+
+ function Read_Discrete (Mem : Memory_Ptr; Typ : Type_Acc) return Int64 is
+ begin
+ case Typ.Sz is
+ when 1 =>
+ return Int64 (Read_U8 (Mem));
+ when 4 =>
+ return Int64 (Read_I32 (Mem));
+ when 8 =>
+ return Int64 (Read_I64 (Mem));
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Read_Discrete;
+
+ function Read_Discrete (Vt : Valtyp) return Int64 is
+ begin
+ return Read_Discrete (Vt.Val.Mem, Vt.Typ);
+ end Read_Discrete;
+
+ function Create_Value_Float (Val : Fp64; Vtype : Type_Acc) return Valtyp
+ is
+ Res : Valtyp;
+ pragma Assert (Vtype /= null);
+ begin
+ Res := Create_Value_Memory (Vtype);
+ Write_Fp64 (Res.Val.Mem, Val);
+ return Res;
+ end Create_Value_Float;
+
+ function Read_Fp64 (Vt : Valtyp) return Fp64 is
+ begin
+ pragma Assert (Vt.Typ.Kind = Type_Float);
+ pragma Assert (Vt.Typ.Sz = 8);
+ return Read_Fp64 (Vt.Val.Mem);
+ end Read_Fp64;
+
+ function Read_Access (Vt : Valtyp) return Heap_Index is
+ begin
+ pragma Assert (Vt.Typ.Kind = Type_Access);
+ return Read_Access (Vt.Val.Mem);
+ end Read_Access;
+
+ function Create_Value_Discrete (Val : Int64; Vtype : Type_Acc) return Valtyp
+ is
+ Res : Valtyp;
+ begin
+ Res := Create_Value_Memory (Vtype);
+ case Vtype.Sz is
+ when 1 =>
+ Write_U8 (Res.Val.Mem, Ghdl_U8 (Val));
+ when 4 =>
+ Write_I32 (Res.Val.Mem, Ghdl_I32 (Val));
+ when 8 =>
+ Write_I64 (Res.Val.Mem, Ghdl_I64 (Val));
+ when others =>
+ raise Internal_Error;
+ end case;
+ return Res;
+ end Create_Value_Discrete;
+
+ function Create_Value_Uns (Val : Uns64; Vtype : Type_Acc) return Valtyp
+ is
+ Res : Valtyp;
+ begin
+ Res := Create_Value_Memory (Vtype);
+ case Vtype.Sz is
+ when 1 =>
+ Write_U8 (Res.Val.Mem, Ghdl_U8 (Val));
+ when 4 =>
+ Write_U32 (Res.Val.Mem, Ghdl_U32 (Val));
+ when others =>
+ raise Internal_Error;
+ end case;
+ return Res;
+ end Create_Value_Uns;
+
+ pragma Unreferenced (Read_U32);
+
+ function Create_Value_Int (Val : Int64; Vtype : Type_Acc) return Valtyp
+ is
+ Res : Valtyp;
+ begin
+ Res := Create_Value_Memory (Vtype);
+ case Vtype.Sz is
+ when 4 =>
+ Write_I32 (Res.Val.Mem, Ghdl_I32 (Val));
+ when 8 =>
+ Write_I64 (Res.Val.Mem, Ghdl_I64 (Val));
+ when others =>
+ raise Internal_Error;
+ end case;
+ return Res;
+ end Create_Value_Int;
+
+ function Arr_Index (M : Memory_Ptr; Idx : Iir_Index32; El_Typ : Type_Acc)
+ return Memory_Ptr is
+ begin
+ return M + Size_Type (Idx) * El_Typ.Sz;
+ end Arr_Index;
+
+ procedure Write_Value_Default (M : Memory_Ptr; Typ : Type_Acc) is
begin
case Typ.Kind is
when Type_Bit
| Type_Logic =>
-- FIXME: what about subtype ?
- return Create_Value_Discrete (0);
+ Write_U8 (M, 0);
when Type_Discrete =>
- return Create_Value_Discrete (Typ.Drange.Left);
+ Write_Discrete (M, Typ, Typ.Drange.Left);
when Type_Float =>
- return Create_Value_Float (Typ.Frange.Left);
+ Write_Fp64 (M, Typ.Frange.Left);
when Type_Vector =>
declare
+ Len : constant Iir_Index32 := Vec_Length (Typ);
El_Typ : constant Type_Acc := Typ.Vec_El;
- Arr : Value_Array_Acc;
begin
- Arr := Create_Value_Array (Iir_Index32 (Typ.Vbound.Len));
- for I in Arr.V'Range loop
- Arr.V (I) := Create_Value_Default (El_Typ);
+ for I in 1 .. Len loop
+ Write_Value_Default (Arr_Index (M, I - 1, El_Typ), El_Typ);
end loop;
- return Create_Value_Const_Array (Arr);
end;
when Type_Unbounded_Vector =>
raise Internal_Error;
@@ -967,50 +1063,78 @@ package body Synth.Values is
raise Internal_Error;
when Type_Array =>
declare
- El_Typ : constant Type_Acc := Get_Array_Element (Typ);
- Arr : Value_Array_Acc;
+ Len : constant Iir_Index32 := Get_Array_Flat_Length (Typ);
+ El_Typ : constant Type_Acc := Typ.Arr_El;
begin
- Arr := Create_Value_Array
- (Iir_Index32 (Get_Array_Flat_Length (Typ)));
- for I in Arr.V'Range loop
- Arr.V (I) := Create_Value_Default (El_Typ);
+ for I in 1 .. Len loop
+ Write_Value_Default (Arr_Index (M, I - 1, El_Typ), El_Typ);
end loop;
- return Create_Value_Const_Array (Arr);
end;
when Type_Unbounded_Array =>
raise Internal_Error;
when Type_Record =>
- declare
- Els : Value_Array_Acc;
- begin
- Els := Create_Value_Array (Typ.Rec.Len);
- for I in Els.V'Range loop
- Els.V (I) := Create_Value_Default (Typ.Rec.E (I).Typ);
- end loop;
- return Create_Value_Const_Record (Els);
- end;
+ for I in Typ.Rec.E'Range loop
+ Write_Value_Default (M + Typ.Rec.E (I).Moff, Typ.Rec.E (I).Typ);
+ end loop;
when Type_Access =>
- return Create_Value_Access (Null_Heap_Index);
+ Write_Access (M, Null_Heap_Index);
when Type_File =>
raise Internal_Error;
end case;
- end Create_Value_Default;
+ end Write_Value_Default;
- function Create_Value_Default (Typ : Type_Acc) return Valtyp is
+ function Create_Value_Default (Typ : Type_Acc) return Valtyp
+ is
+ Res : Valtyp;
begin
- return (Typ, Create_Value_Default (Typ));
+ Res := Create_Value_Memory (Typ);
+ Write_Value_Default (Res.Val.Mem, Typ);
+ return Res;
end Create_Value_Default;
- function Value_To_String (Val : Value_Acc) return String
+ function Create_Value_Access (Val : Heap_Index; Acc_Typ : Type_Acc)
+ return Valtyp
is
- Str : String (1 .. Natural (Val.Arr.Len));
+ Res : Valtyp;
begin
- for I in Val.Arr.V'Range loop
- Str (Natural (I)) := Character'Val (Val.Arr.V (I).Scal);
+ Res := Create_Value_Memory (Acc_Typ);
+ Write_Access (Res.Val.Mem, Val);
+ return Res;
+ end Create_Value_Access;
+
+ function Value_To_String (Val : Valtyp) return String
+ is
+ Str : String (1 .. Natural (Val.Typ.Abounds.D (1).Len));
+ begin
+ for I in Str'Range loop
+ Str (Natural (I)) := Character'Val
+ (Read_U8 (Val.Val.Mem + Size_Type (I - 1)));
end loop;
return Str;
end Value_To_String;
+ function Get_Memtyp (V : Valtyp) return Memtyp is
+ begin
+ case V.Val.Kind is
+ when Value_Net
+ | Value_Wire =>
+ raise Internal_Error;
+ when Value_Memory =>
+ return (V.Typ, V.Val.Mem);
+ when Value_Alias =>
+ declare
+ T : Memtyp;
+ begin
+ T := Get_Memtyp ((V.Typ, V.Val.A_Obj));
+ return (T.Typ, T.Mem + V.Val.A_Off.Mem_Off);
+ end;
+ when Value_Const =>
+ return Get_Memtyp ((V.Typ, V.Val.C_Val));
+ when Value_File =>
+ raise Internal_Error;
+ end case;
+ end Get_Memtyp;
+
procedure Init is
begin
Instance_Pool := Global_Pool'Access;
diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads
index 6e1b29e80..ffb554717 100644
--- a/src/synth/synth-values.ads
+++ b/src/synth/synth-values.ads
@@ -18,9 +18,12 @@
-- Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
-- MA 02110-1301, USA.
+with Ada.Unchecked_Deallocation;
+
with Types; use Types;
with Areapools; use Areapools;
+with Grt.Types; use Grt.Types;
with Grt.Files_Operations;
with Netlists; use Netlists;
@@ -60,8 +63,8 @@ package Synth.Values is
type Bound_Array_Type is array (Dim_Type range <>) of Bound_Type;
- type Bound_Array (Len : Dim_Type) is record
- D : Bound_Array_Type (1 .. Len);
+ type Bound_Array (Ndim : Dim_Type) is record
+ D : Bound_Array_Type (1 .. Ndim);
end record;
type Bound_Array_Acc is access Bound_Array;
@@ -92,7 +95,13 @@ package Synth.Values is
type Type_Acc is access Type_Type;
type Rec_El_Type is record
- Off : Uns32;
+ -- Bit offset: offset of the element in a net.
+ Boff : Uns32;
+
+ -- Memory offset: offset of the element in memory.
+ Moff : Size_Type;
+
+ -- Type of the element.
Typ : Type_Acc;
end record;
@@ -103,11 +112,20 @@ package Synth.Values is
type Rec_El_Array_Acc is access Rec_El_Array;
+ -- Power of 2 alignment.
+ type Palign_Type is range 0 .. 3;
+
type Type_Type (Kind : Type_Kind) is record
-- False if the type is not synthesisable: is or contains access/file.
Is_Synth : Boolean;
- -- Number of bits for this type.
+ -- Alignment (in bytes) for this type.
+ Al : Palign_Type;
+
+ -- Number of bytes (when in memory) for this type.
+ Sz : Size_Type;
+
+ -- Number of bits (when in a net) for this type.
W : Width;
case Kind is
@@ -153,20 +171,9 @@ package Synth.Values is
-- into a net.
Value_Wire,
- -- A discrete value (integer or enumeration).
- Value_Discrete,
+ -- Any kind of constant value, raw stored in memory.
+ Value_Memory,
- Value_Float,
-
- -- An array (const if all elements are constants).
- Value_Array,
- Value_Const_Array,
-
- -- A record (const if all elements are constants).
- Value_Record,
- Value_Const_Record,
-
- Value_Access,
Value_File,
-- A constant. This is a named value. One purpose is to avoid to
@@ -184,9 +191,9 @@ package Synth.Values is
type Value_Type_Array is array (Iir_Index32 range <>) of Value_Acc;
- type Value_Array_Type (Len : Iir_Index32) is record
+ type Value_Array_Type (Ln : Iir_Index32) is record
-- Values are from left to right. So V(1) is at index 'Left.
- V : Value_Type_Array (1 .. Len);
+ V : Value_Type_Array (1 .. Ln);
end record;
type Value_Array_Acc is access Value_Array_Type;
@@ -196,24 +203,33 @@ package Synth.Values is
subtype File_Index is Grt.Files_Operations.Ghdl_File_Index;
+ type Memory_Element is mod 2**8;
+ type Memory_Array is array (Size_Type range <>) of Memory_Element;
+
+ -- Flat pointer for a generic pointer.
+ type Memory_Ptr is access all Memory_Array (Size_Type);
+
+ type Memtyp is record
+ Typ : Type_Acc;
+ Mem : Memory_Ptr;
+ end record;
+
+ -- Offsets for a value.
+ type Value_Offsets is record
+ Net_Off : Uns32;
+ Mem_Off : Size_Type;
+ end record;
+
+ function "+" (L, R : Value_Offsets) return Value_Offsets;
+
type Value_Type (Kind : Value_Kind) is record
case Kind is
when Value_Net =>
N : Net;
when Value_Wire =>
W : Wire_Id;
- when Value_Discrete =>
- Scal : Int64;
- when Value_Float =>
- Fp : Fp64;
- when Value_Array
- | Value_Const_Array =>
- Arr : Value_Array_Acc;
- when Value_Record
- | Value_Const_Record =>
- Rec : Value_Array_Acc;
- when Value_Access =>
- Acc : Heap_Index;
+ when Value_Memory =>
+ Mem : Memory_Ptr;
when Value_File =>
File : File_Index;
when Value_Const =>
@@ -222,7 +238,7 @@ package Synth.Values is
C_Net : Net;
when Value_Alias =>
A_Obj : Value_Acc;
- A_Off : Uns32;
+ A_Off : Value_Offsets;
end case;
end record;
@@ -234,6 +250,12 @@ package Synth.Values is
No_Valtyp : constant Valtyp := (null, null);
+ type Valtyp_Array is array (Nat32 range <>) of Valtyp;
+ type Valtyp_Array_Acc is access Valtyp_Array;
+
+ procedure Free_Valtyp_Array is new Ada.Unchecked_Deallocation
+ (Valtyp_Array, Valtyp_Array_Acc);
+
Global_Pool : aliased Areapool;
Expr_Pool : aliased Areapool;
@@ -244,15 +266,19 @@ package Synth.Values is
Instance_Pool : Areapool_Acc;
-- Types.
- function Create_Discrete_Type (Rng : Discrete_Range_Type; W : Width)
+ function Create_Discrete_Type (Rng : Discrete_Range_Type;
+ Sz : Size_Type;
+ W : Width)
return Type_Acc;
+
function Create_Float_Type (Rng : Float_Range_Type) return Type_Acc;
function Create_Vec_Type_By_Length (Len : Width; El : Type_Acc)
return Type_Acc;
function Create_Vector_Type (Bnd : Bound_Type; El_Type : Type_Acc)
return Type_Acc;
function Create_Unbounded_Vector (El_Type : Type_Acc) return Type_Acc;
- function Create_Slice_Type (W : Width; El_Type : Type_Acc) return Type_Acc;
+ function Create_Slice_Type (Len : Uns32; El_Type : Type_Acc)
+ return Type_Acc;
function Create_Bound_Array (Ndims : Dim_Type) return Bound_Array_Acc;
function Create_Array_Type (Bnd : Bound_Array_Acc; El_Type : Type_Acc)
return Type_Acc;
@@ -260,8 +286,7 @@ package Synth.Values is
return Type_Acc;
function Create_Rec_El_Array (Nels : Iir_Index32) return Rec_El_Array_Acc;
- function Create_Record_Type (Els : Rec_El_Array_Acc; W : Width)
- return Type_Acc;
+ function Create_Record_Type (Els : Rec_El_Array_Acc) return Type_Acc;
function Create_Access_Type (Acc_Type : Type_Acc) return Type_Acc;
@@ -272,6 +297,9 @@ package Synth.Values is
function Get_Array_Bound (Typ : Type_Acc; Dim : Dim_Type)
return Bound_Type;
+ -- Return the length of RNG.
+ function Get_Range_Length (Rng : Discrete_Range_Type) return Uns32;
+
-- Return the element of a vector/array/unbounded_array.
function Get_Array_Element (Arr_Type : Type_Acc) return Type_Acc;
@@ -283,80 +311,55 @@ package Synth.Values is
-- Can also return true for nets and wires.
function Is_Static_Val (Val : Value_Acc) return Boolean;
- function Is_Equal (L, R : Value_Acc) return Boolean;
+ function Is_Equal (L, R : Valtyp) return Boolean;
function Are_Types_Equal (L, R : Type_Acc) return Boolean;
-- Create a Value_Net.
- function Create_Value_Net (N : Net) return Value_Acc;
function Create_Value_Net (N : Net; Ntype : Type_Acc) return Valtyp;
-- Create a Value_Wire. For a bit wire, RNG must be null.
- function Create_Value_Wire (W : Wire_Id) return Value_Acc;
function Create_Value_Wire (W : Wire_Id; Wtype : Type_Acc) return Valtyp;
- function Create_Value_Discrete (Val : Int64) return Value_Acc;
+ function Create_Value_Memory (Vtype : Type_Acc) return Valtyp;
+
+ function Create_Value_Uns (Val : Uns64; Vtype : Type_Acc) return Valtyp;
+ function Create_Value_Int (Val : Int64; Vtype : Type_Acc) return Valtyp;
function Create_Value_Discrete (Val : Int64; Vtype : Type_Acc)
return Valtyp;
- function Create_Value_Float (Val : Fp64) return Value_Acc;
- function Create_Value_Float (Val : Fp64; Vtype : Type_Acc) return Valtyp;
-
- function Create_Value_Access (Acc : Heap_Index) return Value_Acc;
- function Create_Value_Access (Vtype : Type_Acc; Acc : Heap_Index)
+ function Create_Value_Access (Val : Heap_Index; Acc_Typ : Type_Acc)
return Valtyp;
- function Create_Value_File (File : File_Index) return Value_Acc;
+ function Create_Value_Float (Val : Fp64; Vtype : Type_Acc) return Valtyp;
+
function Create_Value_File (Vtype : Type_Acc; File : File_Index)
return Valtyp;
- function Create_Value_Array (Len : Iir_Index32) return Value_Array_Acc;
+ function Create_Value_Alias
+ (Obj : Value_Acc; Off : Value_Offsets; Typ : Type_Acc) return Valtyp;
- -- Create a Value_Array.
- function Create_Value_Array (Arr : Value_Array_Acc) return Value_Acc;
- function Create_Value_Array (Bounds : Type_Acc; Arr : Value_Array_Acc)
- return Valtyp;
- function Create_Value_Const_Array (Arr : Value_Array_Acc) return Value_Acc;
- function Create_Value_Const_Array (Bounds : Type_Acc; Arr : Value_Array_Acc)
- return Valtyp;
-
- -- Like the previous one but automatically build the array.
- function Create_Value_Array (Bounds : Type_Acc) return Value_Acc;
-
- -- Allocate the ARR component of the Value_Type ARR, using BOUNDS.
- -- procedure Create_Array_Data (Arr : Value_Acc);
-
- function Create_Value_Record (Els : Value_Array_Acc) return Value_Acc;
- function Create_Value_Record (Typ : Type_Acc; Els : Value_Array_Acc)
- return Valtyp;
- function Create_Value_Const_Record (Els : Value_Array_Acc) return Value_Acc;
- function Create_Value_Const_Record (Typ : Type_Acc; Els : Value_Array_Acc)
- return Valtyp;
-
- function Create_Value_Alias (Obj : Value_Acc; Off : Uns32) return Value_Acc;
- function Create_Value_Alias (Obj : Value_Acc; Off : Uns32; Typ : Type_Acc)
- return Valtyp;
- function Create_Value_Const (Val : Value_Acc; Loc : Syn_Src)
- return Value_Acc;
function Create_Value_Const (Val : Valtyp; Loc : Syn_Src)
return Valtyp;
-- If VAL is a const, replace it by its value.
- procedure Strip_Const (Val : in out Value_Acc);
procedure Strip_Const (Vt : in out Valtyp);
- function Strip_Const (Val : Value_Acc) return Value_Acc;
-- If VAL is a const or an alias, replace it by its value.
-- Used to extract the real data of a static value. Note that the type
-- is not correct anymore.
- function Strip_Alias_Const (V : Value_Acc) return Value_Acc;
function Strip_Alias_Const (V : Valtyp) return Valtyp;
- function Unshare (Src : Value_Acc; Pool : Areapool_Acc)
- return Value_Acc;
+ -- Return the memtyp of V; also strip const and aliases.
+ function Get_Memtyp (V : Valtyp) return Memtyp;
+
+ function Unshare (Src : Valtyp; Pool : Areapool_Acc) return Valtyp;
+
+ -- Return the length of a vector type.
+ function Vec_Length (Typ : Type_Acc) return Iir_Index32;
-- Get the number of indexes in array type TYP without counting
-- sub-elements.
- function Get_Array_Flat_Length (Typ : Type_Acc) return Width;
+ function Get_Array_Flat_Length (Typ : Type_Acc) return Iir_Index32;
-- Return length of dimension DIM of type T.
function Get_Bound_Length (T : Type_Acc; Dim : Dim_Type) return Width;
@@ -366,12 +369,32 @@ package Synth.Values is
function Get_Type_Width (Atype : Type_Acc) return Width;
-- Create a default initial value for TYP.
- function Create_Value_Default (Typ : Type_Acc) return Value_Acc;
function Create_Value_Default (Typ : Type_Acc) return Valtyp;
+ procedure Write_Value_Default (M : Memory_Ptr; Typ : Type_Acc);
-- Convert a value to a string. The value must be a const_array of scalar,
-- which represent characters.
- function Value_To_String (Val : Value_Acc) return String;
+ function Value_To_String (Val : Valtyp) return String;
+
+ -- Memory access.
+ procedure Write_Discrete (Vt : Valtyp; Val : Int64);
+ function Read_Discrete (Mem : Memory_Ptr; Typ : Type_Acc) return Int64;
+ function Read_Discrete (Vt : Valtyp) return Int64;
+
+ procedure Write_Access (Mem : Memory_Ptr; Val : Heap_Index);
+ function Read_Access (Vt : Valtyp) return Heap_Index;
+
+ function Read_Fp64 (Mem : Memory_Ptr) return Fp64;
+ function Read_Fp64 (Vt : Valtyp) return Fp64;
+
+ -- Low level subprograms.
+ function Read_U8 (Mem : Memory_Ptr) return Ghdl_U8;
+ procedure Write_U8 (Mem : Memory_Ptr; Val : Ghdl_U8);
+
+ function "+" (Base : Memory_Ptr; Off : Size_Type) return Memory_Ptr;
+
+ procedure Copy_Memory (Dest : Memory_Ptr; Src : Memory_Ptr; Sz : Size_Type);
+ procedure Write_Value (Dest : Memory_Ptr; Vt : Valtyp);
procedure Init;