diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/synth/synth-context.adb | 13 | ||||
-rw-r--r-- | src/synth/synth-context.ads | 5 | ||||
-rw-r--r-- | src/synth/synth-decls.adb | 39 | ||||
-rw-r--r-- | src/synth/synth-expr.adb | 3 | ||||
-rw-r--r-- | src/synth/synth-stmts.adb | 34 | ||||
-rw-r--r-- | src/synth/synth-values.adb | 53 | ||||
-rw-r--r-- | src/synth/synth-values.ads | 3 |
7 files changed, 134 insertions, 16 deletions
diff --git a/src/synth/synth-context.adb b/src/synth/synth-context.adb index 2a219a904..d05d45737 100644 --- a/src/synth/synth-context.adb +++ b/src/synth/synth-context.adb @@ -59,6 +59,7 @@ package body Synth.Context is Bit1 => No_Net); Res := new Synth_Instance_Type'(Max_Objs => Global_Info.Nbr_Objects, + Is_Const => False, Base => Base, Name => No_Sname, Block_Scope => Global_Info, @@ -85,6 +86,7 @@ package body Synth.Context is end if; Res := new Synth_Instance_Type'(Max_Objs => Info.Nbr_Objects, + Is_Const => False, Base => Parent.Base, Name => Name, Block_Scope => Scope, @@ -154,6 +156,17 @@ package body Synth.Context is return Inst.Base.Bit1; end Get_Inst_Bit1; + function Get_Instance_Const (Inst : Synth_Instance_Acc) return Boolean is + begin + return Inst.Is_Const; + end Get_Instance_Const; + + procedure Set_Instance_Const (Inst : Synth_Instance_Acc; Val : Boolean) is + begin + pragma Assert (not Val or else Inst.Elab_Objects = 0); + Inst.Is_Const := Val; + end Set_Instance_Const; + function Create_Value_Instance (Inst : Synth_Instance_Acc) return Value_Acc is begin diff --git a/src/synth/synth-context.ads b/src/synth/synth-context.ads index 055518941..a652e9ba3 100644 --- a/src/synth/synth-context.ads +++ b/src/synth/synth-context.ads @@ -69,6 +69,9 @@ package Synth.Context is -- Start the definition of module M (using INST). procedure Set_Instance_Module (Inst : Synth_Instance_Acc; M : Module); + function Get_Instance_Const (Inst : Synth_Instance_Acc) return Boolean; + procedure Set_Instance_Const (Inst : Synth_Instance_Acc; Val : Boolean); + procedure Create_Object (Syn_Inst : Synth_Instance_Acc; Decl : Iir; Val : Value_Acc); @@ -117,6 +120,8 @@ private type Base_Instance_Acc is access Base_Instance_Type; type Synth_Instance_Type (Max_Objs : Object_Slot_Type) is limited record + Is_Const : Boolean; + Base : Base_Instance_Acc; -- Name prefix for declarations. diff --git a/src/synth/synth-decls.adb b/src/synth/synth-decls.adb index ba6d2d238..9b5fbad14 100644 --- a/src/synth/synth-decls.adb +++ b/src/synth/synth-decls.adb @@ -419,6 +419,9 @@ package body Synth.Decls is Obj_Type := Get_Value_Type (Syn_Inst, Decl_Type); Val := Synth_Expression_With_Type (Syn_Inst, Get_Default_Value (Decl), Obj_Type); + -- For constant functions, the value must be constant. + pragma Assert (not Get_Instance_Const (Syn_Inst) + or else Is_Const (Val)); Create_Object_Force (Syn_Inst, First_Decl, Val); end if; end Synth_Constant_Declaration; @@ -483,19 +486,29 @@ package body Synth.Decls is Init : Value_Acc; Obj_Type : Type_Acc; begin - Make_Object (Syn_Inst, Wire_Variable, Decl); + Obj_Type := Get_Value_Type (Syn_Inst, Get_Type (Decl)); if Is_Valid (Def) then - Obj_Type := Get_Value_Type (Syn_Inst, Get_Type (Decl)); Init := Synth_Expression_With_Type (Syn_Inst, Def, Obj_Type); Init := Synth_Subtype_Conversion (Init, Obj_Type, False, Decl); else - Init := null; + if Get_Instance_Const (Syn_Inst) then + Init := Create_Value_Default (Obj_Type); + else + Init := null; + end if; end if; - Create_Var_Wire (Syn_Inst, Decl, Init); - if Is_Subprg and then Init /= null then - Phi_Assign (Get_Build (Syn_Inst), - Get_Value (Syn_Inst, Decl).W, Get_Net (Init), 0); + if Get_Instance_Const (Syn_Inst) then + pragma Assert (Init /= null); + Create_Object (Syn_Inst, Decl, Init); + else + Make_Object (Syn_Inst, Wire_Variable, Decl); + Create_Var_Wire (Syn_Inst, Decl, Init); + if Is_Subprg and then Init /= null then + Phi_Assign + (Get_Build (Syn_Inst), + Get_Value (Syn_Inst, Decl).W, Get_Net (Init), 0); + end if; end if; end; when Iir_Kind_Interface_Variable_Declaration => @@ -589,12 +602,12 @@ package body Synth.Decls is Val : Value_Acc; begin case Get_Kind (Decl) is - when Iir_Kind_Variable_Declaration => - Val := Get_Value (Syn_Inst, Decl); - Free_Wire (Val.W); - when Iir_Kind_Interface_Variable_Declaration => - Val := Get_Value (Syn_Inst, Decl); - Free_Wire (Val.W); + when Iir_Kind_Variable_Declaration + | Iir_Kind_Interface_Variable_Declaration => + if not Get_Instance_Const (Syn_Inst) then + Val := Get_Value (Syn_Inst, Decl); + Free_Wire (Val.W); + end if; when Iir_Kind_Constant_Declaration => null; when Iir_Kind_Signal_Declaration diff --git a/src/synth/synth-expr.adb b/src/synth/synth-expr.adb index 82ceedfa2..5fdf30067 100644 --- a/src/synth/synth-expr.adb +++ b/src/synth/synth-expr.adb @@ -803,7 +803,8 @@ package body Synth.Expr is pragma Assert (Vtype.Kind = Type_Array); return Val; when Type_Unbounded_Vector => - pragma Assert (Vtype.Kind = Type_Vector); + pragma Assert (Vtype.Kind = Type_Vector + or else Vtype.Kind = Type_Slice); return Val; when Type_Record => -- TODO: handle elements. diff --git a/src/synth/synth-stmts.adb b/src/synth/synth-stmts.adb index 726017f27..1fd331e85 100644 --- a/src/synth/synth-stmts.adb +++ b/src/synth/synth-stmts.adb @@ -360,6 +360,25 @@ package body Synth.Stmts is end case; end Synth_Target; + procedure Assign_Value (Targ : Value_Acc; Val : Value_Acc; Loc : Node) is + begin + case Targ.Kind is + when Value_Discrete => + Targ.Scal := Val.Scal; + when Value_Array => + declare + Len : constant Iir_Index32 := Val.Arr.Len; + begin + for I in 1 .. Len loop + Assign_Value (Targ.Arr.V (Targ.Arr.Len - Len + I), + Val.Arr.V (I), Loc); + end loop; + end; + when others => + raise Internal_Error; + end case; + end Assign_Value; + procedure Synth_Assignment (Syn_Inst : Synth_Instance_Acc; Target : Target_Info; Val : Value_Acc; @@ -370,8 +389,13 @@ package body Synth.Stmts is Synth_Assignment_Aggregate (Syn_Inst, Target.Aggr, Target.Targ_Type, Val, Loc); when Target_Simple => - Synth_Assign (Target.Obj.W, Target.Targ_Type, - Val, Target.Off, Loc); + if Target.Obj.Kind = Value_Wire then + Synth_Assign (Target.Obj.W, Target.Targ_Type, + Val, Target.Off, Loc); + else + pragma Assert (Target.Off = 0); + Assign_Value (Target.Obj, Val, Loc); + end if; when Target_Memory => declare Inst : constant Instance := Get_Net_Parent (Target.Mem_Val); @@ -1207,6 +1231,8 @@ package body Synth.Stmts is Actual : Node; Val : Value_Acc; begin + Set_Instance_Const (Subprg_Inst, True); + Assoc := Assoc_Chain; Assoc_Inter := Inter_Chain; while Is_Valid (Assoc) loop @@ -1234,6 +1260,10 @@ package body Synth.Stmts is Val := Synth_Subtype_Conversion (Val, Inter_Type, True, Assoc); + if Get_Instance_Const (Subprg_Inst) and then not Is_Const (Val) then + Set_Instance_Const (Subprg_Inst, False); + end if; + case Iir_Kinds_Interface_Object_Declaration (Get_Kind (Inter)) is when Iir_Kind_Interface_Constant_Declaration | Iir_Kind_Interface_Variable_Declaration => diff --git a/src/synth/synth-values.adb b/src/synth/synth-values.adb index 030ceec81..a2c9f8623 100644 --- a/src/synth/synth-values.adb +++ b/src/synth/synth-values.adb @@ -592,6 +592,59 @@ package body Synth.Values is return Atype.W; end Get_Type_Width; + function Create_Value_Default (Typ : Type_Acc) return Value_Acc is + begin + case Typ.Kind is + when Type_Bit + | Type_Logic => + -- FIXME: what about subtype ? + return Create_Value_Discrete (0, Typ); + when Type_Discrete => + return Create_Value_Discrete (Typ.Drange.Left, Typ); + when Type_Float => + return Create_Value_Float (Typ.Frange.Left, Typ); + when Type_Vector => + declare + El_Typ : constant Type_Acc := Typ.Vec_El; + Arr : Value_Array_Acc; + begin + Arr := Create_Value_Array (Iir_Index32 (Typ.Vbound.Len)); + for I in Arr.V'Range loop + Arr.V (I) := Create_Value_Default (El_Typ); + end loop; + return Create_Value_Array (Typ, Arr); + end; + when Type_Unbounded_Vector => + raise Internal_Error; + when Type_Slice => + raise Internal_Error; + when Type_Array => + declare + El_Typ : constant Type_Acc := Typ.Vec_El; + Arr : Value_Array_Acc; + begin + Arr := Create_Value_Array + (Iir_Index32 (Get_Array_Flat_Length (Typ))); + for I in Arr.V'Range loop + Arr.V (I) := Create_Value_Default (El_Typ); + end loop; + return Create_Value_Array (Typ, Arr); + end; + when Type_Unbounded_Array => + raise Internal_Error; + when Type_Record => + declare + Els : Value_Array_Acc; + begin + Els := Create_Value_Array (Typ.Rec.Len); + for I in Els.V'Range loop + Els.V (I) := Create_Value_Default (Typ.Rec.E (I).Typ); + end loop; + return Create_Value_Record (Typ, Els); + end; + end case; + end Create_Value_Default; + procedure Init is begin Instance_Pool := Global_Pool'Access; diff --git a/src/synth/synth-values.ads b/src/synth/synth-values.ads index 09a5df1d4..73aefde2e 100644 --- a/src/synth/synth-values.ads +++ b/src/synth/synth-values.ads @@ -295,6 +295,9 @@ package Synth.Values is function Get_Type_Width (Atype : Type_Acc) return Width; + -- Create a default initial value for TYP. + function Create_Value_Default (Typ : Type_Acc) return Value_Acc; + procedure Init; -- Set by Init. |