diff options
Diffstat (limited to 'src/vhdl/vhdl-sem_stmts.adb')
-rw-r--r-- | src/vhdl/vhdl-sem_stmts.adb | 81 |
1 files changed, 80 insertions, 1 deletions
diff --git a/src/vhdl/vhdl-sem_stmts.adb b/src/vhdl/vhdl-sem_stmts.adb index 74409ccab..c1c2431e1 100644 --- a/src/vhdl/vhdl-sem_stmts.adb +++ b/src/vhdl/vhdl-sem_stmts.adb @@ -25,6 +25,7 @@ with Vhdl.Sem_Expr; use Vhdl.Sem_Expr; with Vhdl.Sem_Names; use Vhdl.Sem_Names; with Vhdl.Sem_Scopes; use Vhdl.Sem_Scopes; with Vhdl.Sem_Types; +with Vhdl.Sem_Inst; with Vhdl.Sem_Psl; with Std_Names; with Vhdl.Evaluation; use Vhdl.Evaluation; @@ -1945,10 +1946,79 @@ package body Vhdl.Sem_Stmts is end if; end Sem_Instantiated_Unit; + function Component_Need_Instance (Comp : Iir) return Boolean + is + Inter : Iir; + Inter_Type, Type_Name : Iir; + Has_Type_Gen : Boolean; + begin + Has_Type_Gen := False; + Inter := Get_Generic_Chain (Comp); + while Inter /= Null_Iir loop + case Get_Kind (Inter) is + when Iir_Kind_Interface_Package_Declaration + | Iir_Kind_Interface_Type_Declaration => + Has_Type_Gen := True; + when others => + null; + end case; + Inter := Get_Chain (Inter); + end loop; + + -- If neither interface package nor interface type, no need to check + -- ports. + if not Has_Type_Gen then + return False; + end if; + + -- Check if a type from an interface package or a generic type is used. + Inter := Get_Port_Chain (Comp); + while Inter /= Null_Iir loop + Inter_Type := Get_Subtype_Indication (Inter); + if Inter_Type /= Null_Iir then + -- Maybe to ad-hoc ? + Type_Name := Get_Base_Name (Inter_Type); + case Get_Kind (Type_Name) is + when Iir_Kind_Interface_Package_Declaration + | Iir_Kind_Interface_Type_Declaration => + return True; + when others => + null; + end case; + end if; + Inter := Get_Chain (Inter); + end loop; + + return False; + end Component_Need_Instance; + + procedure Reassoc_Association_Chain (Chain : Iir) + is + Assoc : Iir; + Formal : Iir; + Ent : Iir; + begin + Assoc := Chain; + while Assoc /= Null_Iir loop + Formal := Get_Formal (Assoc); + if Formal /= Null_Iir then + if Get_Kind (Formal) = Iir_Kind_Simple_Name then + Ent := Get_Named_Entity (Formal); + Ent := Sem_Inst.Get_Origin (Ent); + Set_Named_Entity (Formal, Ent); + else + raise Internal_Error; + end if; + end if; + Assoc := Get_Chain (Assoc); + end loop; + end Reassoc_Association_Chain; + procedure Sem_Component_Instantiation_Statement (Stmt: Iir_Component_Instantiation_Statement; Is_Passive : Boolean) is Decl : Iir; + Decl_Inst : Iir; Entity_Unit : Iir_Design_Unit; Bind : Iir_Binding_Indication; begin @@ -1972,7 +2042,16 @@ package body Vhdl.Sem_Stmts is -- The associations Sem_Generic_Association_Chain (Decl, Stmt); - Sem_Port_Association_Chain (Decl, Stmt); + if Component_Need_Instance (Decl) then + Decl_Inst := Sem_Inst.Instantiate_Component_Declaration (Decl, Stmt); + Set_Instantiated_Header (Stmt, Decl_Inst); + Sem_Port_Association_Chain (Decl_Inst, Stmt); + -- Re-associate formals with the non-instantiated interfaces. + Reassoc_Association_Chain (Get_Generic_Map_Aspect_Chain (Stmt)); + Reassoc_Association_Chain (Get_Port_Map_Aspect_Chain (Stmt)); + else + Sem_Port_Association_Chain (Decl, Stmt); + end if; -- FIXME: add sources for signals, in order to detect multiple sources -- to unresolved signals. |