diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/synth/synth-expr.adb | 47 | ||||
| -rw-r--r-- | src/synth/synth-expr.ads | 9 | ||||
| -rw-r--r-- | src/synth/synth-stmts.adb | 23 | 
3 files changed, 47 insertions, 32 deletions
| diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index 308b84150..03a91155e 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -1186,15 +1186,16 @@ package body Synth.Expr is     procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc;                                   Name : Node;                                   Pfx_Bnd : Bound_Type; +                                 El_Wd : Width;                                   Res_Bnd : out Bound_Type;                                   Inp : out Net; -                                 Step : out Uns32;                                   Off : out Uns32; -                                 Wd : out Uns32) +                                 Wd : out Width)     is        Expr : constant Node := Get_Suffix (Name);        Left, Right : Value_Acc;        Dir : Iir_Direction; +      Step : Uns32;     begin        Off := 0; @@ -1211,7 +1212,6 @@ package body Synth.Expr is        if Pfx_Bnd.Dir /= Dir then           Error_Msg_Synth (+Name, "direction mismatch in slice"); -         Step := 0;           Wd := 0;           return;        end if; @@ -1220,9 +1220,9 @@ package body Synth.Expr is           declare              L : constant Int64 := Get_Const_Discrete (Left);              R : constant Int64 := Get_Const_Discrete (Right); +            Len : Uns32;           begin              Inp := No_Net; -            Step := 0;              if not In_Bounds (Pfx_Bnd, Int32 (L))                or else not In_Bounds (Pfx_Bnd, Int32 (R)) @@ -1235,24 +1235,25 @@ package body Synth.Expr is              case Pfx_Bnd.Dir is                 when Iir_To => -                  Wd := Width (R - L + 1); +                  Len := Uns32 (R - L + 1);                    Res_Bnd := (Dir => Iir_To, -                              Wlen => Wd, -                              Wbounds => Wd, -                              Len => Wd, +                              Wlen => Len, +                              Wbounds => Pfx_Bnd.Wbounds, +                              Len => Len,                                Left => Int32 (L),                                Right => Int32 (R)); -                  Off := Uns32 (Pfx_Bnd.Right - Res_Bnd.Right); +                  Off := Uns32 (Pfx_Bnd.Right - Res_Bnd.Right) * El_Wd;                 when Iir_Downto => -                  Wd := Width (L - R + 1); +                  Len := Uns32 (L - R + 1);                    Res_Bnd := (Dir => Iir_Downto, -                              Wlen => Wd, -                              Wbounds => Wd, -                              Len => Wd, +                              Wlen => Len, +                              Wbounds => Pfx_Bnd.Wbounds, +                              Len => Len,                                Left => Int32 (L),                                Right => Int32 (R)); -                  Off := Uns32 (Res_Bnd.Right - Pfx_Bnd.Right); +                  Off := Uns32 (Res_Bnd.Right - Pfx_Bnd.Right) * El_Wd;              end case; +            Wd := Len * El_Wd;           end;        else           if Is_Const (Left) or else Is_Const (Right) then @@ -1264,6 +1265,11 @@ package body Synth.Expr is           Synth_Extract_Dyn_Suffix             (Name, Pfx_Bnd, Get_Net (Left), Get_Net (Right),              Inp, Step, Off, Wd); +         Inp := Build_Memidx1 +           (Get_Build (Syn_Inst), +            Inp, Step * El_Wd, 0, +            Get_Width (Inp) + Width (Clog2 (Uns64 (Step * El_Wd)))); +         Wd := Wd * El_Wd;        end if;     end Synth_Slice_Suffix; @@ -1278,26 +1284,23 @@ package body Synth.Expr is        Res_Bnd : Bound_Type;        Res_Type : Type_Acc;        Inp : Net; -      Step : Uns32;        Off : Uns32;        Wd : Uns32;        N : Net;     begin        Get_Onedimensional_Array_Bounds (Pfx.Typ, Pfx_Bnd, El_Typ); -      Synth_Slice_Suffix -        (Syn_Inst, Name, Pfx_Bnd, Res_Bnd, Inp, Step, Off, Wd); +      Synth_Slice_Suffix (Syn_Inst, Name, Pfx_Bnd, El_Typ.W, +                          Res_Bnd, Inp, Off, Wd);        if Inp /= No_Net then -         N := Build_Dyn_Extract (Build_Context, Get_Net (Pfx), -                                 Inp, Step * El_Typ.W, Off * El_Typ.W, -                                 Wd * El_Typ.W); +         N := Build_Dyn_Extract (Build_Context, +                                 Get_Net (Pfx), Inp, 1, Off, Wd);           Set_Location (N, Name);           --  TODO: the bounds cannot be created as they are not known.           Res_Type := Create_Slice_Type (Wd, El_Typ);           return Create_Value_Net (N, Res_Type);        else -         N := Build_Extract (Build_Context, Get_Net (Pfx), -                             Off * El_Typ.W, Wd * El_Typ.W); +         N := Build_Extract (Build_Context, Get_Net (Pfx), Off, Wd);           Set_Location (N, Name);           Res_Type := Create_Onedimensional_Array_Subtype (Pfx.Typ, Res_Bnd);           return Create_Value_Net (N, Res_Type); diff --git a/src/synth/synth-expr.ads b/src/synth/synth-expr.ads index d40e41eb3..f04e0630b 100644 --- a/src/synth/synth-expr.ads +++ b/src/synth/synth-expr.ads @@ -41,6 +41,11 @@ package Synth.Expr is     function Get_Const_Discrete (V : Value_Acc) return Int64; +   --  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); +     function Create_Onedimensional_Array_Subtype       (Btyp : Type_Acc; Bnd : Bound_Type) return Type_Acc; @@ -98,11 +103,11 @@ package Synth.Expr is     procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc;                                   Name : Node;                                   Pfx_Bnd : Bound_Type; +                                 El_Wd : Width;                                   Res_Bnd : out Bound_Type;                                   Inp : out Net; -                                 Step : out Uns32;                                   Off : out Uns32; -                                 Wd : out Uns32); +                                 Wd : out Width);     --  If VOFF is No_Net then OFF is valid, if VOFF is not No_Net then     --  OFF is 0. diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 733607af2..da8c74acc 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -180,16 +180,19 @@ package body Synth.Stmts is           when Iir_Kind_Slice_Name =>              declare +               Pfx_Bnd : Bound_Type; +               El_Typ : Type_Acc;                 Res_Bnd : Bound_Type;                 Inp : Net; -               Step : Uns32;                 Sl_Off : Uns32;                 Wd : Uns32;              begin                 Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Pfx),                                          Dest_Obj, Dest_Off, Dest_Type); -               Synth_Slice_Suffix (Syn_Inst, Pfx, Dest_Type.Vbound, -                                   Res_Bnd, Inp, Step, Sl_Off, Wd); + +               Get_Onedimensional_Array_Bounds (Dest_Type, Pfx_Bnd, El_Typ); +               Synth_Slice_Suffix (Syn_Inst, Pfx, Pfx_Bnd, El_Typ.W, +                                   Res_Bnd, Inp, Sl_Off, Wd);                 if Inp /= No_Net then                    Error_Msg_Synth @@ -314,10 +317,11 @@ package body Synth.Stmts is                 Obj : Value_Acc;                 Off : Uns32;                 Typ : Type_Acc; +               Pfx_Bnd : Bound_Type; +               El_Typ : Type_Acc;                 Res_Bnd : Bound_Type;                 Inp : Net; -               Step : Uns32;                 Sl_Off : Uns32;                 Wd : Uns32; @@ -327,15 +331,18 @@ package body Synth.Stmts is              begin                 Synth_Assignment_Prefix (Syn_Inst, Get_Prefix (Target),                                          Obj, Off, Typ); -               Synth_Slice_Suffix (Syn_Inst, Target, Typ.Vbound, -                                   Res_Bnd, Inp, Step, Sl_Off, Wd); -               Res_Type := Create_Vector_Type (Res_Bnd, Typ.Vec_El); + +               Get_Onedimensional_Array_Bounds (Typ, Pfx_Bnd, El_Typ); + +               Synth_Slice_Suffix (Syn_Inst, Target, Pfx_Bnd, El_Typ.W, +                                   Res_Bnd, Inp, Sl_Off, Wd); +               Res_Type := Create_Vector_Type (Res_Bnd, El_Typ);                 if Inp /= No_Net then                    Targ_Net := Get_Current_Assign_Value                      (Build_Context, Obj.W, Off, Get_Type_Width (Typ));                    V := Build_Dyn_Insert                      (Build_Context, Targ_Net, No_Net, -                     Inp, Step, Sl_Off); +                     Inp, 1, Sl_Off);                    Set_Location (V, Target);                    return Target_Info'(Kind => Target_Memory,                                        Targ_Type => Res_Type, | 
