diff options
author | Tristan Gingold <tgingold@free.fr> | 2019-10-12 19:16:02 +0200 |
---|---|---|
committer | Tristan Gingold <tgingold@free.fr> | 2019-10-13 18:54:23 +0200 |
commit | 22e85aee201d10940e5fedcd7c657a5291fba75f (patch) | |
tree | d90e98f365ab45cce0570084043e0352d81f8bec /src | |
parent | a8560bb08e6c065871e6e5f5f7825cd1a2db62e4 (diff) | |
download | ghdl-22e85aee201d10940e5fedcd7c657a5291fba75f.tar.gz ghdl-22e85aee201d10940e5fedcd7c657a5291fba75f.tar.bz2 ghdl-22e85aee201d10940e5fedcd7c657a5291fba75f.zip |
synth-expr: handle range array attribute in slices.
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/synth-expr.adb | 116 |
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 " |