aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-10-02 20:47:54 +0200
committerTristan Gingold <tgingold@free.fr>2019-10-02 20:47:54 +0200
commit5610cd1aae1c88d4beec14b2beaf10040d678696 (patch)
tree6fb6fd4e22c3b3651edd238234b776fd3f032531 /src/synth
parentd145f8b9f99463f310a466f2e8e114d1b61afaee (diff)
downloadghdl-5610cd1aae1c88d4beec14b2beaf10040d678696.tar.gz
ghdl-5610cd1aae1c88d4beec14b2beaf10040d678696.tar.bz2
ghdl-5610cd1aae1c88d4beec14b2beaf10040d678696.zip
synth: refactoring for memidx1.
Diffstat (limited to 'src/synth')
-rw-r--r--src/synth/synth-expr.adb47
-rw-r--r--src/synth/synth-expr.ads9
-rw-r--r--src/synth/synth-stmts.adb23
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,