aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2020-03-26 12:59:09 +0100
committerTristan Gingold <tgingold@free.fr>2020-03-26 12:59:09 +0100
commitbe6153b9d5deb0957d1b584324b161c075c73878 (patch)
treeb348143bed0092dd160a44e679b2f1ceabef3e66 /src
parent643f13aab1704494ceee79c3d8e0ac65b75ea2a1 (diff)
downloadghdl-be6153b9d5deb0957d1b584324b161c075c73878.tar.gz
ghdl-be6153b9d5deb0957d1b584324b161c075c73878.tar.bz2
ghdl-be6153b9d5deb0957d1b584324b161c075c73878.zip
synth-expr: handle multi-dimensional arrays for indexed names.
Diffstat (limited to 'src')
-rw-r--r--src/synth/synth-expr.adb62
1 files changed, 38 insertions, 24 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index 459a7d071..77236a069 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -1403,36 +1403,50 @@ package body Synth.Expr is
W : out Width)
is
Indexes : constant Iir_Flist := Get_Index_List (Name);
- Idx_Expr : constant Node := Get_Nth_Element (Indexes, 0);
+ El_Typ : constant Type_Acc := Get_Array_Element (Pfx_Type);
+ Idx_Expr : Node;
Idx_Val : Value_Acc;
- Idx_Type : Type_Acc;
Bnd : Bound_Type;
- El_Typ : Type_Acc;
+ Stride : Uns32;
+ Ivoff : Net;
begin
- if Get_Nbr_Elements (Indexes) /= 1 then
- Error_Msg_Synth (+Name, "multi-dim arrays not yet supported");
- raise Internal_Error;
- end if;
+ W := El_Typ.W;
+ Voff := No_Net;
+ Off := 0;
- -- Use the base type as the subtype of the index is not synth-ed.
- Idx_Type := Get_Value_Type
- (Syn_Inst, Get_Base_Type (Get_Type (Idx_Expr)));
- Idx_Val := Synth_Expression_With_Type (Syn_Inst, Idx_Expr, Idx_Type);
- Strip_Const (Idx_Val);
+ for I in Flist_First .. Flist_Last (Indexes) loop
+ Idx_Expr := Get_Nth_Element (Indexes, I);
- Get_Onedimensional_Array_Bounds (Pfx_Type, Bnd, El_Typ);
- W := El_Typ.W;
+ -- Compute stride. This is O(n**2), but for small n.
+ Stride := W;
+ for J in I + 1 .. Flist_Last (Indexes) loop
+ Bnd := Get_Array_Bound (Pfx_Type, Dim_Type (J + 1));
+ Stride := Stride * Bnd.Len;
+ end loop;
- if Idx_Val.Kind = Value_Discrete then
- Voff := No_Net;
- Off := Index_To_Offset (Syn_Inst, Bnd, Idx_Val.Scal, Name) * W;
- else
- Voff := Dyn_Index_To_Offset (Bnd, Idx_Val, Name);
- Voff := Build_Memidx (Get_Build (Syn_Inst), Voff, W, Bnd.Len - 1,
- Width (Clog2 (Uns64 (W * Bnd.Len))));
- Set_Location (Voff, Name);
- Off := 0;
- end if;
+ -- Use the base type as the subtype of the index is not synth-ed.
+ Idx_Val := Synth_Expression_With_Basetype (Syn_Inst, Idx_Expr);
+ Strip_Const (Idx_Val);
+
+ Bnd := Get_Array_Bound (Pfx_Type, Dim_Type (I + 1));
+
+ if Idx_Val.Kind = Value_Discrete then
+ Off := Off
+ + Index_To_Offset (Syn_Inst, Bnd, Idx_Val.Scal, Name) * Stride;
+ else
+ Ivoff := Dyn_Index_To_Offset (Bnd, Idx_Val, Name);
+ Ivoff := Build_Memidx (Get_Build (Syn_Inst), Ivoff, W, Bnd.Len - 1,
+ Width (Clog2 (Uns64 (Stride * Bnd.Len))));
+ Set_Location (Ivoff, Idx_Expr);
+
+ if Voff = No_Net then
+ Voff := Ivoff;
+ else
+ Voff := Build_Addidx (Get_Build (Syn_Inst), Ivoff, Voff);
+ Set_Location (Voff, Idx_Expr);
+ end if;
+ end if;
+ end loop;
end Synth_Indexed_Name;
function Is_Static (N : Net) return Boolean is