aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/synth-vhdl_stmts.adb
diff options
context:
space:
mode:
Diffstat (limited to 'src/synth/synth-vhdl_stmts.adb')
-rw-r--r--src/synth/synth-vhdl_stmts.adb488
1 files changed, 283 insertions, 205 deletions
diff --git a/src/synth/synth-vhdl_stmts.adb b/src/synth/synth-vhdl_stmts.adb
index 6fa2e9227..f351c34f3 100644
--- a/src/synth/synth-vhdl_stmts.adb
+++ b/src/synth/synth-vhdl_stmts.adb
@@ -142,6 +142,7 @@ package body Synth.Vhdl_Stmts is
when Iir_Kind_Indexed_Name =>
declare
+ El_Typ : Type_Acc;
Voff : Net;
Off : Value_Offsets;
Err : Boolean;
@@ -150,7 +151,8 @@ package body Synth.Vhdl_Stmts is
(Syn_Inst, Get_Prefix (Pfx),
Dest_Base, Dest_Typ, Dest_Off, Dest_Dyn);
Strip_Const (Dest_Base);
- Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Typ, Voff, Off, Err);
+ Synth_Indexed_Name (Syn_Inst, Pfx, Dest_Typ,
+ El_Typ, Voff, Off, Err);
if Err then
Dest_Base := No_Valtyp;
@@ -179,7 +181,7 @@ package body Synth.Vhdl_Stmts is
end if;
end if;
- Dest_Typ := Get_Array_Element (Dest_Typ);
+ Dest_Typ := El_Typ;
end;
when Iir_Kind_Selected_Element =>
@@ -190,10 +192,7 @@ package body Synth.Vhdl_Stmts is
Synth_Assignment_Prefix
(Syn_Inst, Get_Prefix (Pfx),
Dest_Base, Dest_Typ, Dest_Off, Dest_Dyn);
- Dest_Off.Net_Off :=
- Dest_Off.Net_Off + Dest_Typ.Rec.E (Idx + 1).Boff;
- Dest_Off.Mem_Off :=
- Dest_Off.Mem_Off + Dest_Typ.Rec.E (Idx + 1).Moff;
+ Dest_Off := Dest_Off + Dest_Typ.Rec.E (Idx + 1).Offs;
Dest_Typ := Dest_Typ.Rec.E (Idx + 1).Typ;
end;
@@ -261,8 +260,6 @@ package body Synth.Vhdl_Stmts is
end case;
end Synth_Assignment_Prefix;
- type Target_Info_Array is array (Natural range <>) of Target_Info;
-
function Synth_Aggregate_Target_Type (Syn_Inst : Synth_Instance_Acc;
Target : Node) return Type_Acc
is
@@ -295,7 +292,7 @@ package body Synth.Vhdl_Stmts is
pragma Assert (Get_Kind (Choice) = Iir_Kind_Choice_By_None);
El := Get_Associated_Expr (Choice);
El_Typ := Elab.Vhdl_Expr.Exec_Type_Of_Object (Syn_Inst, El);
- Bnd := Get_Array_Bound (El_Typ, 1);
+ Bnd := Get_Array_Bound (El_Typ);
Len := Len + Bnd.Len;
Choice := Get_Chain (Choice);
end loop;
@@ -323,7 +320,7 @@ package body Synth.Vhdl_Stmts is
-- Compute the type.
case Base_Typ.Kind is
when Type_Unbounded_Vector =>
- Res := Create_Vector_Type (Bnd, Base_Typ.Uvec_El);
+ Res := Create_Vector_Type (Bnd, Base_Typ.Uarr_El);
when others =>
raise Internal_Error;
end case;
@@ -344,6 +341,7 @@ package body Synth.Vhdl_Stmts is
| Iir_Kind_Interface_Signal_Declaration
| Iir_Kind_Variable_Declaration
| Iir_Kind_Signal_Declaration
+ | Iir_Kind_Object_Alias_Declaration
| Iir_Kind_Indexed_Name
| Iir_Kind_Slice_Name
| Iir_Kind_Dereference =>
@@ -417,14 +415,14 @@ package body Synth.Vhdl_Stmts is
end case;
end Aggregate_Extract;
- procedure Synth_Assignment_Aggregate (Syn_Inst : Synth_Instance_Acc;
- Target : Node;
- Target_Typ : Type_Acc;
- Val : Valtyp;
- Loc : Node)
+ procedure Assign_Aggregate (Inst : Synth_Instance_Acc;
+ Target : Node;
+ Target_Typ : Type_Acc;
+ Val : Valtyp;
+ Loc : Node)
is
- Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
- Targ_Bnd : constant Bound_Type := Get_Array_Bound (Target_Typ, 1);
+ Ctxt : constant Context_Acc := Get_Build (Inst);
+ Targ_Bnd : constant Bound_Type := Get_Array_Bound (Target_Typ);
Choice : Node;
Assoc : Node;
Pos : Uns32;
@@ -436,23 +434,96 @@ package body Synth.Vhdl_Stmts is
Assoc := Get_Associated_Expr (Choice);
case Get_Kind (Choice) is
when Iir_Kind_Choice_By_None =>
- Targ_Info := Synth_Target (Syn_Inst, Assoc);
+ Targ_Info := Synth_Target (Inst, Assoc);
if Get_Element_Type_Flag (Choice) then
Pos := Pos - 1;
else
- Pos := Pos - Get_Array_Bound (Targ_Info.Targ_Type, 1).Len;
+ Pos := Pos - Get_Array_Bound (Targ_Info.Targ_Type).Len;
end if;
- Synth_Assignment
- (Syn_Inst, Targ_Info,
- Aggregate_Extract (Ctxt, Val, Pos,
- Targ_Info.Targ_Type, Assoc),
- Loc);
+ Assign (Inst, Targ_Info,
+ Aggregate_Extract (Ctxt, Val, Pos,
+ Targ_Info.Targ_Type, Assoc),
+ Loc);
when others =>
- Error_Kind ("synth_assignment_aggregate", Choice);
+ Error_Kind ("assign_aggregate", Choice);
end case;
Choice := Get_Chain (Choice);
end loop;
- end Synth_Assignment_Aggregate;
+ end Assign_Aggregate;
+
+ procedure Synth_Assignment_Aggregate is
+ new Assign_Aggregate (Assign => Synth_Assignment);
+
+ procedure Synth_Assignment_Simple (Syn_Inst : Synth_Instance_Acc;
+ Targ : Valtyp;
+ Off : Value_Offsets;
+ Val : Valtyp;
+ Loc : Node)
+ is
+ Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
+ W : Wire_Id;
+ V : Valtyp;
+ begin
+ if Targ = No_Valtyp then
+ -- There was an error.
+ return;
+ end if;
+
+ if Targ.Val.Kind = Value_Alias then
+ Synth_Assignment_Simple (Syn_Inst, (Targ.Val.A_Typ, Targ.Val.A_Obj),
+ Off + Targ.Val.A_Off, Val, Loc);
+ return;
+ end if;
+
+ V := Val;
+
+ if Targ.Val.Kind = Value_Wire then
+ W := Get_Value_Wire (Targ.Val);
+ if Is_Static (V.Val)
+ and then V.Typ.Sz = Targ.Typ.Sz
+ then
+ pragma Assert (Off = No_Value_Offsets);
+ Phi_Assign_Static (W, Unshare (Get_Memtyp (V)));
+ else
+ if V.Typ.W = 0 then
+ -- Forget about null wires.
+ return;
+ end if;
+ Phi_Assign_Net (Ctxt, W, Get_Net (Ctxt, V), Off.Net_Off);
+ end if;
+ else
+ if not Is_Static (V.Val) then
+ -- Maybe the error message is too cryptic ?
+ Error_Msg_Synth
+ (+Loc, "cannot assign a net to a static value");
+ else
+ Copy_Memory (Targ.Val.Mem + Off.Mem_Off, Get_Memory (V), V.Typ.Sz);
+ end if;
+ end if;
+ end Synth_Assignment_Simple;
+
+ procedure Synth_Assignment_Memory (Syn_Inst : Synth_Instance_Acc;
+ Targ_Base : Value_Acc;
+ Targ_Poff : Uns32;
+ Targ_Ptyp : Type_Acc;
+ Targ_Voff : Net;
+ Targ_Eoff : Uns32;
+ Val : Valtyp;
+ Loc : Node)
+ is
+ Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
+ W : constant Wire_Id := Get_Value_Wire (Targ_Base);
+ N : Net;
+ begin
+ -- Get the whole memory.
+ N := Get_Current_Assign_Value (Ctxt, W, Targ_Poff, Targ_Ptyp.W);
+ -- Insert the new value.
+ N := Build_Dyn_Insert
+ (Ctxt, N, Get_Net (Ctxt, Val), Targ_Voff, Targ_Eoff);
+ Set_Location (N, Loc);
+ -- Write.
+ Phi_Assign_Net (Ctxt, W, N, Targ_Poff);
+ end Synth_Assignment_Memory;
procedure Synth_Assignment (Syn_Inst : Synth_Instance_Acc;
Target : Target_Info;
@@ -461,7 +532,6 @@ package body Synth.Vhdl_Stmts is
is
Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
V : Valtyp;
- W : Wire_Id;
begin
V := Synth_Subtype_Conversion (Ctxt, Val, Target.Targ_Type, False, Loc);
pragma Unreferenced (Val);
@@ -475,52 +545,13 @@ package body Synth.Vhdl_Stmts is
Synth_Assignment_Aggregate
(Syn_Inst, Target.Aggr, Target.Targ_Type, V, Loc);
when Target_Simple =>
- if V.Typ.Sz = 0 then
- -- If there is nothing to assign (like a null slice),
- -- return now.
- return;
- end if;
-
- if Target.Obj.Val.Kind = Value_Wire then
- W := Get_Value_Wire (Target.Obj.Val);
- if Is_Static (V.Val)
- and then V.Typ.Sz = Target.Obj.Typ.Sz
- then
- pragma Assert (Target.Off = (0, 0));
- Phi_Assign_Static (W, Unshare (Get_Memtyp (V)));
- else
- if V.Typ.W = 0 then
- -- Forget about null wires.
- return;
- end if;
- Phi_Assign_Net
- (Ctxt, W, Get_Net (Ctxt, V), Target.Off.Net_Off);
- end if;
- else
- if not Is_Static (V.Val) then
- -- Maybe the error message is too cryptic ?
- Error_Msg_Synth
- (+Loc, "cannot assign a net to a static value");
- else
- Strip_Const (V);
- Copy_Memory (Target.Obj.Val.Mem + Target.Off.Mem_Off,
- V.Val.Mem, V.Typ.Sz);
- end if;
- end if;
+ Synth_Assignment_Simple (Syn_Inst, Target.Obj, Target.Off, V, Loc);
when Target_Memory =>
- declare
- Ctxt : constant Context_Acc := Get_Build (Syn_Inst);
- W : constant Wire_Id := Get_Value_Wire (Target.Mem_Obj.Val);
- N : Net;
- begin
- N := Get_Current_Assign_Value
- (Ctxt, W,
- Target.Mem_Dyn.Pfx_Off.Net_Off, Target.Mem_Dyn.Pfx_Typ.W);
- N := Build_Dyn_Insert (Ctxt, N, Get_Net (Ctxt, V),
- Target.Mem_Dyn.Voff, Target.Mem_Doff);
- Set_Location (N, Loc);
- Phi_Assign_Net (Ctxt, W, N, Target.Mem_Dyn.Pfx_Off.Net_Off);
- end;
+ Synth_Assignment_Memory
+ (Syn_Inst, Target.Mem_Obj.Val,
+ Target.Mem_Dyn.Pfx_Off.Net_Off, Target.Mem_Dyn.Pfx_Typ,
+ Target.Mem_Dyn.Voff, Target.Mem_Doff,
+ V, Loc);
end case;
end Synth_Assignment;
@@ -851,8 +882,8 @@ package body Synth.Vhdl_Stmts is
when Type_Discrete =>
return False;
when Type_Vector =>
- if V.Typ.Vec_El = Logic_Type then
- for I in 1 .. Size_Type (V.Typ.Vbound.Len) loop
+ if V.Typ.Arr_El = Logic_Type then
+ for I in 1 .. Size_Type (V.Typ.Abound.Len) loop
if Ignore_Choice_Logic (Read_U8 (V.Val.Mem + (I - 1)), Loc)
then
return True;
@@ -1578,16 +1609,6 @@ package body Synth.Vhdl_Stmts is
end if;
end Synth_Label;
- function Is_Copyback_Interface (Inter : Node) return Boolean is
- begin
- case Iir_Parameter_Modes (Get_Mode (Inter)) is
- when Iir_In_Mode =>
- return False;
- when Iir_Out_Mode | Iir_Inout_Mode =>
- return Get_Kind (Inter) = Iir_Kind_Interface_Variable_Declaration;
- end case;
- end Is_Copyback_Interface;
-
type Association_Iterator_Kind is
(Association_Function,
Association_Operator);
@@ -1623,36 +1644,6 @@ package body Synth.Vhdl_Stmts is
Right => Right);
end Association_Iterator_Build;
- function Count_Associations (Init : Association_Iterator_Init)
- return Natural
- is
- Assoc : Node;
- Assoc_Inter : Node;
- Inter : Node;
- Nbr_Inout : Natural;
- begin
- case Init.Kind is
- when Association_Function =>
- Nbr_Inout := 0;
-
- Assoc := Init.Assoc_Chain;
- Assoc_Inter := Init.Inter_Chain;
- while Is_Valid (Assoc) loop
- Inter := Get_Association_Interface (Assoc, Assoc_Inter);
-
- if Is_Copyback_Interface (Inter) then
- Nbr_Inout := Nbr_Inout + 1;
- end if;
-
- Next_Association_Interface (Assoc, Assoc_Inter);
- end loop;
-
- return Nbr_Inout;
- when Association_Operator =>
- return 0;
- end case;
- end Count_Associations;
-
type Association_Iterator
(Kind : Association_Iterator_Kind := Association_Function) is
record
@@ -1729,7 +1720,9 @@ package body Synth.Vhdl_Stmts is
Formal := Get_Formal (Assoc);
pragma Assert (Formal /= Null_Node);
Formal := Get_Interface_Of_Formal (Formal);
- if Formal = Inter then
+ -- Compare by identifier, as INTER can be the generic
+ -- interface, while FORMAL is the instantiated one.
+ if Get_Identifier (Formal) = Get_Identifier (Inter) then
-- Found.
-- Optimize in case assocs are in order.
if Assoc = Iterator.First_Named_Assoc then
@@ -1750,26 +1743,42 @@ package body Synth.Vhdl_Stmts is
end case;
end Association_Iterate_Next;
- procedure Synth_Subprogram_Association (Subprg_Inst : Synth_Instance_Acc;
- Caller_Inst : Synth_Instance_Acc;
- Init : Association_Iterator_Init;
- Infos : out Target_Info_Array)
+ function Info_To_Valtyp (Info : Target_Info) return Valtyp is
+ begin
+ case Info.Kind is
+ when Target_Simple =>
+ if Info.Off = No_Value_Offsets then
+ return Info.Obj;
+ else
+ return Create_Value_Alias (Info.Obj, Info.Off, Info.Targ_Type);
+ end if;
+ when Target_Aggregate =>
+ raise Internal_Error;
+ when Target_Memory =>
+ return Create_Value_Dyn_Alias (Info.Mem_Obj.Val,
+ Info.Mem_Dyn.Pfx_Off.Net_Off,
+ Info.Mem_Dyn.Pfx_Typ,
+ Info.Mem_Dyn.Voff,
+ Info.Mem_Doff,
+ Info.Targ_Type);
+ end case;
+ end Info_To_Valtyp;
+
+ procedure Synth_Subprogram_Associations (Subprg_Inst : Synth_Instance_Acc;
+ Caller_Inst : Synth_Instance_Acc;
+ Init : Association_Iterator_Init)
is
- pragma Assert (Infos'First = 1);
Ctxt : constant Context_Acc := Get_Build (Caller_Inst);
Inter : Node;
Inter_Type : Type_Acc;
Assoc : Node;
Actual : Node;
Val : Valtyp;
- Nbr_Inout : Natural;
Iterator : Association_Iterator;
Info : Target_Info;
begin
Set_Instance_Const (Subprg_Inst, True);
- Nbr_Inout := 0;
-
-- Process in INTER order.
Association_Iterate_Init (Iterator, Init);
loop
@@ -1778,8 +1787,9 @@ package body Synth.Vhdl_Stmts is
Inter_Type := Get_Subtype_Object (Subprg_Inst, Get_Type (Inter));
- case Iir_Parameter_Modes (Get_Mode (Inter)) is
- when Iir_In_Mode =>
+ case Iir_Kinds_Interface_Object_Declaration (Get_Kind (Inter)) is
+ when Iir_Kind_Interface_Constant_Declaration =>
+ pragma Assert (Get_Mode (Inter) = Iir_In_Mode);
if Assoc = Null_Node
or else Get_Kind (Assoc) = Iir_Kind_Association_Element_Open
then
@@ -1797,40 +1807,38 @@ package body Synth.Vhdl_Stmts is
Val := Synth_Expression_With_Type
(Caller_Inst, Actual, Inter_Type);
end if;
- when Iir_Out_Mode | Iir_Inout_Mode =>
+ when Iir_Kind_Interface_Variable_Declaration =>
+ -- Always pass by value.
Actual := Get_Actual (Assoc);
Info := Synth_Target (Caller_Inst, Actual);
-
- case Iir_Kinds_Interface_Object_Declaration (Get_Kind (Inter))
- is
- when Iir_Kind_Interface_Constant_Declaration =>
- raise Internal_Error;
- when Iir_Kind_Interface_Variable_Declaration =>
- -- Always pass by value.
- Nbr_Inout := Nbr_Inout + 1;
- Infos (Nbr_Inout) := Info;
- if Info.Kind /= Target_Memory
- and then Is_Static (Info.Obj.Val)
- then
- Val := Create_Value_Memory (Info.Targ_Type);
- Copy_Memory (Val.Val.Mem,
- Info.Obj.Val.Mem + Info.Off.Mem_Off,
- Info.Targ_Type.Sz);
- else
- Val := Synth_Read (Caller_Inst, Info, Assoc);
- end if;
- when Iir_Kind_Interface_Signal_Declaration =>
- -- Always pass by reference (use an alias).
- if Info.Kind = Target_Memory then
- raise Internal_Error;
- end if;
- Val := Create_Value_Alias
- (Info.Obj, Info.Off, Info.Targ_Type);
- when Iir_Kind_Interface_File_Declaration =>
- Val := Info.Obj;
- when Iir_Kind_Interface_Quantity_Declaration =>
- raise Internal_Error;
- end case;
+ if Is_Copyback_Parameter (Inter) then
+ Create_Object (Caller_Inst, Assoc, Info_To_Valtyp (Info));
+ end if;
+ if Info.Kind /= Target_Memory
+ and then Is_Static (Info.Obj.Val)
+ then
+ Val := Create_Value_Memory (Info.Targ_Type);
+ Copy_Memory (Val.Val.Mem,
+ Info.Obj.Val.Mem + Info.Off.Mem_Off,
+ Info.Targ_Type.Sz);
+ else
+ Val := Synth_Read (Caller_Inst, Info, Assoc);
+ end if;
+ when Iir_Kind_Interface_Signal_Declaration =>
+ -- Always pass by reference (use an alias).
+ Actual := Get_Actual (Assoc);
+ Info := Synth_Target (Caller_Inst, Actual);
+ if Info.Kind = Target_Memory then
+ raise Internal_Error;
+ end if;
+ Val := Create_Value_Alias
+ (Info.Obj, Info.Off, Info.Targ_Type);
+ when Iir_Kind_Interface_File_Declaration =>
+ Actual := Get_Actual (Assoc);
+ Info := Synth_Target (Caller_Inst, Actual);
+ Val := Info.Obj;
+ when Iir_Kind_Interface_Quantity_Declaration =>
+ raise Internal_Error;
end case;
if Val = No_Valtyp then
@@ -1842,9 +1850,14 @@ package body Synth.Vhdl_Stmts is
case Iir_Kinds_Interface_Object_Declaration (Get_Kind (Inter)) is
when Iir_Kind_Interface_Constant_Declaration
| Iir_Kind_Interface_Variable_Declaration =>
- -- Always passed by value
- Val := Synth_Subtype_Conversion
- (Ctxt, Val, Inter_Type, True, Assoc);
+ if Get_Mode (Inter) /= Iir_Out_Mode then
+ -- Always passed by value
+ Val := Synth_Subtype_Conversion
+ (Ctxt, Val, Inter_Type, True, Assoc);
+ else
+ -- Use default value ?
+ null;
+ end if;
when Iir_Kind_Interface_Signal_Declaration =>
-- LRM08 4.2.2.3 Signal parameters
-- If an actual signal is associated with a signal parameter
@@ -1905,7 +1918,7 @@ package body Synth.Vhdl_Stmts is
case Iir_Kinds_Interface_Object_Declaration (Get_Kind (Inter)) is
when Iir_Kind_Interface_Constant_Declaration =>
- -- Pass by reference.
+ -- Pass by copy.
Create_Object (Subprg_Inst, Inter, Val);
when Iir_Kind_Interface_Variable_Declaration =>
-- Arguments are passed by copy.
@@ -1925,19 +1938,17 @@ package body Synth.Vhdl_Stmts is
raise Internal_Error;
end case;
end loop;
- end Synth_Subprogram_Association;
+ end Synth_Subprogram_Associations;
procedure Synth_Subprogram_Association (Subprg_Inst : Synth_Instance_Acc;
Caller_Inst : Synth_Instance_Acc;
Inter_Chain : Node;
Assoc_Chain : Node)
is
- Infos : Target_Info_Array (1 .. 0);
Init : Association_Iterator_Init;
begin
Init := Association_Iterator_Build (Inter_Chain, Assoc_Chain);
- Synth_Subprogram_Association (Subprg_Inst, Caller_Inst, Init, Infos);
- pragma Unreferenced (Infos);
+ Synth_Subprogram_Associations (Subprg_Inst, Caller_Inst, Init);
end Synth_Subprogram_Association;
-- Create wires for out and inout interface variables.
@@ -1975,31 +1986,39 @@ package body Synth.Vhdl_Stmts is
procedure Synth_Subprogram_Back_Association
(Subprg_Inst : Synth_Instance_Acc;
Caller_Inst : Synth_Instance_Acc;
- Init : Association_Iterator_Init;
- Infos : Target_Info_Array)
+ Inter_Chain : Node;
+ Assoc_Chain : Node)
is
- pragma Assert (Infos'First = 1);
Inter : Node;
Assoc : Node;
Assoc_Inter : Node;
Val : Valtyp;
- Nbr_Inout : Natural;
+ Targ : Valtyp;
W : Wire_Id;
+ D : Destroy_Type;
begin
- Nbr_Inout := 0;
- pragma Assert (Init.Kind = Association_Function);
- Assoc := Init.Assoc_Chain;
- Assoc_Inter := Init.Inter_Chain;
+ Destroy_Init (D, Caller_Inst);
+ Assoc := Assoc_Chain;
+ Assoc_Inter := Inter_Chain;
while Is_Valid (Assoc) loop
Inter := Get_Association_Interface (Assoc, Assoc_Inter);
- if Is_Copyback_Interface (Inter) then
+ if Is_Copyback_Parameter (Inter) then
if not Get_Whole_Association_Flag (Assoc) then
raise Internal_Error;
end if;
- Nbr_Inout := Nbr_Inout + 1;
+ Targ := Get_Value (Caller_Inst, Assoc);
Val := Get_Value (Subprg_Inst, Inter);
- Synth_Assignment (Caller_Inst, Infos (Nbr_Inout), Val, Assoc);
+ if Targ.Val.Kind = Value_Dyn_Alias then
+ Synth_Assignment_Memory
+ (Caller_Inst, Targ.Val.D_Obj,
+ Targ.Val.D_Poff, Targ.Val.D_Ptyp,
+ Get_Value_Dyn_Alias_Voff (Targ.Val), Targ.Val.D_Eoff,
+ Val, Assoc);
+ else
+ Synth_Assignment_Simple
+ (Caller_Inst, Targ, No_Value_Offsets, Val, Assoc);
+ end if;
-- Free wire used for out/inout interface variables.
if Val.Val.Kind = Value_Wire then
@@ -2007,11 +2026,13 @@ package body Synth.Vhdl_Stmts is
Phi_Discard_Wires (W, No_Wire_Id);
Free_Wire (W);
end if;
+
+ Destroy_Object (D, Assoc);
end if;
Next_Association_Interface (Assoc, Assoc_Inter);
end loop;
- pragma Assert (Nbr_Inout = Infos'Last);
+ Destroy_Finish (D);
end Synth_Subprogram_Back_Association;
function Build_Control_Signal (Syn_Inst : Synth_Instance_Acc;
@@ -2029,8 +2050,7 @@ package body Synth.Vhdl_Stmts is
function Synth_Dynamic_Subprogram_Call (Syn_Inst : Synth_Instance_Acc;
Sub_Inst : Synth_Instance_Acc;
Call : Node;
- Init : Association_Iterator_Init;
- Infos : Target_Info_Array)
+ Init : Association_Iterator_Init)
return Valtyp
is
Imp : constant Node := Get_Implementation (Call);
@@ -2106,7 +2126,8 @@ package body Synth.Vhdl_Stmts is
end if;
else
Res := No_Valtyp;
- Synth_Subprogram_Back_Association (C.Inst, Syn_Inst, Init, Infos);
+ Synth_Subprogram_Back_Association
+ (C.Inst, Syn_Inst, Init.Inter_Chain, Init.Assoc_Chain);
end if;
end if;
@@ -2114,7 +2135,6 @@ package body Synth.Vhdl_Stmts is
Vhdl_Decls.Finalize_Declarations
(C.Inst, Get_Declaration_Chain (Bod), True);
- pragma Unreferenced (Infos);
-- Propagate assignments.
-- Wires that have been created for this subprogram will be destroyed.
@@ -2141,8 +2161,7 @@ package body Synth.Vhdl_Stmts is
Sub_Inst : Synth_Instance_Acc;
Call : Node;
Bod : Node;
- Init : Association_Iterator_Init;
- Infos : Target_Info_Array)
+ Init : Association_Iterator_Init)
return Valtyp
is
Imp : constant Node := Get_Implementation (Call);
@@ -2184,17 +2203,31 @@ package body Synth.Vhdl_Stmts is
end if;
else
Res := No_Valtyp;
- Synth_Subprogram_Back_Association (C.Inst, Syn_Inst, Init, Infos);
+ Synth_Subprogram_Back_Association
+ (C.Inst, Syn_Inst, Init.Inter_Chain, Init.Assoc_Chain);
end if;
end if;
Vhdl_Decls.Finalize_Declarations
(C.Inst, Get_Declaration_Chain (Bod), True);
- pragma Unreferenced (Infos);
return Res;
end Synth_Static_Subprogram_Call;
+ function Synth_Subprogram_Call_Instance (Inst : Synth_Instance_Acc;
+ Imp : Node;
+ Bod : Node)
+ return Synth_Instance_Acc
+ is
+ Res : Synth_Instance_Acc;
+ Up_Inst : Synth_Instance_Acc;
+ begin
+ Up_Inst := Get_Instance_By_Scope (Inst, Get_Parent_Scope (Imp));
+ Res := Make_Elab_Instance (Up_Inst, Bod, Config => Null_Node);
+ Set_Caller_Instance (Res, Inst);
+ return Res;
+ end Synth_Subprogram_Call_Instance;
+
function Synth_Subprogram_Call (Syn_Inst : Synth_Instance_Acc;
Call : Node;
Init : Association_Iterator_Init)
@@ -2204,23 +2237,18 @@ package body Synth.Vhdl_Stmts is
Imp : constant Node := Get_Implementation (Call);
Is_Func : constant Boolean := Is_Function_Declaration (Imp);
Bod : constant Node := Vhdl.Sem_Inst.Get_Subprogram_Body_Origin (Imp);
- Nbr_Inout : constant Natural := Count_Associations (Init);
- Infos : Target_Info_Array (1 .. Nbr_Inout);
Area_Mark : Areapools.Mark_Type;
Res : Valtyp;
Sub_Inst : Synth_Instance_Acc;
- Up_Inst : Synth_Instance_Acc;
begin
Areapools.Mark (Area_Mark, Instance_Pool.all);
- Up_Inst := Get_Instance_By_Scope (Syn_Inst, Get_Parent_Scope (Imp));
- Sub_Inst := Make_Elab_Instance (Up_Inst, Bod, Config => Null_Node);
- Set_Caller_Instance (Sub_Inst, Syn_Inst);
+ Sub_Inst := Synth_Subprogram_Call_Instance (Syn_Inst, Imp, Bod);
if Ctxt /= null then
Set_Extra (Sub_Inst, Syn_Inst, New_Internal_Name (Ctxt));
end if;
- Synth_Subprogram_Association (Sub_Inst, Syn_Inst, Init, Infos);
+ Synth_Subprogram_Associations (Sub_Inst, Syn_Inst, Init);
if Is_Error (Sub_Inst) then
Res := No_Valtyp;
@@ -2233,10 +2261,10 @@ package body Synth.Vhdl_Stmts is
if Get_Instance_Const (Sub_Inst) then
Res := Synth_Static_Subprogram_Call
- (Syn_Inst, Sub_Inst, Call, Bod, Init, Infos);
+ (Syn_Inst, Sub_Inst, Call, Bod, Init);
else
Res := Synth_Dynamic_Subprogram_Call
- (Syn_Inst, Sub_Inst, Call, Init, Infos);
+ (Syn_Inst, Sub_Inst, Call, Init);
end if;
end if;
@@ -2300,8 +2328,6 @@ package body Synth.Vhdl_Stmts is
Inter_Chain : constant Node := Get_Interface_Declaration_Chain (Imp);
Init : constant Association_Iterator_Init :=
Association_Iterator_Build (Inter_Chain, Assoc_Chain);
- Nbr_Inout : constant Natural := Count_Associations (Init);
- Infos : Target_Info_Array (1 .. Nbr_Inout);
Area_Mark : Areapools.Mark_Type;
Sub_Inst : Synth_Instance_Acc;
begin
@@ -2312,11 +2338,12 @@ package body Synth.Vhdl_Stmts is
Set_Extra (Sub_Inst, Syn_Inst, New_Internal_Name (Ctxt));
end if;
- Synth_Subprogram_Association (Sub_Inst, Syn_Inst, Init, Infos);
+ Synth_Subprogram_Associations (Sub_Inst, Syn_Inst, Init);
Synth.Vhdl_Static_Proc.Synth_Static_Procedure (Sub_Inst, Imp, Call);
- Synth_Subprogram_Back_Association (Sub_Inst, Syn_Inst, Init, Infos);
+ Synth_Subprogram_Back_Association
+ (Sub_Inst, Syn_Inst, Init.Inter_Chain, Init.Assoc_Chain);
Free_Instance (Sub_Inst);
Areapools.Release (Area_Mark, Instance_Pool.all);
@@ -2678,11 +2705,14 @@ package body Synth.Vhdl_Stmts is
is
Iterator : constant Node := Get_Parameter_Specification (Stmt);
It_Type : constant Node := Get_Declaration_Type (Iterator);
+ D : Destroy_Type;
begin
- Destroy_Object (Inst, Iterator);
+ Destroy_Init (D, Inst);
+ Destroy_Object (D, Iterator);
if It_Type /= Null_Node then
- Destroy_Object (Inst, It_Type);
+ Destroy_Object (D, It_Type);
end if;
+ Destroy_Finish (D);
end Finish_For_Loop_Statement;
procedure Synth_Dynamic_For_Loop_Statement
@@ -2950,7 +2980,7 @@ package body Synth.Vhdl_Stmts is
Put_Err ("): ");
if Rep = No_Valtyp then
- Put_Line_Err ("assertion failure");
+ Put_Line_Err ("Assertion violation");
else
Put_Line_Err (Value_To_String (Rep));
end if;
@@ -2961,10 +2991,53 @@ package body Synth.Vhdl_Stmts is
end if;
end Synth_Static_Report;
- procedure Synth_Static_Report_Statement (C : Seq_Context; Stmt : Node) is
+ procedure Execute_Report_Statement (Inst : Synth_Instance_Acc;
+ Stmt : Node) is
begin
- Synth_Static_Report (C.Inst, Stmt);
- end Synth_Static_Report_Statement;
+ Synth_Static_Report (Inst, Stmt);
+ end Execute_Report_Statement;
+
+ -- Return True if EXPR can be evaluated with static values.
+ -- Does not need to be fully accurate, used for report/assert messages.
+ function Is_Static_Expr (Inst : Synth_Instance_Acc;
+ Expr : Node) return Boolean is
+ begin
+ case Get_Kind (Expr) is
+ when Iir_Kinds_Dyadic_Operator =>
+ return Is_Static_Expr (Inst, Get_Left (Expr))
+ and then Is_Static_Expr (Inst, Get_Right (Expr));
+ when Iir_Kind_Image_Attribute =>
+ return Is_Static_Expr (Inst, Get_Parameter (Expr));
+ when Iir_Kind_Instance_Name_Attribute
+ | Iir_Kinds_Literal
+ | Iir_Kind_Enumeration_Literal =>
+ return True;
+ when Iir_Kind_Length_Array_Attribute =>
+ -- Attributes on types can be evaluated.
+ return True;
+ when Iir_Kind_Simple_Name =>
+ return Is_Static_Expr (Inst, Get_Named_Entity (Expr));
+ when others =>
+ Error_Kind ("is_static_expr", Expr);
+ return False;
+ end case;
+ end Is_Static_Expr;
+
+ procedure Synth_Dynamic_Report_Statement (Inst : Synth_Instance_Acc;
+ Stmt : Node;
+ Is_Cond : Boolean)
+ is
+ Rep_Expr : constant Node := Get_Report_Expression (Stmt);
+ Sev_Expr : constant Node := Get_Severity_Expression (Stmt);
+ begin
+ if not Is_Cond
+ and then Is_Static_Expr (Inst, Rep_Expr)
+ and then (Sev_Expr = Null_Node
+ or else Is_Static_Expr (Inst, Sev_Expr))
+ then
+ Synth_Static_Report (Inst, Stmt);
+ end if;
+ end Synth_Dynamic_Report_Statement;
procedure Execute_Assertion_Statement (Inst : Synth_Instance_Acc;
Stmt : Node)
@@ -3083,7 +3156,12 @@ package body Synth.Vhdl_Stmts is
Synth_Procedure_Call (C.Inst, Stmt);
when Iir_Kind_Report_Statement =>
if not Is_Dyn then
- Synth_Static_Report_Statement (C, Stmt);
+ Execute_Report_Statement (C.Inst, Stmt);
+ else
+ -- Not executed.
+ -- Depends on the execution path: the report statement may
+ -- be conditionally executed.
+ Synth_Dynamic_Report_Statement (C.Inst, Stmt, True);
end if;
when Iir_Kind_Assertion_Statement =>
if not Is_Dyn then