aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/synth/netlists-gates.ads9
-rw-r--r--src/synth/netlists-memories.adb29
-rw-r--r--src/synth/synth-expr.adb12
3 files changed, 26 insertions, 24 deletions
diff --git a/src/synth/netlists-gates.ads b/src/synth/netlists-gates.ads
index 990331bf9..4acf9f6b4 100644
--- a/src/synth/netlists-gates.ads
+++ b/src/synth/netlists-gates.ads
@@ -257,12 +257,21 @@ package Netlists.Gates is
subtype Dyn_Insert_Module_Id is
Module_Id range Id_Dyn_Insert .. Id_Dyn_Insert_En;
+ -- Gate to compute dynamic insert or extract offsets.
+ -- Provides the scale (step) factor (needed for insert/extract wider than
+ -- 1 bit), also provides the maximum index value.
+ -- For multi-dimensional insert/extract, memidx needs to be combined with
+ -- addidx.
-- Inputs: 0: index
-- Params: 0: step
-- 1: max
-- OUT := IN0 * STEP, IN0 < MAX
Id_Memidx : constant Module_Id := 90;
+ -- Combine (simply add) indexes for dynamic insert or extract.
+ -- Despite the addition being commutative, the inputs are ordered.
+ -- Input 0 must be a memidx (the most significant one, so with the larger
+ -- step), and input 1 must be either a memidx or an addidx.
-- OUT := IN0 + IN1, size extension (max of inputs width).
-- Inputs: 0: a memidx
-- 1: chain (addidx or memidx).
diff --git a/src/synth/netlists-memories.adb b/src/synth/netlists-memories.adb
index 704c96e8b..f9e5c124c 100644
--- a/src/synth/netlists-memories.adb
+++ b/src/synth/netlists-memories.adb
@@ -165,10 +165,10 @@ package body Netlists.Memories is
when Id_Dyn_Extract =>
-- Extract step from memidx gate.
Idx := Get_Net_Parent (Get_Input_Net (Extr_Inst, 1));
- if Get_Id (Idx) = Id_Addidx then
- -- Multi-dim arrays, lowest index is the first one.
- Idx := Get_Net_Parent (Get_Input_Net (Idx, 0));
- end if;
+ while Get_Id (Idx) = Id_Addidx loop
+ -- Multi-dim arrays, lowest index is the last one.
+ Idx := Get_Net_Parent (Get_Input_Net (Idx, 1));
+ end loop;
pragma Assert (Get_Id (Idx) = Id_Memidx);
Step := Get_Param_Uns32 (Idx, 0);
@@ -316,7 +316,7 @@ package body Netlists.Memories is
pragma Unreferenced (Mem_Depth);
-- Do checks on memidx.
- Last_Size := 0;
+ Last_Size := Mem_Size;
for I in Indexes'Range loop
declare
Inst : constant Instance := Indexes (I).Inst;
@@ -326,17 +326,18 @@ package body Netlists.Memories is
Max : constant Uns32 := Get_Param_Uns32 (Inst, 1);
Max_W : constant Width := Clog2 (Max + 1);
Sub_Addr1 : Net;
+ Sz : Uns32;
begin
-- Check max (from previous dimension).
+ -- Check the memidx can index its whole input.
pragma Assert (Max /= 0);
- if I /= Indexes'First then
- if Last_Size /= Step then
- raise Internal_Error;
- end if;
+ Sz := (Max + 1) * Step;
+ if Sz /= Last_Size then
+ raise Internal_Error;
end if;
- Last_Size := (Max + 1) * Step;
+ Last_Size := Step;
- if I = Indexes'First then
+ if I = Indexes'Last then
if Step /= Val_Wd then
raise Internal_Error;
end if;
@@ -357,16 +358,12 @@ package body Netlists.Memories is
end;
end loop;
- if Last_Size /= Mem_Size then
- raise Internal_Error;
- end if;
-
-- Lower (just concat addresses).
declare
use Netlists.Concats;
Concat : Concat_Type;
begin
- for I in Indexes'Range loop
+ for I in reverse Indexes'Range loop
Append (Concat, Indexes (I).Addr);
end loop;
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index 85404d7e3..654d25eb8 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -1167,16 +1167,10 @@ package body Synth.Expr is
Voff := No_Net;
Off := (0, 0);
- for I in Flist_First .. Flist_Last (Indexes) loop
+ Stride := 1;
+ for I in reverse 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 := 1;
- 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;
-
-- 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);
@@ -1204,6 +1198,8 @@ package body Synth.Expr is
Set_Location (Voff, Idx_Expr);
end if;
end if;
+
+ Stride := Stride * Bnd.Len;
end loop;
end Synth_Indexed_Name;