diff options
-rw-r--r-- | src/synth/synth-context.adb | 25 | ||||
-rw-r--r-- | src/synth/synth-expr.adb | 102 | ||||
-rw-r--r-- | src/synth/synth-expr.ads | 10 | ||||
-rw-r--r-- | src/synth/synth-stmts.adb | 70 |
4 files changed, 106 insertions, 101 deletions
diff --git a/src/synth/synth-context.adb b/src/synth/synth-context.adb index 7681d8f3b..be229c4cd 100644 --- a/src/synth/synth-context.adb +++ b/src/synth/synth-context.adb @@ -25,7 +25,6 @@ with Tables; with Vhdl.Errors; use Vhdl.Errors; with Netlists.Builders; use Netlists.Builders; -with Synth.Types; use Synth.Types; with Synth.Errors; use Synth.Errors; with Synth.Expr; use Synth.Expr; @@ -90,27 +89,11 @@ package body Synth.Context is begin case Get_Kind (Obj_Type) is when Iir_Kind_Enumeration_Type_Definition - | Iir_Kind_Enumeration_Subtype_Definition => - Otype := Get_Value_Type (Syn_Inst, Get_Type (Obj)); + | Iir_Kind_Enumeration_Subtype_Definition + | Iir_Kind_Array_Subtype_Definition + | Iir_Kind_Integer_Subtype_Definition => + Otype := Get_Value_Type (Syn_Inst, Obj_Type); return Alloc_Wire (Kind, Obj, Otype); - when Iir_Kind_Array_Subtype_Definition => - declare - Bnd : Value_Acc; - begin - Bnd := Get_Value (Syn_Inst, Obj_Type); - if Is_Vector_Type (Obj_Type) then - return Alloc_Wire (Kind, Obj, Bnd.Typ); - else - raise Internal_Error; - end if; - end; - when Iir_Kind_Integer_Subtype_Definition => - declare - Rng : Value_Acc; - begin - Rng := Get_Value (Syn_Inst, Obj_Type); - return Alloc_Wire (Kind, Obj, Rng.Typ); - end; when others => Error_Kind ("alloc_object", Obj_Type); end case; diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index abdedf37b..10173471f 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -1130,22 +1130,20 @@ package body Synth.Expr is end case; end In_Bounds; - function Index_To_Offset (Pfx : Value_Acc; Idx : Int64; Loc : Node) - return Uns32 - is - Rng : constant Type_Acc := Pfx.Typ; + function Index_To_Offset (Bnd : Bound_Type; Idx : Int64; Loc : Node) + return Uns32 is begin - if not In_Bounds (Rng.Vbound, Int32 (Idx)) then + if not In_Bounds (Bnd, Int32 (Idx)) then Error_Msg_Synth (+Loc, "index not within bounds"); return 0; end if; -- The offset is from the LSB (bit 0). Bit 0 is the rightmost one. - case Rng.Vbound.Dir is + case Bnd.Dir is when Iir_To => - return Uns32 (Rng.Vbound.Right - Int32 (Idx)); + return Uns32 (Bnd.Right - Int32 (Idx)); when Iir_Downto => - return Uns32 (Int32 (Idx) - Rng.Vbound.Right); + return Uns32 (Int32 (Idx) - Bnd.Right); end case; end Index_To_Offset; @@ -1175,64 +1173,78 @@ package body Synth.Expr is return Off; end Dyn_Index_To_Offset; - function Synth_Indexed_Name (Syn_Inst : Synth_Instance_Acc; Name : Node) - return Value_Acc + procedure Synth_Indexed_Name (Syn_Inst : Synth_Instance_Acc; + Name : Node; + Pfx_Type : Type_Acc; + Voff : out Net; + Mul : out Uns32; + Off : out Uns32; + W : out Width) is Indexes : constant Iir_Flist := Get_Index_List (Name); Idx_Expr : constant Node := Get_Nth_Element (Indexes, 0); Idx_Val : Value_Acc; - Pfx_Val : Value_Acc; begin if Get_Nbr_Elements (Indexes) /= 1 then Error_Msg_Synth (+Name, "multi-dim arrays not yet supported"); - return null; + raise Internal_Error; end if; - Pfx_Val := Synth_Expression (Syn_Inst, Get_Prefix (Name)); - -- Use the base type as the subtype of the index is not synth-ed. Idx_Val := Synth_Expression_With_Type (Syn_Inst, Idx_Expr, Get_Base_Type (Get_Type (Idx_Expr))); - if Pfx_Val.Typ.Kind = Type_Vector then + if Pfx_Type.Kind = Type_Vector then + W := 1; + Mul := 0; if Idx_Val.Kind = Value_Discrete then - declare - Off : Uns32; - begin - Off := Index_To_Offset (Pfx_Val, Idx_Val.Scal, Name); - return Bit_Extract (Pfx_Val, Off, Name); - end; + Voff := No_Net; + Off := Index_To_Offset (Pfx_Type.Vbound, Idx_Val.Scal, Name); else - declare - Off : Net; - Res : Net; - begin - Off := Dyn_Index_To_Offset (Pfx_Val.Typ.Vbound, Idx_Val, Name); - Res := Build_Dyn_Extract - (Build_Context, Get_Net (Pfx_Val), Off, 1, 0, 1); - Set_Location (Res, Name); - return Create_Value_Net (Res, Pfx_Val.Typ.Vec_El); - end; + Voff := Dyn_Index_To_Offset (Pfx_Type.Vbound, Idx_Val, Name); + Off := 0; end if; - elsif Pfx_Val.Typ.Kind = Type_Array then - declare - Off : Net; - Res : Net; - El_Width : Width; - begin - Off := Dyn_Index_To_Offset - (Pfx_Val.Typ.Abounds.D (1), Idx_Val, Name); - El_Width := Get_Type_Width (Pfx_Val.Typ.Arr_El); - Res := Build_Dyn_Extract - (Build_Context, Get_Net (Pfx_Val), Off, El_Width, 0, El_Width); - Set_Location (Res, Name); - return Create_Value_Net (Res, Pfx_Val.Typ.Arr_El); - end; + elsif Pfx_Type.Kind = Type_Array then + Voff := Dyn_Index_To_Offset (Pfx_Type.Abounds.D (1), Idx_Val, Name); + W := Get_Type_Width (Pfx_Type.Arr_El); + Mul := W; + Off := 0; else raise Internal_Error; end if; end Synth_Indexed_Name; + function Synth_Indexed_Name (Syn_Inst : Synth_Instance_Acc; Name : Node) + return Value_Acc + is + Pfx_Val : Value_Acc; + Voff : Net; + Mul : Uns32; + Off : Uns32; + W : Width; + Res : Net; + begin + Pfx_Val := Synth_Expression (Syn_Inst, Get_Prefix (Name)); + + Synth_Indexed_Name (Syn_Inst, Name, Pfx_Val.Typ, Voff, Mul, Off, W); + + if Voff = No_Net then + pragma Assert (Mul = 0); + if W = 1 and then Pfx_Val.Kind = Value_Array then + return Bit_Extract (Pfx_Val, Off, Name); + else + Res := Build_Extract (Build_Context, Get_Net (Pfx_Val), Off, W); + Set_Location (Res, Name); + return Create_Value_Net (Res, Get_Array_Element (Pfx_Val.Typ)); + end if; + else + Res := Build_Dyn_Extract + (Build_Context, Get_Net (Pfx_Val), Voff, Mul, Int32 (Off), W); + Set_Location (Res, Name); + return Create_Value_Net (Res, Get_Array_Element (Pfx_Val.Typ)); + end if; + end Synth_Indexed_Name; + function Is_Const (N : Net) return Boolean is begin case Get_Id (Get_Module (Get_Parent (N))) is diff --git a/src/synth/synth-expr.ads b/src/synth/synth-expr.ads index 039dab5d6..f7edc2417 100644 --- a/src/synth/synth-expr.ads +++ b/src/synth/synth-expr.ads @@ -69,7 +69,7 @@ package Synth.Expr is (Syn_Inst : Synth_Instance_Acc; Rng : Node) return Float_Range_Type; -- Convert index IDX in PFX to an offset. LOC is used in case of error. - function Index_To_Offset (Pfx : Value_Acc; Idx : Int64; Loc : Node) + function Index_To_Offset (Bnd : Bound_Type; Idx : Int64; Loc : Node) return Uns32; procedure Synth_Slice_Suffix (Syn_Inst : Synth_Instance_Acc; @@ -80,4 +80,12 @@ package Synth.Expr is Step : out Uns32; Off : out Int32; Wd : out Uns32); + + procedure Synth_Indexed_Name (Syn_Inst : Synth_Instance_Acc; + Name : Node; + Pfx_Type : Type_Acc; + Voff : out Net; + Mul : out Uns32; + Off : out Uns32; + W : out Width); end Synth.Expr; diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 468733b09..888746ae7 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -110,9 +110,41 @@ package body Synth.Stmts is end if; end Synth_Assignment_Aggregate; - procedure Synth_Assignment (Syn_Inst : Synth_Instance_Acc; - Target : Node; - Val : Value_Acc) is + procedure Synth_Indexed_Assignment + (Syn_Inst : Synth_Instance_Acc; Target : Node; Val : Value_Acc) + is + Pfx : constant Node := Get_Prefix (Target); + Targ : constant Value_Acc := Get_Value (Syn_Inst, Get_Base_Name (Pfx)); + Targ_Net : Net; + V : Net; + + Val_Net : Net; + Voff : Net; + Mul : Uns32; + Off : Uns32; + W : Width; + begin + Synth_Indexed_Name (Syn_Inst, Target, Targ.Typ, Voff, Mul, Off, W); + + pragma Assert (Get_Type_Width (Val.Typ) = W); + Targ_Net := Get_Last_Assigned_Value (Targ.W); + Val_Net := Get_Net (Val); + + if Voff = No_Net then + -- FIXME: check index. + pragma Assert (Mul = 0); + V := Build_Insert (Build_Context, Targ_Net, Val_Net, Off); + Set_Location (V, Target); + else + V := Build_Dyn_Insert + (Build_Context, Targ_Net, Val_Net, Voff, Mul, Int32 (Off)); + Set_Location (V, Target); + end if; + Synth_Assign (Targ, Create_Value_Net (V, Targ.Typ)); + end Synth_Indexed_Assignment; + + procedure Synth_Assignment + (Syn_Inst : Synth_Instance_Acc; Target : Node; Val : Value_Acc) is begin case Get_Kind (Target) is when Iir_Kind_Simple_Name => @@ -125,37 +157,7 @@ package body Synth.Stmts is when Iir_Kind_Aggregate => Synth_Assignment_Aggregate (Syn_Inst, Target, Val); when Iir_Kind_Indexed_Name => - declare - Pfx : constant Node := Get_Prefix (Target); - Targ : constant Value_Acc := - Get_Value (Syn_Inst, Get_Base_Name (Pfx)); - Indexes : constant Node_Flist := Get_Index_List (Target); - N_Idx : Node; - Idx : Value_Acc; - Targ_Net : Net; - V : Net; - begin - if Get_Nbr_Elements (Indexes) /= 1 - or else Targ.Kind /= Value_Wire - then - -- Only support assignment of vector. - raise Internal_Error; - end if; - N_Idx := Get_Nth_Element (Indexes, 0); - Idx := Synth_Expression_With_Type - (Syn_Inst, N_Idx, Get_Type (N_Idx)); - if Is_Const (Idx) then - -- FIXME: check index. - Targ_Net := Get_Last_Assigned_Value (Targ.W); - V := Build_Insert (Build_Context, - Targ_Net, Get_Net (Val), - Index_To_Offset (Targ, Idx.Scal, Target)); - Set_Location (V, Target); - else - raise Internal_Error; - end if; - Synth_Assign (Targ, Create_Value_Net (V, Targ.Typ)); - end; + Synth_Indexed_Assignment (Syn_Inst, Target, Val); when Iir_Kind_Slice_Name => declare Pfx : constant Node := Get_Prefix (Target); |