Coverage for tsfpga/create_ghdl_ls_config.py: 0%

31 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-20 20:52 +0000

1# -------------------------------------------------------------------------------------------------- 

2# Copyright (c) Lukas Vik. All rights reserved. 

3# 

4# This file is part of the tsfpga project, a project platform for modern FPGA development. 

5# https://tsfpga.com 

6# https://github.com/tsfpga/tsfpga 

7# -------------------------------------------------------------------------------------------------- 

8 

9# Standard libraries 

10import json 

11from pathlib import Path 

12from typing import TYPE_CHECKING, Any, Optional 

13 

14# Local folder libraries 

15from .system_utils import create_file, path_relative_to 

16 

17if TYPE_CHECKING: 

18 # Local folder libraries 

19 from .module_list import ModuleList 

20 from .vivado.simlib_common import VivadoSimlibCommon 

21 

22 

23def create_ghdl_ls_configuration( 

24 output_path: Path, 

25 modules: "ModuleList", 

26 vunit_proj: Any, 

27 simlib: Optional["VivadoSimlibCommon"] = None, 

28) -> None: 

29 """ 

30 Create a configuration file (hdl-prj.json) for the vhdl-lsp VHDL Language Server 

31 (https://github.com/ghdl/ghdl-language-server). 

32 

33 Can be used with modules and an "empty" VUnit project, or with a complete VUnit 

34 project with all user files added. 

35 

36 Execution of this function takes roughly 12 ms for a large project (62 modules and a 

37 VUnit project). 

38 

39 Arguments: 

40 output_path: Output folder. 

41 modules: Source files from these modules will be included. 

42 vunit_proj: A VUnit project. 

43 simlib: Source from this Vivado simlib project will be added. 

44 """ 

45 

46 def get_relative_path(path: Path) -> Path: 

47 return path_relative_to(path=path, other=output_path) 

48 

49 data = dict(options=dict(ghdl_analysis=[]), files=[]) 

50 

51 def add_compiled_library(path: Path) -> None: 

52 relative_path = get_relative_path(path) 

53 data["options"]["ghdl_analysis"].append(f"-P{relative_path}") # type: ignore[index] 

54 

55 data["options"]["ghdl_analysis"] += [ # type: ignore[index] 

56 "--std=08", 

57 ] 

58 

59 # pylint: disable=protected-access 

60 compiled_vunit_libraries_path = Path(vunit_proj._output_path) / "ghdl" / "libraries" 

61 for compiled_library_path in compiled_vunit_libraries_path.glob("*"): 

62 add_compiled_library(compiled_library_path) 

63 

64 if simlib is not None: 

65 for library_name in simlib.library_names: 

66 add_compiled_library(simlib.output_path / library_name) 

67 

68 # The same file might be present in both module file list as well as VUnit project. 

69 # However the opposite might also be true in many cases. 

70 # E.g. files that depend on IP cores that are not included in the simulation project. 

71 # For this reason, add all files to a set first to avoid duplicates. 

72 files = set() 

73 

74 if modules is not None: 

75 for module in modules: 

76 for hdl_file in module.get_simulation_files( 

77 include_ip_cores=False, 

78 include_verilog_files=False, 

79 include_systemverilog_files=False, 

80 ): 

81 files.add(hdl_file.path) 

82 

83 for source_file in vunit_proj.get_compile_order(): 

84 files.add(Path(source_file.name).resolve()) 

85 

86 for file_path in files: 

87 data["files"].append( # type: ignore[attr-defined] 

88 dict(file=str(get_relative_path(file_path)), language="vhdl") 

89 ) 

90 

91 create_file(output_path / "hdl-prj.json", json.dumps(data))