aboutsummaryrefslogtreecommitdiffstats
path: root/src/synth/elab-vhdl_insts.adb
diff options
context:
space:
mode:
authorTristan Gingold <tgingold@free.fr>2021-11-16 18:30:40 +0100
committerTristan Gingold <tgingold@free.fr>2021-11-16 18:30:40 +0100
commit7aa4b1e64d5aaf35acb7ebe25c861336fcabfcc4 (patch)
tree6409c010ac9e664bbdea757de0d8bcdc2ca66fb9 /src/synth/elab-vhdl_insts.adb
parentbff6c33d71382f5374468c757fe187dbeab3a661 (diff)
downloadghdl-7aa4b1e64d5aaf35acb7ebe25c861336fcabfcc4.tar.gz
ghdl-7aa4b1e64d5aaf35acb7ebe25c861336fcabfcc4.tar.bz2
ghdl-7aa4b1e64d5aaf35acb7ebe25c861336fcabfcc4.zip
synth: defer instantations elaboration to handle recursion. Fix #1912
Diffstat (limited to 'src/synth/elab-vhdl_insts.adb')
-rw-r--r--src/synth/elab-vhdl_insts.adb123
1 files changed, 109 insertions, 14 deletions
diff --git a/src/synth/elab-vhdl_insts.adb b/src/synth/elab-vhdl_insts.adb
index aa8203045..f97b4335b 100644
--- a/src/synth/elab-vhdl_insts.adb
+++ b/src/synth/elab-vhdl_insts.adb
@@ -35,6 +35,8 @@ with Elab.Vhdl_Errors; use Elab.Vhdl_Errors;
with Elab.Vhdl_Expr; use Elab.Vhdl_Expr;
package body Elab.Vhdl_Insts is
+ procedure Elab_Instance_Body (Syn_Inst : Synth_Instance_Acc);
+
procedure Elab_Convertible_Declarations (Syn_Inst : Synth_Instance_Acc)
is
use Vhdl.Std_Package;
@@ -407,10 +409,107 @@ package body Elab.Vhdl_Insts is
end loop;
end Elab_Verification_Units;
- procedure Elab_Instance_Body (Syn_Inst : Synth_Instance_Acc;
- Entity : Node;
- Arch : Node;
- Config : Node) is
+ -- Elaborate instantiations.
+ -- This cannot be done immediately like the other statements due to a
+ -- possible conflict with configurations.
+ -- Configurations are applied by Apply_Block_Configuration to the vhdl
+ -- nodes. If instantiations are handled immediately, in case of recursion,
+ -- the configuration may have already been applied to an instantiation and
+ -- therefore cannot be applied again.
+ -- To avoid this issue, statements are first elaborated and instances for
+ -- instantiations are created. The configuration is saved in the
+ -- instances. Then, instances are elaborated using the configuration
+ -- saved.
+ procedure Elab_Recurse_Instantiations
+ (Syn_Inst : Synth_Instance_Acc; Head : Node)
+ is
+ Stmt : Node;
+ begin
+ Stmt := Get_Concurrent_Statement_Chain (Head);
+ while Stmt /= Null_Node loop
+ case Get_Kind (Stmt) is
+ when Iir_Kind_Concurrent_Simple_Signal_Assignment
+ | Iir_Kind_Concurrent_Conditional_Signal_Assignment
+ | Iir_Kind_Concurrent_Selected_Signal_Assignment
+ | Iir_Kind_Concurrent_Procedure_Call_Statement
+ | Iir_Kinds_Process_Statement =>
+ null;
+ when Iir_Kind_If_Generate_Statement =>
+ declare
+ Sub_Inst : constant Synth_Instance_Acc :=
+ Get_Sub_Instance (Syn_Inst, Stmt);
+ begin
+ if Sub_Inst /= null then
+ Elab_Recurse_Instantiations
+ (Sub_Inst, Get_Source_Scope (Sub_Inst));
+ end if;
+ end;
+ when Iir_Kind_For_Generate_Statement =>
+ declare
+ Iterator : constant Node :=
+ Get_Parameter_Specification (Stmt);
+ Bod : constant Node :=
+ Get_Generate_Statement_Body (Stmt);
+ It_Rng : constant Type_Acc :=
+ Get_Subtype_Object (Syn_Inst, Get_Type (Iterator));
+ Gen_Inst : constant Synth_Instance_Acc :=
+ Get_Sub_Instance (Syn_Inst, Stmt);
+ Sub_Inst : Synth_Instance_Acc;
+ begin
+ for I in 1 .. Get_Range_Length (It_Rng.Drange) loop
+ Sub_Inst := Get_Generate_Sub_Instance
+ (Gen_Inst, Positive (I));
+ Elab_Recurse_Instantiations (Sub_Inst, Bod);
+ end loop;
+ end;
+ when Iir_Kind_Component_Instantiation_Statement =>
+ if Is_Component_Instantiation (Stmt) then
+ declare
+ Comp_Inst : constant Synth_Instance_Acc :=
+ Get_Sub_Instance (Syn_Inst, Stmt);
+ Sub_Inst : constant Synth_Instance_Acc :=
+ Get_Component_Instance (Comp_Inst);
+ begin
+ if Sub_Inst /= null then
+ -- Nothing to do if the component is not bound.
+ Elab_Instance_Body (Sub_Inst);
+ end if;
+ end;
+ else
+ declare
+ Sub_Inst : constant Synth_Instance_Acc :=
+ Get_Sub_Instance (Syn_Inst, Stmt);
+ begin
+ Elab_Instance_Body (Sub_Inst);
+ end;
+ end if;
+ when Iir_Kind_Block_Statement =>
+ declare
+ Blk_Inst : constant Synth_Instance_Acc :=
+ Get_Sub_Instance (Syn_Inst, Stmt);
+ begin
+ Elab_Recurse_Instantiations (Blk_Inst, Stmt);
+ end;
+ when Iir_Kind_Psl_Default_Clock
+ | Iir_Kind_Psl_Declaration
+ | Iir_Kind_Psl_Restrict_Directive
+ | Iir_Kind_Psl_Assume_Directive
+ | Iir_Kind_Psl_Cover_Directive
+ | Iir_Kind_Psl_Assert_Directive
+ | Iir_Kind_Concurrent_Assertion_Statement =>
+ null;
+ when others =>
+ Error_Kind ("elab_recurse_instantiations", Stmt);
+ end case;
+ Stmt := Get_Chain (Stmt);
+ end loop;
+ end Elab_Recurse_Instantiations;
+
+ procedure Elab_Instance_Body (Syn_Inst : Synth_Instance_Acc)
+ is
+ Arch : constant Node := Get_Source_Scope (Syn_Inst);
+ Config : constant Node := Get_Instance_Config (Syn_Inst);
+ Entity : constant Node := Get_Entity (Arch);
begin
Apply_Block_Configuration (Config, Arch);
@@ -424,6 +523,8 @@ package body Elab.Vhdl_Insts is
Elab_Concurrent_Statements
(Syn_Inst, Get_Concurrent_Statement_Chain (Arch));
+ Elab_Recurse_Instantiations (Syn_Inst, Arch);
+
Elab_Verification_Units (Syn_Inst, Arch);
end Elab_Instance_Body;
@@ -458,9 +559,6 @@ package body Elab.Vhdl_Insts is
-- TODO: Free it?
return;
end if;
-
- -- Recurse.
- Elab_Instance_Body (Sub_Inst, Entity, Arch, Config);
end Elab_Direct_Instantiation_Statement;
procedure Elab_Component_Instantiation_Statement
@@ -514,6 +612,7 @@ package body Elab.Vhdl_Insts is
if Bind = Null_Iir then
-- No association.
+ Create_Component_Instance (Comp_Inst, null);
return;
end if;
@@ -557,10 +656,6 @@ package body Elab.Vhdl_Insts is
Elab_Ports_Association_Type (Sub_Inst, Comp_Inst,
Get_Port_Chain (Ent),
Get_Port_Map_Aspect_Chain (Bind));
-
- -- Recurse.
- -- TODO: factorize with direct instantiation
- Elab_Instance_Body (Sub_Inst, Ent, Arch, Sub_Config);
end Elab_Component_Instantiation_Statement;
procedure Elab_Design_Instantiation_Statement
@@ -619,7 +714,8 @@ package body Elab.Vhdl_Insts is
-- Start elaboration.
Make_Root_Instance;
- Top_Inst := Make_Elab_Instance (Root_Instance, Arch, Null_Node);
+ Top_Inst := Make_Elab_Instance
+ (Root_Instance, Arch, Get_Block_Configuration (Config));
-- Save the current architecture, so that files can be open using a
-- path relative to the architecture filename.
@@ -664,8 +760,7 @@ package body Elab.Vhdl_Insts is
Inter := Get_Chain (Inter);
end loop;
- Elab_Instance_Body
- (Top_Inst, Entity, Arch, Get_Block_Configuration (Config));
+ Elab_Instance_Body (Top_Inst);
-- Clear elab_flag
for I in Design_Units.First .. Design_Units.Last loop