aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-expr.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth/synth-expr.adb')
-rw-r--r--src/synth/synth-expr.adb100
1 files changed, 73 insertions, 27 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index 988cb89c3..9e5ccff6a 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -893,6 +893,50 @@ package body Synth.Expr is
return Off;
end Dyn_Index_To_Offset;
+ -- Return the bounds of a one dimensional array/vector type and the
+ -- width of the element.
+ procedure Get_Onedimensional_Array_Bounds
+ (Typ : Type_Acc; Bnd : out Bound_Type; El_Typ : out Type_Acc) is
+ begin
+ case Typ.Kind is
+ when Type_Vector =>
+ El_Typ := Typ.Vec_El;
+ Bnd := Typ.Vbound;
+ when Type_Array =>
+ El_Typ := Typ.Arr_El;
+ Bnd := Typ.Abounds.D (1);
+ when others =>
+ raise Internal_Error;
+ end case;
+ end Get_Onedimensional_Array_Bounds;
+
+ function Create_Onedimensional_Array_Subtype
+ (Btyp : Type_Acc; Bnd : Bound_Type) return Type_Acc
+ is
+ Res : Type_Acc;
+ Bnds : Bound_Array_Acc;
+ begin
+ case Btyp.Kind is
+ when Type_Vector =>
+ Res := Create_Vector_Type (Bnd, Btyp.Vec_El);
+ when Type_Unbounded_Vector =>
+ Res := Create_Vector_Type (Bnd, Btyp.Uvec_El);
+ when Type_Array =>
+ pragma Assert (Btyp.Abounds.Len = 1);
+ Bnds := Create_Bound_Array (1);
+ Bnds.D (1) := Bnd;
+ Res := Create_Array_Type (Bnds, Btyp.Arr_El);
+ when Type_Unbounded_Array =>
+ pragma Assert (Btyp.Uarr_Ndim = 1);
+ Bnds := Create_Bound_Array (1);
+ Bnds.D (1) := Bnd;
+ Res := Create_Array_Type (Bnds, Btyp.Uarr_El);
+ when others =>
+ raise Internal_Error;
+ end case;
+ return Res;
+ end Create_Onedimensional_Array_Subtype;
+
procedure Synth_Indexed_Name (Syn_Inst : Synth_Instance_Acc;
Name : Node;
Pfx_Type : Type_Acc;
@@ -906,6 +950,7 @@ package body Synth.Expr is
Idx_Val : Value_Acc;
Idx_Type : Type_Acc;
Bnd : Bound_Type;
+ El_Typ : Type_Acc;
begin
if Get_Nbr_Elements (Indexes) /= 1 then
Error_Msg_Synth (+Name, "multi-dim arrays not yet supported");
@@ -917,21 +962,13 @@ package body Synth.Expr is
(Syn_Inst, Get_Base_Type (Get_Type (Idx_Expr)));
Idx_Val := Synth_Expression_With_Type (Syn_Inst, Idx_Expr, Idx_Type);
- case Pfx_Type.Kind is
- when Type_Vector =>
- W := 1;
- Bnd := Pfx_Type.Vbound;
- when Type_Array =>
- W := Get_Type_Width (Pfx_Type.Arr_El);
- Bnd := Pfx_Type.Abounds.D (1);
- when others =>
- raise Internal_Error;
- end case;
+ Get_Onedimensional_Array_Bounds (Pfx_Type, Bnd, El_Typ);
+ W := El_Typ.W;
if Idx_Val.Kind = Value_Discrete then
Voff := No_Net;
Mul := 0;
- Off := Index_To_Offset (Bnd, Idx_Val.Scal, Name);
+ Off := Index_To_Offset (Bnd, Idx_Val.Scal, Name) * W;
else
Voff := Dyn_Index_To_Offset (Bnd, Idx_Val, Name);
Off := 0;
@@ -947,11 +984,13 @@ package body Synth.Expr is
Mul : Uns32;
Off : Uns32;
W : Width;
+ El_Typ : Type_Acc;
Res : Net;
begin
Pfx_Val := Synth_Expression (Syn_Inst, Get_Prefix (Name));
Synth_Indexed_Name (Syn_Inst, Name, Pfx_Val.Typ, Voff, Mul, Off, W);
+ El_Typ := Get_Array_Element (Pfx_Val.Typ);
if Voff = No_Net then
pragma Assert (Mul = 0);
@@ -960,13 +999,14 @@ package body Synth.Expr is
else
Res := Build_Extract (Build_Context, Get_Net (Pfx_Val), Off, W);
Set_Location (Res, Name);
- return Create_Value_Net (Res, Get_Array_Element (Pfx_Val.Typ));
+ return Create_Value_Net (Res, El_Typ);
end if;
else
- Res := Build_Dyn_Extract
- (Build_Context, Get_Net (Pfx_Val), Voff, Mul, Int32 (Off), W);
+ pragma Assert (Off = 0);
+ Res := Build_Dyn_Extract (Build_Context, Get_Net (Pfx_Val),
+ Voff, Mul, Off, W);
Set_Location (Res, Name);
- return Create_Value_Net (Res, Get_Array_Element (Pfx_Val.Typ));
+ return Create_Value_Net (Res, El_Typ);
end if;
end Synth_Indexed_Name;
@@ -1096,7 +1136,7 @@ package body Synth.Expr is
Right : Net;
Inp : out Net;
Step : out Uns32;
- Off : out Int32;
+ Off : out Uns32;
Width : out Uns32)
is
L_Inp, R_Inp : Net;
@@ -1137,10 +1177,10 @@ package body Synth.Expr is
case Pfx_Bnd.Dir is
when Iir_To =>
- Off := L_Add - Pfx_Bnd.Left;
+ Off := Uns32 (L_Add - Pfx_Bnd.Left);
Width := Uns32 (R_Add - L_Add + 1);
when Iir_Downto =>
- Off := R_Add - Pfx_Bnd.Right;
+ Off := Uns32 (R_Add - Pfx_Bnd.Right);
Width := Uns32 (L_Add - R_Add + 1);
end case;
end Synth_Extract_Dyn_Suffix;
@@ -1151,7 +1191,7 @@ package body Synth.Expr is
Res_Bnd : out Bound_Type;
Inp : out Net;
Step : out Uns32;
- Off : out Int32;
+ Off : out Uns32;
Wd : out Uns32)
is
Expr : constant Node := Get_Suffix (Name);
@@ -1204,7 +1244,7 @@ package body Synth.Expr is
Len => Wd,
Left => Int32 (L),
Right => Int32 (R));
- Off := Pfx_Bnd.Right - Res_Bnd.Right;
+ Off := Uns32 (Pfx_Bnd.Right - Res_Bnd.Right);
when Iir_Downto =>
Wd := Width (L - R + 1);
Res_Bnd := (Dir => Iir_Downto,
@@ -1213,7 +1253,7 @@ package body Synth.Expr is
Len => Wd,
Left => Int32 (L),
Right => Int32 (R));
- Off := Res_Bnd.Right - Pfx_Bnd.Right;
+ Off := Uns32 (Res_Bnd.Right - Pfx_Bnd.Right);
end case;
end;
else
@@ -1235,27 +1275,33 @@ package body Synth.Expr is
Pfx_Node : constant Node := Get_Prefix (Name);
Pfx : constant Value_Acc :=
Synth_Expression_With_Basetype (Syn_Inst, Pfx_Node);
+ Pfx_Bnd : Bound_Type;
+ El_Typ : Type_Acc;
Res_Bnd : Bound_Type;
Res_Type : Type_Acc;
Inp : Net;
Step : Uns32;
- Off : Int32;
+ Off : Uns32;
Wd : Uns32;
N : Net;
begin
+ Get_Onedimensional_Array_Bounds (Pfx.Typ, Pfx_Bnd, El_Typ);
+
Synth_Slice_Suffix
- (Syn_Inst, Name, Pfx.Typ.Vbound, Res_Bnd, Inp, Step, Off, Wd);
+ (Syn_Inst, Name, Pfx_Bnd, Res_Bnd, Inp, Step, Off, Wd);
if Inp /= No_Net then
N := Build_Dyn_Extract (Build_Context, Get_Net (Pfx),
- Inp, Step, Off, Wd);
+ Inp, Step * El_Typ.W, Off * El_Typ.W,
+ Wd * El_Typ.W);
Set_Location (N, Name);
-- TODO: the bounds cannot be created as they are not known.
- Res_Type := Create_Slice_Type (Wd, Pfx.Typ.Vec_El);
+ Res_Type := Create_Slice_Type (Wd, El_Typ);
return Create_Value_Net (N, Res_Type);
else
- N := Build_Extract (Build_Context, Get_Net (Pfx), Uns32 (Off), Wd);
+ N := Build_Extract (Build_Context, Get_Net (Pfx),
+ Off * El_Typ.W, Wd * El_Typ.W);
Set_Location (N, Name);
- Res_Type := Create_Vector_Type (Res_Bnd, Pfx.Typ.Vec_El);
+ Res_Type := Create_Onedimensional_Array_Subtype (Pfx.Typ, Res_Bnd);
return Create_Value_Net (N, Res_Type);
end if;
end Synth_Slice_Name;