diff options
-rw-r--r-- | src/synth/synth-expr.adb | 63 | ||||
-rw-r--r-- | src/synth/synth-expr.ads | 5 | ||||
-rw-r--r-- | src/synth/synth-stmts.adb | 21 | ||||
-rw-r--r-- | src/synth/synth-values.adb | 12 | ||||
-rw-r--r-- | src/synth/synth-values.ads | 1 |
5 files changed, 71 insertions, 31 deletions
diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index 78285cc09..04830971a 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -512,18 +512,6 @@ package body Synth.Expr is end if; end Synth_Bit_Eq_Const; - function Extract_Bound (Val : Value_Acc) return Value_Bound_Acc is - begin - case Val.Kind is - when Value_Net => - return Val.N_Bound; - when Value_Wire => - return Val.W_Bound; - when others => - raise Internal_Error; - end case; - end Extract_Bound; - -- Create the result range of an operator. According to the ieee standard, -- the range is LEN-1 downto 0. function Create_Res_Bound (Prev : Value_Acc; N : Net) return Value_Bound_Acc @@ -907,17 +895,19 @@ package body Synth.Expr is return Bit_Extract (Pfx, Off); end Synth_Indexed_Name; - function Synth_Slice_Name (Syn_Inst : Synth_Instance_Acc; Name : Node) - return Value_Acc + procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc; + Name : Node; + Pfx_Bnd : Value_Bound_Acc; + Res_Bnd : out Value_Bound_Acc; + Off : out Uns32) is - Pfx : constant Value_Acc := - Synth_Expression (Syn_Inst, Get_Prefix (Name)); Expr : constant Node := Get_Suffix (Name); - Res_Bnd : Value_Bound_Acc; Left, Right : Value_Acc; Dir : Iir_Direction; - Bnd : Value_Bound_Acc; begin + Res_Bnd := null; + Off := 0; + case Get_Kind (Expr) is when Iir_Kind_Range_Expression => Left := Synth_Expression (Syn_Inst, Get_Left_Limit (Expr)); @@ -929,28 +919,27 @@ package body Synth.Expr is if Left.Kind /= Value_Discrete then Error_Msg_Synth (+Name, "non constant integer left not supported"); - return null; + return; end if; if Right.Kind /= Value_Discrete then Error_Msg_Synth (+Name, "non constant integer right not supported"); - return null; + return; end if; - Bnd := Extract_Bound (Pfx); - if Bnd.Dir /= Dir then + if Pfx_Bnd.Dir /= Dir then Error_Msg_Synth (+Name, "direction mismatch in slice"); - return null; + return; end if; - if not In_Bounds (Bnd, Int32 (Left.Scal)) - or else not In_Bounds (Bnd, Int32 (Right.Scal)) + if not In_Bounds (Pfx_Bnd, Int32 (Left.Scal)) + or else not In_Bounds (Pfx_Bnd, Int32 (Right.Scal)) then Error_Msg_Synth (+Name, "index not within bounds"); - return null; + return; end if; - case Bnd.Dir is + case Pfx_Bnd.Dir is when Iir_To => Res_Bnd := Create_Value_Bound (Value_Bound_Type' @@ -958,8 +947,7 @@ package body Synth.Expr is Len => Width (Right.Scal - Left.Scal + 1), Left => Int32 (Left.Scal), Right => Int32 (Right.Scal))); - return Vec_Extract - (Pfx, Uns32 (Bnd.Right - Res_Bnd.Right), Res_Bnd); + Off := Uns32 (Pfx_Bnd.Right - Res_Bnd.Right); when Iir_Downto => Res_Bnd := Create_Value_Bound (Value_Bound_Type' @@ -967,9 +955,22 @@ package body Synth.Expr is Len => Width (Left.Scal - Right.Scal + 1), Left => Int32 (Left.Scal), Right => Int32 (Right.Scal))); - return Vec_Extract - (Pfx, Uns32 (Res_Bnd.Right - Bnd.Right), Res_Bnd); + Off := Uns32 (Res_Bnd.Right - Pfx_Bnd.Right); end case; + end Synth_Slice_Suffix; + + function Synth_Slice_Name (Syn_Inst : Synth_Instance_Acc; Name : Node) + return Value_Acc + is + Pfx : constant Value_Acc := + Synth_Expression (Syn_Inst, Get_Prefix (Name)); + Bnd : Value_Bound_Acc; + Res_Bnd : Value_Bound_Acc; + Off : Uns32; + begin + Bnd := Extract_Bound (Pfx); + Synth_Slice_Suffix (Syn_Inst, Name, Bnd, Res_Bnd, Off); + return Vec_Extract (Pfx, Off, Res_Bnd); end Synth_Slice_Name; -- Match: clk_signal_name'event diff --git a/src/synth/synth-expr.ads b/src/synth/synth-expr.ads index 1f4cf3ee2..21758b797 100644 --- a/src/synth/synth-expr.ads +++ b/src/synth/synth-expr.ads @@ -55,4 +55,9 @@ package Synth.Expr is function Index_To_Offset (Pfx : Value_Acc; Idx : Int64; Loc : Node) return Uns32; + procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc; + Name : Node; + Pfx_Bnd : Value_Bound_Acc; + Res_Bnd : out Value_Bound_Acc; + Off : out Uns32); end Synth.Expr; diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 92384c42c..c05568261 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -149,6 +149,27 @@ package body Synth.Stmts is end if; Synth_Assign (Targ, Create_Value_Net (V, null), Get_Type (Pfx)); end; + when Iir_Kind_Slice_Name => + declare + Pfx : constant Node := Get_Prefix (Target); + Targ : constant Value_Acc := + Get_Value (Syn_Inst, Get_Base_Name (Pfx)); + V : Net; + Res_Bnd : Value_Bound_Acc; + Off : Uns32; + begin + if Targ.Kind /= Value_Wire then + -- Only support assignment of vector. + raise Internal_Error; + end if; + Synth_Slice_Suffix (Syn_Inst, Target, Extract_Bound (Targ), + Res_Bnd, Off); + V := Build_Insert (Build_Context, + Get_Net (Targ, Get_Type (Pfx)), + Get_Net (Val, Get_Type (Target)), Off); + Synth_Assign + (Targ, Create_Value_Net (V, Res_Bnd), Get_Type (Pfx)); + end; when others => Error_Kind ("synth_assignment", Target); end case; diff --git a/src/synth/synth-values.adb b/src/synth/synth-values.adb index 45e9cf4e6..b71373b16 100644 --- a/src/synth/synth-values.adb +++ b/src/synth/synth-values.adb @@ -279,4 +279,16 @@ package body Synth.Values is Current_Pool := Prev_Pool; return Res; end Unshare; + + function Extract_Bound (Val : Value_Acc) return Value_Bound_Acc is + begin + case Val.Kind is + when Value_Net => + return Val.N_Bound; + when Value_Wire => + return Val.W_Bound; + when others => + raise Internal_Error; + end case; + end Extract_Bound; end Synth.Values; diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads index 01b522440..48d51e0f8 100644 --- a/src/synth/synth-values.ads +++ b/src/synth/synth-values.ads @@ -201,4 +201,5 @@ package Synth.Values is function Unshare (Src : Value_Acc; Pool : Areapool_Acc) return Value_Acc; + function Extract_Bound (Val : Value_Acc) return Value_Bound_Acc; end Synth.Values; |