@@ -741,19 +741,16 @@ def _has_vhdl2008_conflicts(file_path: str, repo_root: str) -> bool:
741741 if re .search (r'procedure\s+HRead\s*\(' , content , re .IGNORECASE ):
742742 # Check if it's wrapped in translate_off pragma (simulation-only code)
743743 if re .search (r'pragma\s+translate_off' , content , re .IGNORECASE ):
744- print_yellow (f"[GHDL-INCREMENTAL] Skipping { file_path } : contains VHDL-2008 conflicting declarations (HRead/HWrite)" )
745744 return True
746745
747746 # Check for 'force' used as identifier (reserved keyword in VHDL-2008)
748747 # Pattern: "force : in/out/inout type" in port/signal declarations
749748 if re .search (r'\bforce\s*:\s*(in|out|inout|buffer)\b' , content , re .IGNORECASE ):
750- print_yellow (f"[GHDL-INCREMENTAL] Skipping { file_path } : uses 'force' as identifier (VHDL-2008 reserved keyword)" )
751749 return True
752750
753751 # Check for files that import from grlib.stdio (which has VHDL-2008 conflicts)
754752 # Files like testlib.vhd depend on stdio but don't directly have conflicts
755753 if re .search (r'use\s+grlib\.stdio\s*\.' , content , re .IGNORECASE ):
756- print_yellow (f"[GHDL-INCREMENTAL] Skipping { file_path } : depends on grlib.stdio (VHDL-2008 incompatible)" )
757754 return True
758755
759756 except Exception :
@@ -838,7 +835,7 @@ def _build_ghdl_cmd(
838835 work_library: Custom library name (default: "work")
839836 repo_root: Repository root for Synopsys package detection
840837 """
841- cmd = ["ghdl" , "-a" , "--std=08 " , f"--workdir={ workdir } " ]
838+ cmd = ["ghdl" , "-a" , "--std=93c" , "-frelaxed-rules " , f"--workdir={ workdir } " ]
842839
843840 # Add custom library name if specified
844841 if work_library and work_library != "work" :
@@ -872,7 +869,7 @@ def _build_elab_cmd(
872869 files: List of files for Synopsys detection
873870 repo_root: Repository root for Synopsys package detection
874871 """
875- cmd = ["ghdl" , "-e" , "--std=08 " , f"--workdir={ workdir } " ]
872+ cmd = ["ghdl" , "-e" , "--std=93c" , "-frelaxed-rules " , f"--workdir={ workdir } " ]
876873
877874 # Add custom library name if specified
878875 if work_library and work_library != "work" :
@@ -888,12 +885,129 @@ def _build_elab_cmd(
888885 return cmd
889886
890887
888+ def _compile_single_library_incremental (
889+ lib_name : str ,
890+ initial_files : List [str ],
891+ all_modules : List [Tuple [str , str ]],
892+ repo_root : str ,
893+ repo_name : str ,
894+ workdir : str ,
895+ ghdl_extra_flags : List [str ] = None ,
896+ timeout : int = 300 ,
897+ max_lib_iterations : int = 10
898+ ) -> Tuple [int , str , List [str ]]:
899+ """Incrementally compile a single library until it's complete.
900+
901+ Args:
902+ lib_name: Name of the library to compile
903+ initial_files: Initial list of files for this library
904+ all_modules: All available modules to search for dependencies
905+ repo_root: Repository root directory
906+ repo_name: Repository name
907+ workdir: Working directory for GHDL
908+ ghdl_extra_flags: Additional GHDL flags
909+ timeout: Timeout for each command
910+ max_lib_iterations: Maximum iterations for this library
911+
912+ Returns: (return_code, output, final_file_list)
913+ """
914+ lib_files = list (initial_files )
915+ added_files = set (lib_files )
916+
917+ for lib_iter in range (1 , max_lib_iterations + 1 ):
918+ print_blue (f"[GHDL-INCREMENTAL] Library '{ lib_name } ' iteration { lib_iter } /{ max_lib_iterations } | files={ len (lib_files )} " )
919+
920+ # Remove duplicates
921+ seen = set ()
922+ unique_files = []
923+ for f in lib_files :
924+ if f not in seen :
925+ seen .add (f )
926+ unique_files .append (f )
927+ lib_files = unique_files
928+
929+ if not lib_files :
930+ return 1 , "All files filtered out" , lib_files
931+
932+ # Order files by dependencies: packages first, then entities
933+ # This is critical for VHDL compilation
934+ lib_files = _order_vhdl_files (lib_files , repo_root )
935+
936+ # Compile files ONE AT A TIME to avoid GHDL batch compilation issues
937+ # This is slower but more reliable for complex multi-file libraries
938+ print_blue (f"[GHDL-INCREMENTAL] Compiling { len (lib_files )} files for library '{ lib_name } ' one at a time with VHDL-93c" )
939+
940+ combined_output = []
941+ rc = 0
942+ for file_to_compile in lib_files :
943+ cmd = ["ghdl" , "-a" , "--std=93c" , "-frelaxed-rules" , f"--workdir={ workdir } " , f"--work={ lib_name } " ]
944+ flags = _validation_flags (ghdl_extra_flags , [file_to_compile ], repo_root )
945+ if flags :
946+ cmd .extend (flags )
947+ cmd .append (file_to_compile )
948+
949+ file_rc , file_output = _run (cmd , repo_root , timeout )
950+ combined_output .append (file_output )
951+
952+ if file_rc != 0 :
953+ rc = file_rc
954+ # Don't break - continue trying other files
955+
956+ output = "\n " .join (combined_output )
957+
958+ if rc == 0 :
959+ print_green (f"[GHDL-INCREMENTAL] ✓ Library '{ lib_name } ' compiled successfully" )
960+ return 0 , output , lib_files
961+
962+ # Parse errors to find missing dependencies
963+ missing_entities = _parse_missing_entities (output )
964+ missing_packages = _parse_missing_packages (output )
965+
966+ if not missing_entities and not missing_packages :
967+ print_yellow (f"[GHDL-INCREMENTAL] Library '{ lib_name } ' has errors but no missing dependencies detected" )
968+ return rc , output , lib_files
969+
970+ # Find and add missing files for this library only
971+ new_files_added = False
972+ for entity_name in missing_entities :
973+ candidates = _search_repo_for_declaration (repo_root , entity_name , "entity" , repo_name )
974+ for candidate in candidates :
975+ candidate_lib = _get_file_library (candidate , repo_root )
976+ if candidate_lib == lib_name and candidate not in added_files :
977+ lib_files .append (candidate )
978+ added_files .add (candidate )
979+ new_files_added = True
980+ print_yellow (f"[GHDL-INCREMENTAL] Added entity '{ entity_name } ' from { candidate } to library '{ lib_name } '" )
981+
982+ for pkg_name , pkg_lib in missing_packages :
983+ if pkg_lib and pkg_lib != lib_name :
984+ continue # Skip packages from other libraries
985+ candidates = _find_file_declaring_package (repo_root , pkg_name , pkg_lib , repo_name , None )
986+ for candidate in candidates :
987+ candidate_lib = _get_file_library (candidate , repo_root )
988+ if candidate_lib == lib_name and candidate not in added_files :
989+ lib_files .append (candidate )
990+ added_files .add (candidate )
991+ new_files_added = True
992+ print_yellow (f"[GHDL-INCREMENTAL] Added package '{ pkg_name } ' from { candidate } to library '{ lib_name } '" )
993+
994+ if not new_files_added :
995+ print_yellow (f"[GHDL-INCREMENTAL] Library '{ lib_name } ' cannot make progress" )
996+ return rc , output , lib_files
997+
998+ print_red (f"[GHDL-INCREMENTAL] Library '{ lib_name } ' failed to compile after { max_lib_iterations } iterations" )
999+ return 1 , output , lib_files
1000+
1001+
8911002def _compile_multi_library (
8921003 files : List [str ],
8931004 repo_root : str ,
1005+ repo_name : str ,
8941006 workdir : str ,
1007+ modules : List [Tuple [str , str ]],
8951008 ghdl_extra_flags : List [str ] = None ,
896- timeout : int = 300
1009+ timeout : int = 300 ,
1010+ incremental : bool = True
8971011) -> Tuple [int , str ]:
8981012 """Compile VHDL files that belong to multiple libraries.
8991013
@@ -906,9 +1020,12 @@ def _compile_multi_library(
9061020 Args:
9071021 files: List of VHDL files to compile
9081022 repo_root: Repository root directory
1023+ repo_name: Repository name
9091024 workdir: Working directory for GHDL
1025+ modules: All available modules for finding dependencies
9101026 ghdl_extra_flags: Additional GHDL flags
9111027 timeout: Timeout for each command
1028+ incremental: If True, use per-library incremental compilation
9121029
9131030 Returns: (return_code, combined_output)
9141031 """
@@ -944,43 +1061,55 @@ def _compile_multi_library(
9441061 combined_output = []
9451062 overall_rc = 0
9461063
947- # Compile each library separately
1064+ # Compile each library separately (with incremental mode if requested)
9481065 for lib in sorted_libs :
9491066 lib_files = files_by_lib [lib ]
9501067
951- # Filter out files with VHDL-2008 conflicts
952- filtered_files = []
953- for f in lib_files :
954- if _has_vhdl2008_conflicts (f , repo_root ):
955- # Skip this file
1068+ if incremental :
1069+ # Use per-library incremental compilation
1070+ rc , output , final_files = _compile_single_library_incremental (
1071+ lib , lib_files , modules , repo_root , repo_name , workdir ,
1072+ ghdl_extra_flags , timeout , max_lib_iterations = 10
1073+ )
1074+ combined_output .append (output )
1075+ if rc != 0 :
1076+ overall_rc = rc
1077+ print_red (f"[GHDL-INCREMENTAL] ✗ Library '{ lib } ' failed to compile" )
1078+ # Continue to try other libraries
1079+ else :
1080+ # Original non-incremental mode
1081+ # Remove duplicates while preserving order
1082+ seen = set ()
1083+ unique_files = []
1084+ for f in lib_files :
1085+ if f not in seen :
1086+ seen .add (f )
1087+ unique_files .append (f )
1088+ lib_files = unique_files
1089+
1090+ # Don't filter out files - compile everything with VHDL-93
1091+ lib_files = unique_files
1092+
1093+ if not lib_files :
1094+ print_yellow (f"[GHDL-INCREMENTAL] Skipping library '{ lib } ': no files" )
9561095 continue
957- filtered_files .append (f )
958-
959- if not filtered_files :
960- # All files were filtered out
961- print_yellow (f"[GHDL-INCREMENTAL] Skipping library '{ lib } ': all files filtered out" )
962- continue
963-
964- print_blue (f"[GHDL-INCREMENTAL] Compiling library '{ lib } ' ({ len (filtered_files )} files)" )
965-
966- # Build command for this library
967- cmd = ["ghdl" , "-a" , "--std=08" , f"--workdir={ workdir } " , f"--work={ lib } " ]
968-
969- # Add flags
970- flags = _validation_flags (ghdl_extra_flags , filtered_files , repo_root )
971- if flags :
972- cmd .extend (flags )
973-
974- cmd .extend (filtered_files )
975-
976- # Run compilation
977- print_blue (f"[GHDL-INCREMENTAL-DEBUG] Command: { ' ' .join (cmd )} " )
978- rc , output = _run (cmd , repo_root , timeout )
979- combined_output .append (output )
980-
981- if rc != 0 :
982- overall_rc = rc
983- # Don't stop - continue to get all errors
1096+
1097+ print_blue (f"[GHDL-INCREMENTAL] Compiling library '{ lib } ' ({ len (lib_files )} files) with VHDL-93" )
1098+
1099+ # Build command for this library with VHDL-93 and -frelaxed-rules
1100+ cmd = ["ghdl" , "-a" , "--std=93c" , "-frelaxed-rules" , f"--workdir={ workdir } " , f"--work={ lib } " ]
1101+ flags = _validation_flags (ghdl_extra_flags , lib_files , repo_root )
1102+ if flags :
1103+ cmd .extend (flags )
1104+ cmd .extend (lib_files )
1105+
1106+ # Run compilation
1107+ print_blue (f"[GHDL-INCREMENTAL-DEBUG] Command: { ' ' .join (cmd )} " )
1108+ rc , output = _run (cmd , repo_root , timeout )
1109+ combined_output .append (output )
1110+
1111+ if rc != 0 :
1112+ overall_rc = rc
9841113
9851114 return overall_rc , "\n " .join (combined_output )
9861115
@@ -1050,9 +1179,9 @@ def compile_incremental(
10501179
10511180 # Check if we need multi-library compilation mode
10521181 if work_library == "MULTI_LIBRARY" :
1053- # Multi-library mode: compile each library separately
1054- print_blue (f"[GHDL-INCREMENTAL] Using multi-library compilation mode" )
1055- rc , output = _compile_multi_library (ordered_files , repo_root , workdir , ghdl_extra_flags , timeout )
1182+ # Multi-library mode: compile each library separately with incremental sub-loops
1183+ print_blue (f"[GHDL-INCREMENTAL] Using multi-library compilation mode with per-library incremental compilation " )
1184+ rc , output = _compile_multi_library (ordered_files , repo_root , repo_name , workdir , modules , ghdl_extra_flags , timeout , incremental = True )
10561185 else :
10571186 # Single library mode (original behavior)
10581187 cmd = _build_ghdl_cmd (ordered_files , top_entity , workdir , ghdl_extra_flags , work_library , repo_root )
@@ -1273,7 +1402,7 @@ def try_incremental_compilation(
12731402 print_blue (f"[GHDL-INCREMENTAL] Candidates to try: { ', ' .join (top_candidates [:10 ])} " )
12741403
12751404 # Limit candidates for performance
1276- MAX_CANDIDATES = 10
1405+ MAX_CANDIDATES = 1
12771406 if len (top_candidates ) > MAX_CANDIDATES :
12781407 print_yellow (f"[GHDL-INCREMENTAL] Limiting to top { MAX_CANDIDATES } candidates (out of { len (top_candidates )} )" )
12791408 top_candidates = top_candidates [:MAX_CANDIDATES ]
0 commit comments