aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/synth/synth-context.adb13
-rw-r--r--src/synth/synth-context.ads5
-rw-r--r--src/synth/synth-decls.adb39
-rw-r--r--src/synth/synth-expr.adb3
-rw-r--r--src/synth/synth-stmts.adb34
-rw-r--r--src/synth/synth-values.adb53
-rw-r--r--src/synth/synth-values.ads3
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.