aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2019-10-12 19:16:02 +0200
committerTristan Gingold <tgingold@free.fr>2019-10-13 18:54:23 +0200
commit22e85aee201d10940e5fedcd7c657a5291fba75f (patch)
treed90e98f365ab45cce0570084043e0352d81f8bec /src/synth
parenta8560bb08e6c065871e6e5f5f7825cd1a2db62e4 (diff)
downloadghdl-22e85aee201d10940e5fedcd7c657a5291fba75f.tar.gz
ghdl-22e85aee201d10940e5fedcd7c657a5291fba75f.tar.bz2
ghdl-22e85aee201d10940e5fedcd7c657a5291fba75f.zip
synth-expr: handle range array attribute in slices.
Diffstat (limited to 'src/synth')
-rw-r--r--src/synth/synth-expr.adb116
1 files changed, 74 insertions, 42 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb
index cd840b97a..f8f9e0911 100644
--- a/src/synth/synth-expr.adb
+++ b/src/synth/synth-expr.adb
@@ -1138,6 +1138,54 @@ package body Synth.Expr is
end case;
end Synth_Extract_Dyn_Suffix;
+ procedure Synth_Slice_Const_Suffix (Name : Node;
+ Pfx_Bnd : Bound_Type;
+ L, R : Int64;
+ Dir : Iir_Direction;
+ El_Wd : Width;
+ Res_Bnd : out Bound_Type;
+ Off : out Uns32;
+ Wd : out Width)
+ is
+ Len : Uns32;
+ begin
+ if Pfx_Bnd.Dir /= Dir then
+ Error_Msg_Synth (+Name, "direction mismatch in slice");
+ Off := 0;
+ Wd := 0;
+ return;
+ end if;
+
+ if not In_Bounds (Pfx_Bnd, Int32 (L))
+ or else not In_Bounds (Pfx_Bnd, Int32 (R))
+ then
+ Error_Msg_Synth (+Name, "index not within bounds");
+ Wd := 0;
+ Off := 0;
+ return;
+ end if;
+
+ case Pfx_Bnd.Dir is
+ when Iir_To =>
+ Len := Uns32 (R - L + 1);
+ Res_Bnd := (Dir => Iir_To,
+ Wbounds => Pfx_Bnd.Wbounds,
+ Len => Len,
+ Left => Int32 (L),
+ Right => Int32 (R));
+ Off := Uns32 (Pfx_Bnd.Right - Res_Bnd.Right) * El_Wd;
+ when Iir_Downto =>
+ Len := Uns32 (L - R + 1);
+ Res_Bnd := (Dir => Iir_Downto,
+ Wbounds => Pfx_Bnd.Wbounds,
+ Len => Len,
+ Left => Int32 (L),
+ Right => Int32 (R));
+ Off := Uns32 (Res_Bnd.Right - Pfx_Bnd.Right) * El_Wd;
+ end case;
+ Wd := Len * El_Wd;
+ end Synth_Slice_Const_Suffix;
+
procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc;
Name : Node;
Pfx_Bnd : Bound_Type;
@@ -1161,54 +1209,38 @@ package body Synth.Expr is
Right := Synth_Expression_With_Basetype
(Syn_Inst, Get_Right_Limit (Expr));
Dir := Get_Direction (Expr);
+ when Iir_Kind_Range_Array_Attribute =>
+ declare
+ Rng : Discrete_Range_Type;
+ W : Width;
+ begin
+ Synth_Discrete_Range (Syn_Inst, Expr, Rng, W);
+ Inp := No_Net;
+ Synth_Slice_Const_Suffix (Name, Pfx_Bnd,
+ Rng.Left, Rng.Right, Rng.Dir,
+ El_Wd, Res_Bnd, Off, Wd);
+ return;
+ end;
when others =>
- Error_Msg_Synth (+Expr, "only range supported for slices");
+ Error_Msg_Synth
+ (+Expr, "only range expression supported for slices");
end case;
- if Pfx_Bnd.Dir /= Dir then
- Error_Msg_Synth (+Name, "direction mismatch in slice");
- Wd := 0;
- return;
- end if;
-
if Is_Const_Val (Left) and then Is_Const_Val (Right) then
- declare
- L : constant Int64 := Get_Const_Discrete (Left);
- R : constant Int64 := Get_Const_Discrete (Right);
- Len : Uns32;
- begin
+ Inp := No_Net;
+ Synth_Slice_Const_Suffix
+ (Name, Pfx_Bnd,
+ Get_Const_Discrete (Left), Get_Const_Discrete (Right), Dir,
+ El_Wd, Res_Bnd, Off, Wd);
+ else
+ if Pfx_Bnd.Dir /= Dir then
+ Error_Msg_Synth (+Name, "direction mismatch in slice");
Inp := No_Net;
+ Off := 0;
+ Wd := 0;
+ return;
+ end if;
- if not In_Bounds (Pfx_Bnd, Int32 (L))
- or else not In_Bounds (Pfx_Bnd, Int32 (R))
- then
- Error_Msg_Synth (+Name, "index not within bounds");
- Wd := 0;
- Off := 0;
- return;
- end if;
-
- case Pfx_Bnd.Dir is
- when Iir_To =>
- Len := Uns32 (R - L + 1);
- Res_Bnd := (Dir => Iir_To,
- Wbounds => Pfx_Bnd.Wbounds,
- Len => Len,
- Left => Int32 (L),
- Right => Int32 (R));
- Off := Uns32 (Pfx_Bnd.Right - Res_Bnd.Right) * El_Wd;
- when Iir_Downto =>
- Len := Uns32 (L - R + 1);
- Res_Bnd := (Dir => Iir_Downto,
- Wbounds => Pfx_Bnd.Wbounds,
- Len => Len,
- Left => Int32 (L),
- Right => Int32 (R));
- 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
Error_Msg_Synth
(+Name, "left and right bounds of a slice must be "