diff options
author | Tristan Gingold <tgingold@free.fr> | 2020-07-24 06:22:16 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2020-07-24 06:22:16 +0200 |
commit | 921398c1dac0979723374afc01b9feb6e01fa98e (patch) | |
tree | 2d4fa3122f13edba041eae0529f30951d3c1ef85 /src | |
parent | 01c82f09be0baaa84cc189255b47fb1326da7424 (diff) | |
download | ghdl-921398c1dac0979723374afc01b9feb6e01fa98e.tar.gz ghdl-921398c1dac0979723374afc01b9feb6e01fa98e.tar.bz2 ghdl-921398c1dac0979723374afc01b9feb6e01fa98e.zip |
synth: fix handling of multi-dim ROM. Fix #1390
Document index order for memidx.
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/netlists-gates.ads | 9 | ||||
-rw-r--r-- | src/synth/netlists-memories.adb | 29 | ||||
-rw-r--r-- | src/synth/synth-expr.adb | 12 |
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; |