Skip to content

Commit 60904fa

Browse files
committed
Chnages this ghdl runner to prototype
1 parent 9045900 commit 60904fa

File tree

1 file changed

+172
-43
lines changed

1 file changed

+172
-43
lines changed
Lines changed: 172 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
8911002
def _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

Comments
 (0)