From 5610cd1aae1c88d4beec14b2beaf10040d678696 Mon Sep 17 00:00:00 2001 From: Tristan Gingold Date: Wed, 2 Oct 2019 20:47:54 +0200 Subject: synth: refactoring for memidx1. --- src/synth/synth-expr.adb | 47 +++++++++++++++++++++++++---------------------- src/synth/synth-expr.ads | 9 +++++++-- src/synth/synth-stmts.adb | 23 +++++++++++++++-------- 3 files changed, 47 insertions(+), 32 deletions(-) (limited to 'src/synth') 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, -- cgit v1.2.3